Determine whether app is communicating with APNS sandbox or production environment

落花浮王杯 提交于 2020-01-10 07:43:29

问题


I have push notifications set up in my app. I'm trying to determine whether the device token I've received from APNS in the application:didRegisterForRemoteNotificationsWithDeviceToken: method came from the sandbox or development environment. If I can distinguish which environment initialized the token, I'll be able to tell my server to which environment to send the push notification.

I've tried using the DEBUG macro to determine this, but I've seen some strange behavior with this and don't trust it to be 100% correct.

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

Ideally, I'd be able to examine the aps-environment entitlement (value is Development or Production) in code, but I'm not sure if this is even possible.

What's the proper way to determine whether your app is communicating with the APNS sandbox or production environments? I'm assuming that the server needs to know this in the first place. Please correct me if this is assumption is incorrect.

Edited: Apple's documentation on Provider Communication with APNS details the difference between communicating with the sandbox and production. However, the documentation doesn't give information on how to be consistent with registering the token (from the iOS client app) and communicating with the server.


回答1:


You can read and check the embedded provisioning profile.

https://github.com/tcurdt/TCMobileProvision

This is what I do:

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:


This is a hack but its working on XCode 8 with Swift 3

We're basically opening the embedded.mobileprovision file, converting it to a string, then checking for a string that would indicate the app is using the development aps-environment.

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
}



回答3:


  1. The APNS environment is determined according to the code sign Entitlements matching your Code sign identity (good post here) - while identifying your build configuration may work, it may also be false if you've matched that build configuration with a mis-matched entitlement.

  2. Keeping that in mind, using DEBUG as a mean to determine your entitlements should work (if you find DEBUG to be tricky, you can add a your own linker flag under "Apple LLVM..." -> "Other C Flags" -> "Debug") for example, add -DDEBUGGING and then use:

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




回答4:


As mentioned in @tcurdt's answer, the only safe way to determine whether to use the sandbox or not is to check the provisioning file. Here is the Swift code, using 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
}

To install TCMobileProvision, add this to your Podfile:

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


来源:https://stackoverflow.com/questions/10146911/determine-whether-app-is-communicating-with-apns-sandbox-or-production-environme

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!