1import { IOSConfig } from '@expo/config-plugins';
2import plist from '@expo/plist';
3import fs from 'fs';
4
5import { AppIdResolver } from '../AppIdResolver';
6
7/** Resolves the iOS bundle identifier from the Expo config or native files. */
8export class AppleAppIdResolver extends AppIdResolver {
9  constructor(projectRoot: string) {
10    super(projectRoot, 'ios', 'ios.bundleIdentifier');
11  }
12
13  async hasNativeProjectAsync(): Promise<boolean> {
14    try {
15      return !!IOSConfig.Paths.getAppDelegateFilePath(this.projectRoot);
16    } catch {
17      return true;
18    }
19  }
20
21  async resolveAppIdFromNativeAsync(): Promise<string | null> {
22    // Check xcode project
23    try {
24      const bundleId = IOSConfig.BundleIdentifier.getBundleIdentifierFromPbxproj(this.projectRoot);
25      if (bundleId) {
26        return bundleId;
27      }
28    } catch {}
29
30    // Check Info.plist
31    try {
32      const infoPlistPath = IOSConfig.Paths.getInfoPlistPath(this.projectRoot);
33      const data = await plist.parse(fs.readFileSync(infoPlistPath, 'utf8'));
34      if (data.CFBundleIdentifier && !data.CFBundleIdentifier.startsWith('$(')) {
35        return data.CFBundleIdentifier;
36      }
37    } catch {}
38
39    return null;
40  }
41}
42