Определите, взаимодействует ли приложение с песочницей APNS или производственной средой

У меня есть push-уведомления, настроенные в моем приложении. Я пытаюсь определить, был ли токен устройства, который я получил от APNS в методе application:didRegisterForRemoteNotificationsWithDeviceToken:, из изолированной среды или среды разработки. Если я могу отличить, какая среда инициализировала токен, я могу сообщить своему серверу, в какую среду отправить push-уведомление.

Я попытался использовать макрос DEBUG, чтобы определить это, но я видел какое-то странное поведение с этим и не доверяю ему, чтобы он был на 100% правильным.

#ifdef DEBUG
BOOL isProd = YES;
#else
BOOL isProd = NO;
#endif

В идеале я мог бы изучить право на aps-environment (значение "Разработка или производство" ) в коде, но я не уверен, что это возможно.

Каков правильный способ определить, взаимодействует ли ваше приложение с песочницей APNS или производственными средами? Я предполагаю, что сервер должен знать это в первую очередь. Пожалуйста, исправьте меня, если это предположение неверно.

Отредактировано. Документация Apple на Связь провайдера с APNS описывает разницу между общением с песочницей и производством. Однако в документации не содержится информации о том, как быть совместимым с регистрацией токена (из клиентского приложения iOS) и общением с сервером.

Ответы

Ответ 1

Вы можете прочитать и проверить встроенный профиль подготовки.

https://github.com/tcurdt/TCMobileProvision

Это то, что я делаю:

NSString *mobileprovisionPath = [[[NSBundle mainBundle] bundlePath]
        stringByAppendingPathComponent:@"embedded.mobileprovision"];
TCMobileProvision *mobileprovision = [[TCMobileProvision alloc] initWithData:[NSData dataWithContentsOfFile:mobileprovisionPath]];
NSDictionary *entitlements = mobileprovision.dict[@"Entitlements"];
NSString *apsEnvironment = entitlements[@"aps-environment"];
BOOL production = entitlements && apsEnvironment && [apsEnvironment isEqualToString:@"production"];

Ответ 2

  • Среда APNS определяется в соответствии с кодовым знаком "Права, соответствующие вашему идентификатору кода" (хорошая запись здесь) - при определении конфигурации сборки может работать, он также может быть ложным, если вы сопоставили эту конфигурацию сборки с неправильным соответствием.

  • Помня об этом, использование DEBUG как средства для определения ваших прав должно работать (если вы обнаружите, что DEBUG будет сложным, вы можете добавить свой собственный флаг компоновщика в разделе "Apple LLVM..." → "Другие флаги C" → "Отладка" ) например, добавьте -DDEBUGGING, а затем используйте:

#ifdef DEBUGGING BOOL isProd = YES; #else BOOL isProd = NO; #endif

Ответ 3

Это взлом, но его работа над XCode 8 с Swift 3

Мы в основном открываем файл embedded.mobileprovision, преобразуем его в строку, а затем проверяем строку, которая указывает, что приложение использует среду aps для разработки.

func isDevelopmentEnvironment() -> Bool {
    guard let filePath = Bundle.main.path(forResource: "embedded", ofType:"mobileprovision") else {
        return false
    }
    do {
        let url = URL(fileURLWithPath: filePath)
        let data = try Data(contentsOf: url)
        guard let string = String(data: data, encoding: .ascii) else {
            return false
        }
        if string.contains("<key>aps-environment</key>\n\t\t<string>development</string>") {
            return true
        }
    } catch {}
    return false
}

Ответ 4

Как упоминалось в ответе @tcurdt, единственный безопасный способ определить, следует ли использовать песочницу или нет, - проверить файл инициализации. Вот код Swift, используя TCMobileProvision:

func isAPNSandbox() -> Bool {
    if let mobileProvisionURL = NSBundle.mainBundle().URLForResource("embedded", withExtension: "mobileprovision"),
    let mobileProvisionData = NSData(contentsOfURL: mobileProvisionURL),
    let mobileProvision = TCMobileProvision(data: mobileProvisionData) {
        if let entitlements = mobileProvision.dict["Entitlements"],
        let apsEnvironment = entitlements["aps-environment"] as? String
        where apsEnvironment == "development" {
            return true
        }
    }

    return false
}

Чтобы установить TCMobileProvision, добавьте это в свой подфайл:

pod 'TCMobileProvision', :git => 'https://github.com/tcurdt/TCMobileProvision.git'