addPlistKey method

OperationResult addPlistKey(
  1. String key,
  2. String value, {
  3. PlistValueType valueType = PlistValueType.string,
})

Adds a key-value pair to the iOS Info.plist file.

Implementation

OperationResult addPlistKey(
  String key,
  String value, {
  PlistValueType valueType = PlistValueType.string,
}) {
  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();

    final keyPattern = RegExp(
      '<key>${RegExp.escape(key)}</key>',
      multiLine: true,
    );

    if (keyPattern.hasMatch(content)) {
      return Success('Key "$key" already exists in Info.plist.');
    }

    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 valueElement = switch (valueType) {
      PlistValueType.string => '<string>$value</string>',
      PlistValueType.boolean =>
        value.toLowerCase() == 'true' ? '<true/>' : '<false/>',
      PlistValueType.integer => '<integer>$value</integer>',
      PlistValueType.array =>
        '<array>\n\t\t<string>$value</string>\n\t</array>',
    };

    final insertion = '\t<key>$key</key>\n\t$valueElement\n';
    content = content.replaceFirst(
      dictClosePattern,
      '$insertion</dict>\n</plist>\n',
    );

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