addUrlScheme method

OperationResult addUrlScheme(
  1. String scheme
)

Adds a URL scheme to the Info.plist for deep linking.

Implementation

OperationResult addUrlScheme(String scheme) {
  final plistFile = File(_infoPlistPath);

  if (!plistFile.existsSync()) {
    return const Failure(
      'Could not find Info.plist. '
      'Are you in a Flutter project root directory?',
    );
  }

  try {
    String content = plistFile.readAsStringSync();

    if (content.contains('<key>CFBundleURLTypes</key>')) {
      if (content.contains('<string>$scheme</string>')) {
        return Success('URL scheme "$scheme" already exists.');
      }

      final schemesPattern = RegExp(
        r'(<key>CFBundleURLSchemes</key>\s*<array>)',
        multiLine: true,
      );

      if (schemesPattern.hasMatch(content)) {
        content = content.replaceFirst(
          schemesPattern,
          '\$1\n\t\t\t\t<string>$scheme</string>',
        );
        plistFile.writeAsStringSync(content);
        return Success('Successfully added URL scheme "$scheme".');
      }
    }

    final dictClosePattern = RegExp(r'</dict>\s*</plist>\s*$');
    final match = dictClosePattern.firstMatch(content);

    if (match == null) {
      return const Failure(
        'Invalid Info.plist format: could not find closing </dict> tag.',
      );
    }

    final urlTypesBlock = '''
\t<key>CFBundleURLTypes</key>
\t<array>
\t\t<dict>
\t\t\t<key>CFBundleURLSchemes</key>
\t\t\t<array>
\t\t\t\t<string>$scheme</string>
\t\t\t</array>
\t\t</dict>
\t</array>
''';

    content = content.replaceFirst(
      dictClosePattern,
      '$urlTypesBlock</dict>\n</plist>\n',
    );

    plistFile.writeAsStringSync(content);
    return Success('Successfully added URL scheme "$scheme".');
  } on FileSystemException catch (e) {
    return Failure('Failed to update Info.plist: ${e.message}');
  }
}