Налаштування Managed App Configuration для iOS-додатку

TRUETECH займається розробкою, підтримкою та обслуговуванням мобільних додатків iOS, Android, PWA. Маємо великий досвід та експертизу для публікації мобільних додатків до популярних маркетів Google Play, App Store, Amazon, AppGallery та інші.

Розробка та підтримка будь-яких видів мобільних додатків:

Інформаційні та розважальні мобільні програми
Новинки, ігри, довідники, онлайн-каталоги, погодні, фітнес та здоров'я, туристичні, освітні, соціальні мережі та месенджери, квіз, блоги та подкасти, форуми, агрегатори
Мобільні програми електронної комерції
Інтернет-магазини, B2B-додатки, маркетплейси, онлайн-обмінники, кешбек-сервіси, біржі, дропшиппінг-платформи, програми лояльності, доставка їжі та товарів, платіжні системи
Мобільні програми для управління бізнес-процесами
CRM-системи, ERP-системи, управління проектами, інструменти для команди продажів, облік фінансів, управління виробництвом, логістика та доставка, управління персоналом, системи моніторингу даних
Мобільні програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, платформи надання електронних послуг, платформи кешбеку, відеохостинги, тематичні портали, платформи онлайн-бронювання та запису, платформи онлайн-торгівлі

Це лише деякі з типів мобільних додатків, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 1735 послуг
Налаштування Managed App Configuration для iOS-додатку
Середній
від 1 дня до 3 днів
Часті запитання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_mobile-applications_feedme_467_0.webp
    Розробка мобільного додатка для компанії FEEDME
    792
  • image_mobile-applications_xoomer_471_0.webp
    Розробка мобільного додатку для компанії XOOMER
    671
  • image_mobile-applications_rhl_428_0.webp
    Розробка мобільного додатку для компанії RHL
    1097
  • image_mobile-applications_zippy_411_0.webp
    Розробка мобільного додатку для компанії ZIPPY
    969
  • image_mobile-applications_affhome_429_0.webp
    Розробка мобільного додатку для компанії Affhome
    914
  • image_mobile-applications_flavors_409_0.webp
    Розробка мобільного додатку для компанії FLAVORS
    495

Настройка Managed App Configuration для iOS-додатка

Managed App Configuration—механізм Apple MDM, який дозволяє IT-адміністратору передавати конфігурацію в додаток без участі користувача та без хардкода параметрів у коді. MDM-сервер відправляє plist-словник, додаток читає його з UserDefaults. Це стандарт для будь-якого корпоративного iOS-додатка—працює з Jamf, Intune, Workspace ONE, MobileIron та будь-яким іншим MDM.

Як додаток читає Managed Config

Все зберігається в UserDefaults під ключем com.apple.configuration.managed:

func loadManagedConfiguration() {
    guard let config = UserDefaults.standard.dictionary(forKey: "com.apple.configuration.managed") else {
        // Пристрій неуправляємий або конфіг ще не доставлений
        applyDefaultConfiguration()
        return
    }

    let backendURL = config["BackendURL"] as? String ?? AppDefaults.backendURL
    let tenantID = config["TenantID"] as? String
    let sessionTimeout = config["SessionTimeoutMinutes"] as? Int ?? 30
    let enableDebugLogs = config["EnableDebugLogs"] as? Bool ?? false

    AppConfig.shared.apply(
        backendURL: backendURL,
        tenantID: tenantID,
        sessionTimeout: sessionTimeout,
        debugLogs: enableDebugLogs
    )
}

Одна ловушка: конфігурація може не прийти відразу при першому запуску, а через кілька секунд після MDM-checkin. Додаток не повинен блокуватися в очікуванні конфіга—застосовуємо дефолти, потім оновлюємо.

Реакція на зміни конфігурації

MDM може оновити конфіг в будь-який момент—напр., змінити URL бекенду при міграції інфраструктури. Потрібно реагувати без перезапуску:

override func viewDidLoad() {
    super.viewDidLoad()

    NotificationCenter.default.addObserver(
        self,
        selector: #selector(managedConfigChanged),
        name: UserDefaults.didChangeNotification,
        object: nil
    )
}

@objc private func managedConfigChanged() {
    guard let newConfig = UserDefaults.standard.dictionary(forKey: "com.apple.configuration.managed") else { return }

    let newBackendURL = newConfig["BackendURL"] as? String
    if newBackendURL != AppConfig.shared.backendURL {
        // Переініціалізуємо мережневий шар з новим URL
        NetworkManager.shared.reconfigure(baseURL: newBackendURL)
    }
}

UserDefaults.didChangeNotification спрацьовує при будь-якій зміні UserDefaults—фільтруємо лише потрібний ключ, щоб не перезавантажувати конфігурацію при кожній дрібній зміні.

Структура конфігураційного словника

Рекомендований підхід—JSON Schema для документування ключів конфігурації. AppConfig Manager на стороні додатка:

struct ManagedConfig: Decodable {
    let backendURL: String
    let tenantID: String?
    let sessionTimeoutMinutes: Int
    let allowBiometricAuth: Bool
    let supportedLanguages: [String]
    let featureFlags: [String: Bool]?

    enum CodingKeys: String, CodingKey {
        case backendURL = "BackendURL"
        case tenantID = "TenantID"
        case sessionTimeoutMinutes = "SessionTimeoutMinutes"
        case allowBiometricAuth = "AllowBiometricAuth"
        case supportedLanguages = "SupportedLanguages"
        case featureFlags = "FeatureFlags"
    }
}

func decodeManagedConfig() -> ManagedConfig? {
    guard let dict = UserDefaults.standard.dictionary(forKey: "com.apple.configuration.managed"),
          let data = try? JSONSerialization.data(withJSONObject: dict),
          let config = try? JSONDecoder().decode(ManagedConfig.self, from: data) else {
        return nil
    }
    return config
}

Типізована структура краща, ніж ручне приведення типів з [AnyHashable: Any]—помилки конфігурації виявляються раніше.

AppConfig у MDM-консолях

У Jamf Pro конфігурація задається в Apps → App Configuration → XML Profile:

<dict>
    <key>BackendURL</key>
    <string>https://api.corp.example.com/v2</string>
    <key>TenantID</key>
    <string>CORP-EU-001</string>
    <key>SessionTimeoutMinutes</key>
    <integer>20</integer>
    <key>AllowBiometricAuth</key>
    <true/>
    <key>SupportedLanguages</key>
    <array>
        <string>en</string>
        <string>de</string>
    </array>
</dict>

У Intune—через Apps → App Configuration Policies → Managed Devices → iOS/iPadOS → General. Значення вводяться як key-value або XML. Intune передає через Apple MDM протокол—той же com.apple.configuration.managed ключ.

Тестування без MDM-сервера

Для розробки конфігурацію можна емулювати через UserDefaults.standard.set() у launch arguments або окремий debug-екран:

#if DEBUG
func injectTestManagedConfig() {
    let testConfig: [String: Any] = [
        "BackendURL": "https://staging-api.corp.example.com",
        "TenantID": "TEST-001",
        "SessionTimeoutMinutes": 5,
        "AllowBiometricAuth": true
    ]
    UserDefaults.standard.set(testConfig, forKey: "com.apple.configuration.managed")
}
#endif

Правильно також тестувати в Simulator з Managed Preferences через defaults write у терміналі—це імітує реальну доставку конфіга через MDM без необхідності реального MDM-сервера.

Feedback Channel: отчет стану в MDM

MDM може не лише передавати конфіг, але й читати стан додатка через com.apple.configuration.managed.feedback. Додаток записує туди статус:

UserDefaults.standard.set([
    "LastSyncTime": ISO8601DateFormatter().string(from: Date()),
    "ConfigVersion": "2.1",
    "EnrollmentStatus": "active"
], forKey: "com.apple.feedback.managed")

MDM-сервер (Jamf, Intune) читає цей ключ при checkin та відображає в інвентарі пристрою. Зручно для діагностики без звернення до користувача.

Етапи настройки

Визначення параметрів конфігурації → розробка схеми словника → реалізація чтення + реакції на зміни → тестування без MDM → публікація документації ключів для IT-відділу → настройка профілів у MDM-консолі → пілот → rollout.

Терміни: реалізація Managed App Configuration у готовому додатку—1–2 тижні. Вартість розраховується індивідуально.