resolveBundleId static method

Future<String> resolveBundleId(
  1. String appRoot,
  2. IosConfig config, {
  3. String? flavor,
  4. ProcessRunner processRunner = const SystemProcessRunner(),
  5. bool? isMacOS,
})

Resolves the main application bundle identifier.

Implementation

static Future<String> resolveBundleId(
  String appRoot,
  IosConfig config, {
  String? flavor,
  ProcessRunner processRunner = const SystemProcessRunner(),
  bool? isMacOS,
}) async {
  final configuredBundleId = config.bundleId;
  if (configuredBundleId != null) return configuredBundleId;
  if (!(isMacOS ?? Platform.isMacOS)) {
    throw const SmfError(
      'platforms.ios.bundle_id is required when configuration is validated '
      'outside macOS.',
      SmfErrorCode.bundleIdRequired,
    );
  }

  final projectRoot = p.normalize(p.absolute(appRoot));
  final iosDirectory = p.join(projectRoot, 'ios');
  final container = await _xcodeContainer(iosDirectory);
  final scheme = flavor ?? 'Runner';
  final arguments = <String>[
    container.option,
    container.path,
    '-scheme',
    scheme,
    '-configuration',
    'Release',
    '-sdk',
    'iphoneos',
    '-showBuildSettings',
  ];
  final result = await processRunner.run(
    'xcodebuild',
    arguments,
    options: RunOptions(workingDirectory: projectRoot),
  );
  final matches = RegExp(
    r'PRODUCT_BUNDLE_IDENTIFIER = (.+)$',
    multiLine: true,
  ).allMatches(result.stdout);
  final bundleId = matches.isEmpty ? null : matches.last.group(1)?.trim();
  if (bundleId == null || bundleId.isEmpty || bundleId.contains(r'$(')) {
    throw const SmfError(
      'Could not detect PRODUCT_BUNDLE_IDENTIFIER. Set '
      'platforms.ios.bundle_id in smf/config.yaml.',
      SmfErrorCode.bundleIdRequired,
    );
  }
  return bundleId;
}