【问题标题】:How to handle/store push content to core data on background?如何在后台处理/存储推送内容到核心数据?
【发布时间】:2018-07-15 22:22:17
【问题描述】:

在我的应用中, 我们有一项功能,可以将从推送通知接收的内容存储到本地核心数据,并且在后台状态下面临数据丢失问题,

我们遵循的步骤:

1 - 在 didReceiveRemoteNotification 方法中收到推送。

2 - 将新数据从推送中插入核心数据(所有核心数据仅在单个类和单个上下文中处理)

self.getManagedContext().perform {
            do {
                if self.getManagedContext().hasChanges {
                    print("Core Data class: saveChanges.....")
                    try self.getManagedContext().save()
                }
            } catch {
                let saveError = error as NSError
                print("Core Data class: saveChanges)
                print("\(saveError), \(saveError.localizedDescription)")
            }
        }

3 - 在屏幕上,从核心数据中读取所有保存的列表并显示。

案例:

1 - 前台:它工作正常 - 数据存储并且可以读取所有数据。

2 - Closed State(Exit) : 用户强制关闭应用程序,我们从 Web API 读取数据以根据上次时间戳获取所有列表。

3 - 背景:

 -> On App run from Xcode - Debug:
    We received push notification and can read push data, store in DB. But failed sometimes, we can get stored data on display (some times we can't  read all data only even when app is running in XCode).

-> Open Installed Application(not run from Xcode) -> App failed to list all stored data (its obviously not stored, can't get single data for push received while background mode ).

这里有两种情况, 我们确信,在 xcode 中添加了content_available 和“后台模式”启用。请检查

 AnyHashable("aps"): {
alert =     {
    body = "Hello and 6";
    title = "iPhone 6s ";
};
badge = 2;
"content-available" = 1;}

1 - 应用程序未在后台运行,但我们使用 100% 确定的 content_available 键添加到来自 FCM 的推送通知中,因此应用程序应带后台模式 silent push notification -> if app is suspended then the system wakes up or launches your app and puts it into the background running state

2 - 应用程序处于暂停状态 - 如何知道应用程序进入暂停状态或本地数据库未能将数据存储到主上下文。

我们在进行applicationDidEnterBackground 时调用 saveContext 并收到每个推送(插入成功时)。

请分享是否有任何解决方案/任何其他可能性来处理本地存储的推送内容,例如后台获取(但我们的应用需要在收到推送时定期更新,与实时聊天一样)

如果需要更多信息,请告诉我。

谢谢!

注意:Swift 3.3

更新

在 iOS 11 中,不会在后台调用 Push 委托方法,这是导致上述问题的原因。

iOS 10 -> 工作正常

在 iOS 11 中不工作,但我们可以在调试模式下接收推送委托方法。

有什么想法吗?

[AnyHashable("gcm.notification.type"): 0, AnyHashable("gcm.notification.msg"): {"extraType":"Text","content":"测试声音"}, AnyHashable(" gcm.message_id"): 0:1531860472186830%c52fb209c52fb209, AnyHashable("google.c.a.e"): 1, AnyHashable("aps"): { alert = { body = "text body";标题 = "Gopi k"; };徽章 = 2; “内容可用”= 1;声音=默认; }]

任何想法,为什么没有调用委托,因为我们在推送消息中添加了"content-available" = 1

谢谢!

【问题讨论】:

  • 我的猜测是有一个对象在两个或多个队列中处理。你可以阅读它here
  • 好的,谢谢!我会检查

标签: ios swift core-data apple-push-notifications silentpush


【解决方案1】:

您问题中的推送通知负载包含面向用户的元素以及指示静默通知的content-available 标志。通知不能同时面向用户静默。

您的通知负载应该是两个单独的通知,一个用于静默推送,一个用于用户可见通知:

aps : {
    alert :     {
        body : "Hello and 6",
        title : "iPhone 6s ",
    },
    badge : 2,
}

无声推送:

aps : {
    "content-available" : 1;
}

您可以使用我的APNS Payload Verification Tool 来检查您的推送负载是否有效。

如果用户强制关闭您的应用,静默推送不会导致应用被唤醒以执行后台工作。

就在后台状态下使用 CoreData 而言,您会发现一些挑战。

首先,CoreData 存储在应用处于后台并且手机可能被锁定时必须是可写的。 CoreData 持久存储必须使用非常宽松的数据保护值 (NSPersistentStoreFileProtectionKey) 创建。

其次,如果您在应用程序处于任何状态但处于活动状态时让 CoreData 存储打开时间过长,iOS 将终止您的应用程序(异常代码 0xdead10cc)。这意味着当应用程序从前台或活动状态转换时,CoreData 存储应该被保存并从内存中删除 - 这必须在后台任务断言中完成。清理 CoreData 存储可能需要一些时间,并且系统可能会在没有后台任务断言的情况下在保存过程中终止应用程序。当应用程序通过静默推送唤醒以执行后台工作时,它必须重新创建 CoreData 存储,执行它必须执行的任何工作,然后干净地保存并从内存中删除存储。应用程序完成后,不应打开任何 CoreData 文件。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-01
    • 1970-01-01
    • 2013-09-08
    • 2012-05-01
    • 2011-03-15
    相关资源
    最近更新 更多