Ответ
Невозможно изменить оригинальный Info.plist в бандле (read-only), но можно читать и работать с копией или альтернативными хранилищами.
1. Чтение значений (только для чтения):
// Базовое чтение
let bundle = Bundle.main
// Чтение строки
if let appName = bundle.object(forInfoDictionaryKey: "CFBundleName") as? String {
print("App name: (appName)")
}
// Чтение массива
if let urlSchemes = bundle.object(forInfoDictionaryKey: "CFBundleURLSchemes") as? [String] {
print("URL schemes: (urlSchemes)")
}
// Типизированные методы
let version = bundle.infoDictionary?["CFBundleShortVersionString"] as? String
let build = bundle.infoDictionary?["CFBundleVersion"] as? String
2. Эмуляция изменяемого Info.plist:
// Создание изменяемой копии в Documents
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
let configURL = documentsURL.appendingPathComponent("RuntimeConfig.plist")
// Инициализация при первом запуске
if !FileManager.default.fileExists(atPath: configURL.path) {
let originalURL = Bundle.main.url(forResource: "Info", withExtension: "plist")!
try FileManager.default.copyItem(at: originalURL, to: configURL)
}
// Чтение/запись изменяемой версии
var config = NSDictionary(contentsOf: configURL) as? [String: Any] ?? [:]
config["CustomAPIEndpoint"] = "https://api.example.com/v2"
(config as NSDictionary).write(to: configURL, atomically: true)
3. Альтернативы для динамических настроек:
| Способ | Использование |
|---|---|
| UserDefaults | Простые настройки пользователя |
| Keychain | Безопасное хранение токенов, ключей |
| Property List в Documents | Конфигурационные файлы |
| Core Data / SQLite | Сложные структурированные данные |
| Remote Config (Firebase) | Удаленное управление настройками |
Важные ограничения:
- Изменения в
Info.plistне влияют на системные вызовы (разрешения, URL schemes) - App Store Review проверяет значения в оригинальном
Info.plist - Кэшированные значения могут не обновляться сразу