18d307f52SEvan Baconimport { IOSConfig } from '@expo/config-plugins'; 28d307f52SEvan Baconimport plist from '@expo/plist'; 38d307f52SEvan Baconimport fs from 'fs'; 48d307f52SEvan Bacon 58d307f52SEvan Baconimport { AppIdResolver } from '../AppIdResolver'; 68d307f52SEvan Bacon 760392ac6SEvan Baconconst debug = require('debug')('expo:start:platforms:ios:AppleAppIdResolver') as typeof console.log; 860392ac6SEvan Bacon 98d307f52SEvan Bacon/** Resolves the iOS bundle identifier from the Expo config or native files. */ 108d307f52SEvan Baconexport class AppleAppIdResolver extends AppIdResolver { 118d307f52SEvan Bacon constructor(projectRoot: string) { 128d307f52SEvan Bacon super(projectRoot, 'ios', 'ios.bundleIdentifier'); 138d307f52SEvan Bacon } 148d307f52SEvan Bacon 15*def098a4SEvan Bacon /** @return `true` if the app has valid `*.pbxproj` file */ 168d307f52SEvan Bacon async hasNativeProjectAsync(): Promise<boolean> { 178d307f52SEvan Bacon try { 1860392ac6SEvan Bacon // Never returns nullish values. 19*def098a4SEvan Bacon return !!IOSConfig.Paths.getAllPBXProjectPaths(this.projectRoot).length; 2060392ac6SEvan Bacon } catch (error: any) { 2160392ac6SEvan Bacon debug('Expected error checking for native project:', error); 2260392ac6SEvan Bacon return false; 238d307f52SEvan Bacon } 248d307f52SEvan Bacon } 258d307f52SEvan Bacon 268d307f52SEvan Bacon async resolveAppIdFromNativeAsync(): Promise<string | null> { 278d307f52SEvan Bacon // Check xcode project 288d307f52SEvan Bacon try { 298d307f52SEvan Bacon const bundleId = IOSConfig.BundleIdentifier.getBundleIdentifierFromPbxproj(this.projectRoot); 308d307f52SEvan Bacon if (bundleId) { 318d307f52SEvan Bacon return bundleId; 328d307f52SEvan Bacon } 3360392ac6SEvan Bacon } catch (error: any) { 3460392ac6SEvan Bacon debug('Expected error resolving the bundle identifier from the pbxproj:', error); 3560392ac6SEvan Bacon } 368d307f52SEvan Bacon 378d307f52SEvan Bacon // Check Info.plist 388d307f52SEvan Bacon try { 398d307f52SEvan Bacon const infoPlistPath = IOSConfig.Paths.getInfoPlistPath(this.projectRoot); 408d307f52SEvan Bacon const data = await plist.parse(fs.readFileSync(infoPlistPath, 'utf8')); 418d307f52SEvan Bacon if (data.CFBundleIdentifier && !data.CFBundleIdentifier.startsWith('$(')) { 428d307f52SEvan Bacon return data.CFBundleIdentifier; 438d307f52SEvan Bacon } 4460392ac6SEvan Bacon } catch (error) { 4560392ac6SEvan Bacon debug('Expected error resolving the bundle identifier from the project Info.plist:', error); 4660392ac6SEvan Bacon } 478d307f52SEvan Bacon 488d307f52SEvan Bacon return null; 498d307f52SEvan Bacon } 508d307f52SEvan Bacon} 51