2016-02-13 36 views
1

我使用此代碼獲取GCM令牌(APNS和GCM令牌)。是否有自動重試獲取GCM令牌(ios swift)?

當GCM不返回令牌時,會自動執行重試嗎?

如果是這樣 - 我在哪裏可以在代碼中看到它?這種情況發生的頻率如何?

//push 
// [START register_for_remote_notifications] 
func registerForRemoteNotifications(application: UIApplication, launchOptions:[NSObject: AnyObject]?) -> Bool { 
    // [START_EXCLUDE] 
    // Configure the Google context: parses the GoogleService-Info.plist, and initializes 
    // the services that have entries in the file 
    var configureError:NSError? 
    GGLContext.sharedInstance().configureWithError(&configureError) 
    assert(configureError == nil, "Error configuring Google services: \(configureError)") 
    pushManager.gcmSenderID = GGLContext.sharedInstance().configuration.gcmSenderID 
    // [END_EXCLUDE] 
    // Register for remote notifications 
    if #available(iOS 8.0, *) { 
     let settings: UIUserNotificationSettings = 
     UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil) 
     application.registerUserNotificationSettings(settings) 
     application.registerForRemoteNotifications() 
    } else { 
     // Fallback 
     let types: UIRemoteNotificationType = [.Alert, .Badge, .Sound] 
     application.registerForRemoteNotificationTypes(types) 
    } 

    // [END register_for_remote_notifications] 
    // [START start_gcm_service] 
    let gcmConfig = GCMConfig.defaultConfig() 
    gcmConfig.receiverDelegate = pushManager 
    GCMService.sharedInstance().startWithConfig(gcmConfig) 
    // [END start_gcm_service] 
    return true 
} 

func application(application: UIApplication, didRegisterUserNotificationSettings notificationSettings: UIUserNotificationSettings) 
{ 
    UIApplication.sharedApplication().registerForRemoteNotifications() 
} 




func subscribeToTopic() { 
    // If the app has a registration token and is connected to GCM, proceed to subscribe to the 
    // topic 
    if(pushManager.registrationToken != nil && pushManager.connectedToGCM) { 
     GCMPubSub.sharedInstance().subscribeWithToken(pushManager.registrationToken, topic: pushManager.subscriptionTopic, 
      options: nil, handler: {(NSError error) -> Void in 
       if (error != nil) { 
        // Treat the "already subscribed" error more gently 
        if error.code == 3001 { 
         print("Already subscribed to \(self.pushManager.subscriptionTopic)") 
        } else { 
         print("Subscription failed: \(error.localizedDescription)"); 
        } 
       } else { 
        self.pushManager.subscribedToTopic = true; 
        NSLog("Subscribed to \(self.pushManager.subscriptionTopic)"); 
       } 
     }) 
    } 
} 

// [START connect_gcm_service] 
func connectGcmService(application: UIApplication) { 

    if (self.pushManager.connectedToGCM == true) 
    { 
     return 
    } 
    // Connect to the GCM server to receive non-APNS notifications 
    GCMService.sharedInstance().connectWithHandler({ 
     (NSError error) -> Void in 
     if error != nil { 
      print("Could not connect to GCM: \(error.localizedDescription)") 
     } else { 
      self.pushManager.connectedToGCM = true 
      print("Connected to GCM") 
      // [START_EXCLUDE] 
      self.subscribeToTopic() 
      // [END_EXCLUDE] 
     } 
    }) 
} 
// [END connect_gcm_service] 

// [START disconnect_gcm_service] 
func disconnectGcmService(application: UIApplication) { 
    GCMService.sharedInstance().disconnect() 
    // [START_EXCLUDE] 
    self.pushManager.connectedToGCM = false 
    // [END_EXCLUDE] 
} 
// [END disconnect_gcm_service] 


func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken 
    deviceToken: NSData) { 
     let tokenChars = UnsafePointer<CChar>(deviceToken.bytes) 
     var tokenString = "" 

     for i in 0..<deviceToken.length { 
      tokenString += String(format: "%02.2hhx", arguments: [tokenChars[i]]) 
     } 

     print("tokenString: \(tokenString)") 
     pushManager.receiveApnsToken(application, deviceToken: deviceToken) 
} 



func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError 
    error: NSError) { 
     pushManager.receiveApnsTokenError(application, error: error) 
} 


func application(application: UIApplication, 
    didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) { 
     pushManager.ackMessageReception(application, userInfo: userInfo) 



} 

func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) { 
    pushManager.ackMessageReception(application, userInfo: userInfo) 
} 

和PushManager類:

public class PushManager: NSObject, GGLInstanceIDDelegate, GCMReceiverDelegate { 

    var connectedToGCM = false 
    var subscribedToTopic = false 
    var gcmSenderID: String? 
    var registrationToken: String? 
    var registrationOptions = [String: AnyObject]() 

    let registrationKey = "onRegistrationCompleted" 
    let messageKey = "onMessageReceived" 
    let subscriptionTopic = "/topics/global" 

// // [START register_for_remote_notifications] 
    func registerForRemoteNotifications(application: UIApplication, launchOptions: [NSObject: AnyObject]?) -> Bool { 
      // [START_EXCLUDE] 
      // Configure the Google context: parses the GoogleService-Info.plist, and initializes 
      // the services that have entries in the file 
      var configureError:NSError? 
      GGLContext.sharedInstance().configureWithError(&configureError) 
      assert(configureError == nil, "Error configuring Google services: \(configureError)") 
      gcmSenderID = GGLContext.sharedInstance().configuration.gcmSenderID 
      // [END_EXCLUDE] 
      // Register for remote notifications 
      if #available(iOS 8.0, *) { 
       let settings: UIUserNotificationSettings = 
       UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil) 
       application.registerUserNotificationSettings(settings) 
       application.registerForRemoteNotifications() 
      } else { 
       // Fallback 
       let types: UIRemoteNotificationType = [.Alert, .Badge, .Sound] 
       application.registerForRemoteNotificationTypes(types) 
      } 

      // [END register_for_remote_notifications] 
      // [START start_gcm_service] 
      let gcmConfig = GCMConfig.defaultConfig() 
      gcmConfig.receiverDelegate = self 
      GCMService.sharedInstance().startWithConfig(gcmConfig) 
      // [END start_gcm_service] 
      return true 
    } 

    func subscribeToTopic() { 
     // If the app has a registration token and is connected to GCM, proceed to subscribe to the 
     // topic 
     if(registrationToken != nil && connectedToGCM) { 
      GCMPubSub.sharedInstance().subscribeWithToken(self.registrationToken, topic: subscriptionTopic, 
       options: nil, handler: {(NSError error) -> Void in 
        if (error != nil) { 
         // Treat the "already subscribed" error more gently 
         if error.code == 3001 { 
          print("Already subscribed to \(self.subscriptionTopic)") 
         } else { 
          print("Subscription failed: \(error.localizedDescription)"); 
         } 
        } else { 
         self.subscribedToTopic = true; 
         NSLog("Subscribed to \(self.subscriptionTopic)"); 
        } 
      }) 
     } 
    } 

    // [START connect_gcm_service] 
    func connectGcmService(application: UIApplication) { 
     // Connect to the GCM server to receive non-APNS notifications 
     GCMService.sharedInstance().connectWithHandler({ 
      (NSError error) -> Void in 
      if error != nil { 
       print("Could not connect to GCM: \(error.localizedDescription)") 
      } else { 
       self.connectedToGCM = true 
       print("Connected to GCM") 
       // [START_EXCLUDE] 
       self.subscribeToTopic() 
       // [END_EXCLUDE] 
      } 
     }) 
    } 
    // [END connect_gcm_service] 

    // [START disconnect_gcm_service] 
    func applicationDidEnterBackground(application: UIApplication) { 
     GCMService.sharedInstance().disconnect() 
     // [START_EXCLUDE] 
     self.connectedToGCM = false 
     // [END_EXCLUDE] 
    } 
    // [END disconnect_gcm_service] 

    // [START receive_apns_token] 
    public func receiveApnsToken(application: UIApplication, deviceToken: NSData) { 
      // [END receive_apns_token] 
      // [START get_gcm_reg_token] 
      // Create a config and set a delegate that implements the GGLInstaceIDDelegate protocol. 
      let instanceIDConfig = GGLInstanceIDConfig.defaultConfig() 
      instanceIDConfig.delegate = self 
      // Start the GGLInstanceID shared instance with that config and request a registration 
      // token to enable reception of notifications 
      GGLInstanceID.sharedInstance().startWithConfig(instanceIDConfig) 
      registrationOptions = [kGGLInstanceIDRegisterAPNSOption:deviceToken, 
       kGGLInstanceIDAPNSServerTypeSandboxOption:true] 
      GGLInstanceID.sharedInstance().tokenWithAuthorizedEntity(gcmSenderID, 
       scope: kGGLInstanceIDScopeGCM, options: registrationOptions, handler: registrationHandler) 
      // [END get_gcm_reg_token] 
    } 

    // [START receive_apns_token_error] 
    public func receiveApnsTokenError(application: UIApplication, error: NSError) { 
      print("Registration for remote notification failed with error: \(error.localizedDescription)") 
      // [END receive_apns_token_error] 
      let userInfo = ["error": error.localizedDescription] 
      NSNotificationCenter.defaultCenter().postNotificationName(
       registrationKey, object: nil, userInfo: userInfo) 
    } 

    // [START ack_message_reception] 
    func ackMessageReception(application: UIApplication, userInfo: [NSObject : AnyObject]) {//, fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) { 
      print("Notification received: \(userInfo)") 
      // This works only if the app started the GCM service 
      GCMService.sharedInstance().appDidReceiveMessage(userInfo); 
      ... 
    } 

    func application(application: UIApplication, 
     didReceiveRemoteNotification userInfo: [NSObject : AnyObject], 
     fetchCompletionHandler handler: (UIBackgroundFetchResult) -> Void) { 
      print("Notification received: \(userInfo)") 
      // This works only if the app started the GCM service 
      GCMService.sharedInstance().appDidReceiveMessage(userInfo); 
      // Handle the received message 
      // Invoke the completion handler passing the appropriate UIBackgroundFetchResult value 
      // [START_EXCLUDE] 
      NSNotificationCenter.defaultCenter().postNotificationName(messageKey, object: nil, 
       userInfo: userInfo) 
      handler(UIBackgroundFetchResult.NoData); 
      // [END_EXCLUDE] 
    } 
    // [END ack_message_reception] 

    func registrationHandler(registrationToken: String!, error: NSError!) { 
     if (registrationToken != nil) { 
      self.registrationToken = registrationToken 
      print("Registration Token: \(registrationToken)") 
      self.subscribeToTopic() 
      let userInfo = ["registrationToken": registrationToken] 
      NSNotificationCenter.defaultCenter().postNotificationName(
       self.registrationKey, object: nil, userInfo: userInfo) 
     } else { 
      print("Registration to GCM failed with error: \(error.localizedDescription)") 
      let userInfo = ["error": error.localizedDescription] 
      NSNotificationCenter.defaultCenter().postNotificationName(
       self.registrationKey, object: nil, userInfo: userInfo) 
     } 
    } 

    // [START on_token_refresh] 
    public func onTokenRefresh() { 
     // A rotation of the registration tokens is happening, so the app needs to request a new token. 
     print("The GCM registration token needs to be changed.") 
     GGLInstanceID.sharedInstance().tokenWithAuthorizedEntity(gcmSenderID, 
      scope: kGGLInstanceIDScopeGCM, options: registrationOptions, handler: registrationHandler) 
    } 
+0

你還在遇到他的問題嗎? –

回答

0

基於該docs,如果註冊失敗,則客戶端應用程序建議重試。如果GCM對於客戶端應用程序的運行不是必不可少的,則應用程序可以忽略註冊錯誤,並在下次啓動時嘗試重新註冊。否則,它應該使用指數回退重試註冊操作(客戶端應用程序應該在重試之前等待兩倍的時間)。一旦你的客戶端應用程序有一個註冊令牌,它可以通過GCM APNs接口接收消息。

要處理刷新註冊令牌的情況,GGLInstanceIDDelegate協議會聲明一個onTokenRefresh方法,該方法在系統確定需要刷新令牌時調用。

func onTokenRefresh() { 
// A rotation of the registration tokens is happening, so the app needs to request a new token. 
print("The GCM registration token needs to be changed.") 
GGLInstanceID.sharedInstance().tokenWithAuthorizedEntity(gcmSenderID, 
scope: kGGLInstanceIDScopeGCM, options: registrationOptions, handler: registrationHandler) 
} 
相關問題