2012-04-13 20 views
15

我在我的應用程序中設置了推送通知。我正試圖確定我從方法中的APNS收到的設備令牌是否來自沙箱或開發環境。如果我可以區分哪個環境初始化令牌,我可以告訴服務器哪個環境發送推送通知。確定應用程序是否正在與APNS沙箱或生產環境進行通信

我試過使用DEBUG宏來確定這一點,但我已經看到了一些奇怪的行爲,並且不相信它是100%正確的。

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

理想情況下,我可以檢查aps-environment資格(價值開發或生產)的代碼,但我不知道這甚至有可能。

什麼是確定您的應用程序是否與APNS沙箱或生產環境進行通信的正確方法?我假設服務器首先需要知道這一點。如果這是假設是不正確的,請糾正我。

編輯:關於Provider Communication with APNS的Apple文檔詳細介紹了與沙箱和生產進行通信的區別。但是,文檔不提供有關如何與註冊令牌(從iOS客戶端應用程序)一致並與服務器通信的信息。如果你已經是匹配的構建配置,同時確定您的構建配置可能會工作,也可能是假的 -

回答

14

你可以閱讀和檢查的嵌入供應曲線。

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

該庫有點過時了,但它很好地抓住了'aps-環境'(在@tcurdt的例子中用''aps-environment''替換'get-task-allow''',並且不要把它比作bool) – 2015-02-19 22:25:41

+0

@AlbertBori你能否提出一個關於什麼是過時? – tcurdt 2015-02-20 00:14:03

+0

當然可以!在這裏你去:https://github.com/tcurdt/TCMobileProvision/issues/1 – 2015-02-20 17:03:41

4
  1. 的APNS環境是根據代碼符號應享權利匹配您的驗證碼登錄身份(好後here)確定與錯配的權利。請記住,使用DEBUG作爲一種手段來確定您的權利應該可以工作(如果您發現DEBUG變得棘手,您可以在「Apple LLVM ...」 - >「其他地方」添加您自己的鏈接器標誌C標記」 - > 「調試」) 例如,添加-DDEBUGGING然後用:

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

+0

感謝您的回覆,@Wiz。我結束了在配置plist文件中使用布爾值。正如你所提到的,唯一的缺點是這個配置設置必須與項目文件中的代碼簽名標識相匹配。這是不可取的,但是可用的最佳解決方案。 – goldierox 2012-04-26 18:09:31

+0

同意。蘋果公司可以很容易地提供API來告訴你當前的權利是什麼 - 然後你可以設置生產,或將沙箱標記路由到你的沙箱服務器...... – 2012-11-27 15:27:13

0

正如@ tcurdt的答覆中提到,唯一安全的方法來確定是否使用沙箱或不是是檢查配置文件。這裏是銀行代碼,使用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,添加到您的Podfile:

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

phatmann,謝謝你的Swift代碼。我很好奇你是否有理由檢查沙箱的布爾狀態,如果在生產環境中不返回true?我發現的是,如果我從xCode運行本地構建,在嘗試加載'mobileprovision'時會失敗,這將導致返回false(表明它不在沙箱中)。但是,如果我創建了成功加載mobileprovision文件的沙箱預配置歸檔文件並正確指出這是沙盒版本。這種情況似乎有必要進行測試,以便成功找到「生產」。 – KeithB 2016-11-29 21:06:51

+0

@KithithB似乎最好的辦法可能是用'sandbox','production'和'unspecified'來返回一個枚舉。隨意編輯適當的代碼。 – phatmann 2016-12-05 19:25:58

4

這是一個黑客,但其對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 
} 
相關問題