首页 文章

ios Swift GCM注册令牌为零

提问于
浏览
4

我究竟做错了什么?它打印出我的registrationToken是NIL,虽然它也成功打印出注册到GCM .

appDelegate.swift

import UIKit
import SlideMenuControllerSwift
import AFNetworking

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
    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"


    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        var configureError:NSError?
        GGLContext.sharedInstance().configureWithError(&configureError)
        if configureError != nil {
            println("Error configuring the Google context: \(configureError)")
        }
        gcmSenderID = GGLContext.sharedInstance().configuration.gcmSenderID
        // [END_EXCLUDE]

        // Register for remote notifications
        var types: UIUserNotificationType = UIUserNotificationType.Badge | UIUserNotificationType.Alert | UIUserNotificationType.Sound
        var settings: UIUserNotificationSettings =
        UIUserNotificationSettings( forTypes: types, categories: nil )
        application.registerUserNotificationSettings(settings)
        application.registerForRemoteNotifications()

        // [START start_gcm_service]
        GCMService.sharedInstance().startWithConfig(GCMConfig.defaultConfig())

        AFNetworkReachabilityManager.sharedManager().startMonitoring()
        // Override point for customization after application launch.
        Utilities.customizeNavigationBar()
        Utilities.customizeNavigationBarButtons()
        let storyboard = UIStoryboard(name: "MenuStoryboard", bundle: nil)
        let containerController: RestaurantTableViewController = storyboard.instantiateViewControllerWithIdentifier("hi") as! RestaurantTableViewController
        let rightMenu: RightMenuViewController = storyboard.instantiateViewControllerWithIdentifier("rightMenu") as! RightMenuViewController
        let leftMenu: LeftMenuViewController = storyboard.instantiateViewControllerWithIdentifier("leftMenu") as! LeftMenuViewController


        let nvc: UINavigationController = UINavigationController(rootViewController: containerController)
        //        leftMenu.mainViewController = nvc

        let slideMenuController = SlideMenuController(mainViewController:nvc, leftMenuViewController: leftMenu, rightMenuViewController: rightMenu)
        self.window?.rootViewController = slideMenuController
        self.window?.makeKeyAndVisible()

        return true
    }
    func application( application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData ) {

        // Start the GGLInstanceID shared instance with the default config and request a registration token to enable reception of notifications
        GGLInstanceID.sharedInstance().startWithConfig(GGLInstanceIDConfig.defaultConfig())
        registrationOptions = [kGGLInstanceIDRegisterAPNSOption:deviceToken,
            kGGLInstanceIDAPNSServerTypeSandboxOption:true]
        GGLInstanceID.sharedInstance().tokenWithAuthorizedEntity(gcmSenderID, scope: kGGLInstanceIDScopeGCM, options: registrationOptions, handler: registrationHandler)


    }

    // [START receive_apns_token_error]
    func application( application: UIApplication, didFailToRegisterForRemoteNotificationsWithError
        error: NSError ) {
            println("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)
    }


    func registrationHandler(registrationToken: String!, error: NSError!) {
        if (registrationToken != nil) {
            self.registrationToken = registrationToken
            println("Registration Token: \(registrationToken)")
              NSUserDefaults.standardUserDefaults().setObject(registrationToken, forKey: "registrationToken")
            self.subscribeToTopic()
            let userInfo = ["registrationToken": registrationToken]
            NSNotificationCenter.defaultCenter().postNotificationName(
                self.registrationKey, object: nil, userInfo: userInfo)
        } else {
            println("Registration to GCM failed with error: \(error.localizedDescription)")
            let userInfo = ["error": error.localizedDescription]
            NSNotificationCenter.defaultCenter().postNotificationName(
                self.registrationKey, object: nil, userInfo: userInfo)
        }    }
    func onTokenRefresh() {
        // A rotation of the registration tokens is happening, so the app needs to request a new token.
        println("The GCM registration token needs to be changed.")
        GGLInstanceID.sharedInstance().tokenWithAuthorizedEntity(gcmSenderID,
            scope: kGGLInstanceIDScopeGCM, options: registrationOptions, handler: registrationHandler)
    }

    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 applicationDidBecomeActive( 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]
            }
        })
    }


    // [START ack_message_reception]
    func application( application: UIApplication,
        didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
            print("Notification received: \(userInfo)")
            // This works only if the app started the GCM service
            GCMService.sharedInstance().appDidReceiveMessage(userInfo);
            // Handle the received message
            // [START_EXCLUDE]
            NSNotificationCenter.defaultCenter().postNotificationName(messageKey, object: nil,
                userInfo: userInfo)
            // [END_EXCLUDE]
    }

    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]
    }
    func applicationDidEnterBackground(application: UIApplication) {
        GCMService.sharedInstance().disconnect()
        // [START_EXCLUDE]
        self.connectedToGCM = false
        // [END_EXCLUDE]
        println("Stop executing app and whent into background!")
    }

    func applicationWillEnterForeground(application: UIApplication) {
        // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
    }


    func applicationWillTerminate(application: UIApplication) {
        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    }


    // [START upstream_callbacks]
    func willSendDataMessageWithID(messageID: String!, error: NSError!) {
        if (error != nil) {
            // Failed to send the message.
        } else {
            // Will send message, you can save the messageID to track the message
        }
    }

    func didSendDataMessageWithID(messageID: String!) {
        // Did successfully send message identified by messageID
    }
    // [END upstream_callbacks]

    func didDeleteMessagesOnServer() {
        // Some messages sent to this device were deleted on the GCM server before reception, likely
        // because the TTL expired. The client should notify the app server of this, so that the app
        // server can resend those messages.
    }
}

Error LOG

Tracking ID must not be nil or empty.
Client ID must not be nil or empty.
Attempted to configure [Identity, Analytics, AdMob, SignIn, AppInvite, CloudMessaging].
Successfully configured [CloudMessaging].
Failed to configure [Analytics, SignIn].
Subspecs not present, so not configured [Identity, AdMob, AppInvite].

Error configuring the Google context: Optional(Error Domain=com.google.greenhouse Code=-200 "Unable to configure GGL." 
UserInfo=0x7fdab9d3a390 {NSLocalizedRecoverySuggestion=Check formatting and location of GoogleService-Info.plist., NSLocalizedDescription=Unable to configure GGL., NSLocalizedFailureReason=Unable to parse supplied GoogleService-Info.plist. See log for details.})

我正在尝试连接到GCM,我已经设置了SENDER-ID和SENDER ID,现在有什么问题了吗?

Setting up a GCM Client App on iOS它说:

如果注册成功,InstanceID将使用有效的注册令牌和nil错误对象调用registrationToken处理程序 . 如果注册失败,则注册令牌为nil并返回有效的错误对象 . 有关错误代码的详细信息,请参阅GGLInstanceID.h . 注册失败时,客户端应用程序应实施指数退避以重试 .

我得到输出 nil error object 但也有nil注册令牌 .

1 回答

  • 1

    我认为您的代码没有任何问题,因为这是在 iOS Client 上实现 Cloud Messaging 的正确方法 .

    您可能错过的一些棘手的部分是Provisioning APNs SSL Certificates的配置

    • 使用推送通知创建您的应用程序ID

    • 创建SSL证书

    • 下载并运行它以便添加到配置文件

    • 要确保您的配置文件具有此证书,请转至 Xcode -> Preferences -> Account -> Your Apple ID -> Your Team -> View Details -> Download All .

    这将刷新您的证书,然后转到您的目标,选择正确的团队并运行它 . 希望它应该工作:)

相关问题