2012-04-13 28 views
15

Tôi đã thiết lập thông báo đẩy trong ứng dụng của mình. Tôi đang cố gắng xác định liệu mã thông báo thiết bị tôi đã nhận được từ APNS trong phương thức application:didRegisterForRemoteNotificationsWithDeviceToken: có đến từ môi trường sandbox hoặc môi trường phát triển hay không. Nếu tôi có thể phân biệt môi trường nào đã khởi tạo mã thông báo, tôi sẽ có thể thông báo cho máy chủ của tôi biết môi trường nào sẽ gửi thông báo đẩy.Xác định xem ứng dụng có đang kết nối với hộp cát hoặc môi trường sản xuất APNS hay không

Tôi đã thử sử dụng macro DEBUG để xác định điều này, nhưng tôi đã thấy một số hành vi lạ với điều này và không tin tưởng nó là chính xác 100%.

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

Lý tưởng nhất, tôi muốn có thể kiểm tra aps-environment hưởng (giá trị là phát triển hoặc sản xuất) trong mã, nhưng tôi không chắc chắn nếu điều này thậm chí còn có thể.

Cách thích hợp để xác định xem ứng dụng của bạn có đang kết nối với hộp cát APNS hoặc môi trường sản xuất không? Tôi giả định rằng máy chủ cần biết điều này ngay từ đầu. Xin vui lòng sửa tôi nếu đây là giả định là không chính xác.

Đã chỉnh sửa: Tài liệu của Apple trên Provider Communication with APNS nêu chi tiết sự khác biệt giữa giao tiếp với hộp cát và sản xuất. Tuy nhiên, tài liệu không cung cấp thông tin về cách nhất quán với việc đăng ký mã thông báo (từ ứng dụng khách iOS) và liên lạc với máy chủ.

Trả lời

14

Bạn có thể đọc và kiểm tra hồ sơ cá nhân provisioning nhúng.

https://github.com/tcurdt/TCMobileProvision

Đây là những gì tôi làm:

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

Thư viện hơi lỗi thời, nhưng nó hoạt động tốt để nắm bắt 'aps- môi trường' (thay thế '" get-task-allow "' với '" aps-environment "' trong ví dụ @tcurdt, và không so sánh nó như là một bool) –

+0

@AlbertBori bạn có thể vui lòng gửi một vấn đề về cái gì lỗi thời? – tcurdt

+0

Điều chắc chắn! Ở đây bạn đi: https://github.com/tcurdt/TCMobileProvision/issues/1 –

4
  1. Môi trường APNS được xác định theo quyền lợi dấu hiệu đang phù hợp với bản sắc dấu Mã của bạn (bài tốt here) - trong khi xác định cấu hình xây dựng của bạn có thể làm việc, nó cũng có thể là sai lầm nếu bạn đã xuất hiện mà build cấu hình với một quyền lợi phù hợp. Lưu ý rằng, sử dụng DEBUG làm phương tiện để xác định quyền lợi của bạn sẽ hoạt động (nếu bạn thấy DEBUG phức tạp, bạn có thể thêm cờ liên kết của riêng bạn trong "Apple LLVM ..." -> "Khác C Flags" -> "Debug") ví dụ, thêm -DDEBUGGING và sau đó sử dụng:

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

+0

Cảm ơn bạn đã trả lời, @Wiz. Tôi đã kết thúc bằng cách sử dụng một boolean trong tập tin plist cấu hình. Đánh bắt duy nhất, như bạn đã đề cập, là cài đặt cấu hình này phải khớp với danh tính ký mã, có trong tệp dự án. Đó là không mong muốn nhưng giải pháp tốt nhất có sẵn. – goldierox

+0

Đồng ý. Apple có thể dễ dàng cung cấp API để cho bạn biết quyền lợi hiện tại là gì - sau đó bạn có thể thiết lập sản xuất hoặc định tuyến mã thông báo hộp cát tới máy chủ hộp cát của bạn ... –

0

Như đã đề cập trong câu trả lời @ tcurdt của, cách an toàn chỉ để xác định xem có sử dụng sandbox hoặc không phải là để kiểm tra các tập tin dự phòng. Đây là mã Swift, sử dụng 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 
} 

Để cài đặt TCMobileProvision, thêm video này vào Podfile của bạn:

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

phatmann, cảm ơn mã Swift. Tôi tò mò nếu bạn có lý do để kiểm tra trạng thái boolean của Sandbox và không trả về true nếu trên Production? Những gì tôi thấy là nếu tôi đang chạy một xây dựng địa phương từ xCode nó không thành công khi cố gắng tải 'mobileprovision', mà gây ra một sự trở lại của sai (chỉ ra rằng nó không phải là trong sandbox). Tuy nhiên, nếu tôi tạo một tệp lưu trữ được cung cấp sandbox đã tải thành công tệp mobileprovision và cho biết chính xác rằng đây là một bản dựng Sandbox. Đây là trường hợp có vẻ như cần thiết để kiểm tra thành công trong việc tìm kiếm "sản xuất". – KeithB

+0

@KeithB có vẻ như cách tiếp cận tốt nhất có thể là trả về một enum với 'sandbox',' production' và 'unspecified'. Vui lòng chỉnh sửa mã một cách thích hợp. – phatmann

4

Đây là một hack nhưng làm việc của nó trên XCode 8 với Swift 3

Chúng tôi về cơ bản mở tập tin embedded.mobileprovision, chuyển đổi nó thành một chuỗi, sau đó kiểm tra một chuỗi có thể cho biết ứng dụng đang sử dụng môi trường phát triển 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 
} 
Các vấn đề liên quan