2012-04-13 11 views
15

Tengo notificaciones automáticas configuradas en mi aplicación. Estoy tratando de determinar si el token del dispositivo que recibí de APNS en el método application:didRegisterForRemoteNotificationsWithDeviceToken: provino de la zona de pruebas o del entorno de desarrollo. Si puedo distinguir qué entorno inicializó el token, podré decirle a mi servidor a qué entorno enviar la notificación de inserción.Determinar si la aplicación se está comunicando con el recinto de seguridad de APNS o el entorno de producción

He intentado utilizar la macro DEBUG para determinar esto, pero he visto un comportamiento extraño con esto y no creo que sea 100% correcto.

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

Idealmente, me gustaría ser capaz de examinar el derecho aps-environment (el valor es desarrollo o producción) en el código, pero no estoy seguro de si esto es posible.

¿Cuál es la forma correcta de determinar si su aplicación se está comunicando con el recinto de seguridad APNS o los entornos de producción? Supongo que el servidor necesita saber esto en primer lugar. Por favor corrígeme si esta es una suposición incorrecta.

Editado: la documentación de Apple en Provider Communication with APNS detalla la diferencia entre la comunicación con el entorno limitado y la producción. Sin embargo, la documentación no proporciona información sobre cómo ser coherente con el registro del token (desde la aplicación cliente de iOS) y la comunicación con el servidor.

Respuesta

14

puede leer y comprobar el archivo de suministro incrustado.

https://github.com/tcurdt/TCMobileProvision

Esto es lo que hago:

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"]; 
+0

La biblioteca está un poco desactualizada, pero funcionó bien para capturar los 'aps- environment' (reemplace '" get-task-allow "' con '" aps-environment "' en el ejemplo de @tcurdt, y no lo compare como un bool) –

+0

@AlbertBori podría archivar un problema sobre lo que es ¿anticuado? – tcurdt

+0

¡Claro! Aquí tienes: https://github.com/tcurdt/TCMobileProvision/issues/1 –

4
  1. El entorno de APN se determina de acuerdo con los derechos firmar código que coincidan con su identidad señal de código (buen puesto here) -, mientras que la identificación de su configuración de generación puede trabajar, también puede ser falsa si se ha emparejado que configuración de generación con un derecho desajustado.

  2. Teniendo esto en cuenta, utilizar DEBUG como medio para determinar sus derechos debe funcionar (si encuentra que DEBUG es complicado, puede agregar un marcador de vinculador propio en "Apple LLVM ..." -> "Otro Banderas C" -> "depuración") por ejemplo, añadir -DDEBUGGING y luego usar:

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

+0

Gracias por la respuesta, @Wiz. Terminé usando un booleano en el archivo plist de configuración. La única pega, como mencionó, es que esta configuración debe coincidir con la identidad de firma de código, que está en el archivo del proyecto. No es deseable, pero es la mejor solución disponible. – goldierox

+0

de acuerdo. Apple podría proporcionar fácilmente API para decirle cuál es la titularidad actual, luego podría configurar la producción o enrutar tokens de espacio aislado a su servidor de recinto de seguridad ... –

0

Como se mencionó en la respuesta de @ tcurdt, la única manera segura de determinar si se debe usar la caja de arena o no es comprobar el archivo de aprovisionamiento. Aquí está el código Swift, utilizando 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 
} 

Para instalar TCMobileProvision, agregar esto a su PODFILE:

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

phatmann, gracias por el código Swift. Me da curiosidad si tienes un motivo para verificar un estado booleano de Sandbox y no devolver verdadero si está en producción. Lo que encontré fue que si estoy ejecutando una compilación local desde xCode, falla al intentar cargar 'mobileprovision', lo que causa un retorno de falso (lo que indica que NO está en el sandbox). Sin embargo, si creo un archivo de almacenamiento aprovisionado para caja de arena que carga correctamente el archivo de suministro móvil e indica correctamente que se trata de una compilación de Sandbox. Siendo este el caso, parece necesario probar para encontrar con éxito la "producción". – KeithB

+0

@KeithB parece que el mejor enfoque podría ser devolver una enumeración con 'sandbox',' production' y 'unspecified'. Siéntete libre de editar el código apropiadamente. – phatmann

4

Este es un truco, pero su trabajo en XCode 8 con Swift 3

Hemos básicamente estamos abriendo el archivo embedded.mobileprovision, convirtiéndolo en una cadena, y luego buscando una cadena que indique que la aplicación está utilizando el entorno de desarrollo 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 
} 
Cuestiones relacionadas