【问题标题】:object id nil first time every time swift parse每次快速解析时第一次对象 id 为零
【发布时间】:2015-09-21 13:33:01
【问题描述】:

我正在一个 swift 项目中实现解析。我使用设备的 objectid 作为发送通知的唯一标识符。我为每个用户获取这个值并将其存储在我的数据库中。

我实现了以下方法:

func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
        println("get in here every time?")
        let installation = PFInstallation.currentInstallation()
        installation.setDeviceTokenFromData(deviceToken)

        installation.saveInBackground()

        if installation.objectId != nil {
            installation.setObject(installation.objectId!, forKey: "userName")
            updateNotificationIDWebServiceCall(installation.objectId!)
        }
        else{
            println("object id was nil. Device token was: \(deviceToken).")
            //JLToast.makeText("object id was nil. Device token was: \(deviceToken).").show()
        }
        installation.saveInBackground()
    }

我在应用启动时成功使用此方法,但我的对象 id 始终为零,这是第一次安装应用时。

如果用户关闭应用程序并重新启动,则 objectid 不再为零,我可以使用每个用户的正确标识符更新我的后端,但是我的问题在于将应用程序置于后台并不使用的人甚至不知道如何杀死一个应用程序。

我该如何解决这个问题?我可以在 didBecomeActive 中添加一些代码吗?我似乎找不到 saveInBackground 方法的回调。

这也是我的 didFinishLaunchingWithOptions:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        Prefs.notificationToShow = true

        // Override point for customization after application launch.
        //UIApplication.sharedApplication().applicationIconBadgeNumber = 0

        if (PFInstallation.currentInstallation().badge != 0) {
            PFInstallation.currentInstallation().badge = 0
            PFInstallation.currentInstallation().saveInBackground()
        }
        Parse.setApplicationId("xxx",
            clientKey: "yyy")

        // Register for Push Notitications
        if application.applicationState != UIApplicationState.Background {
            // Track an app open here if we launch with a push, unless
            // "content_available" was used to trigger a background push (introduced in iOS 7).
            // In that case, we skip tracking here to avoid double counting the app-open.

            let preBackgroundPush = !application.respondsToSelector("backgroundRefreshStatus")
            let oldPushHandlerOnly = !self.respondsToSelector("application:didReceiveRemoteNotification:fetchCompletionHandler:")
            var pushPayload = false
            if let options = launchOptions {
                pushPayload = options[UIApplicationLaunchOptionsRemoteNotificationKey] != nil
            }
            if (preBackgroundPush || oldPushHandlerOnly || pushPayload) {
                PFAnalytics.trackAppOpenedWithLaunchOptions(launchOptions)
            }
        }
        if application.respondsToSelector("registerUserNotificationSettings:") {
            let userNotificationTypes = UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound
            let settings = UIUserNotificationSettings(forTypes: userNotificationTypes, categories: nil)
            application.registerUserNotificationSettings(settings)
            application.registerForRemoteNotifications()
        } else {
            let types = UIUserNotificationType.Badge | UIUserNotificationType.Alert | UIUserNotificationType.Sound
            application.registerForRemoteNotifications()
        }

        NSThread.sleepForTimeInterval(1);
        UIApplication.sharedApplication().statusBarHidden = true
        self.window?.makeKeyAndVisible()
        Fabric.with([Twitter(), Crashlytics()])

        return FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
}

【问题讨论】:

    标签: ios swift parse-platform push-notification


    【解决方案1】:

    我不确定为什么安装对象的 objectId 为 nil,但是我有一个替代方法,您可能会感兴趣。

    与其将安装的 objectId 保存给用户以获得唯一标识符,不如考虑在每个安装中保存指向当前用户的指针。每个设备都将获得自己的安装对象,并且一个用户可能拥有多个设备。

    您需要有一种方法可以将推送通知发送到他们的所有设备,但在您当前的设计下,每个用户仅限于一台设备。

    通过将用户指针添加到每个安装对象,您将能够查询和创建用户集以发送通知。

    添加一些调试代码以确保 Parse 正确保存安装可能也是值得的。将您的 didRegisterForRemoteNotificationsWithDeviceToken 更改为以下内容:

    installation.saveInBackgroundWithBlock { (success: Bool, error: NSError?) -> Void in
        if (success) {
            println("success - didRegisterForRemoteNotificationsWithDeviceToken")
        } else {
            //  Log details of the failure
            println("failure - didRegisterForRemoteNotificationsWithDeviceToken")
            println("Error: \(error!) \(error!.userInfo!)")
        }
    } 
    

    【讨论】:

    • 我在应用启动时更新 notificationID,所以如果用户在第二台设备上登录,他们的 id 将被更新并将通知发送到新设备。我们不支持向每位用户多于一台设备发送通知。关于为什么第一次 objectID 为 nil 的任何建议或关于如何在 didbecomeactive 或其他地方获取它的解决方法?我的客户想要这个,因为应用程序的人口统计是可能不会主动杀死应用程序的用户,因此,我后端的 notificationID 仍然为零。检索时有回调吗?
    • 刚刚更新了答案以具有用于保存/调试错误的完成块。我认为问题在于您在didRegisterForRemoteNotificationsWithDeviceToken 中使用了两种不同的保存。我很确定问题在于 objectId 在保存到 Parse 之前将为零。由于保存是在后台异步完成的,因此您当前正在尝试访问尚未完成保存的安装的 objectId
    • 太好了,这是我的想法。将尝试上述不同的方法并报告
    猜你喜欢
    • 1970-01-01
    • 2013-03-10
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多