如何在后台处理/存储推送内容到核心数据? [英] How to handle/store push content to core data on background?

查看:31
本文介绍了如何在后台处理/存储推送内容到核心数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In my app, We have a feature to store content receive from push notification to locally core-data and are facing data loss issues on background state,

我们遵循的步骤:

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

1 - Push received in didReceiveRemoteNotification method.

2 - 在核心数据中插入来自push的新数据(所有核心数据处理仅在单个类和单个上下文中处理)

2 - Insert the new data from push in core data( All core data process handling in single class and single context only)

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 - 在屏幕上,从核心数据中读取所有保存的列表并显示.

3 - On screen, reading all saved list from core data and display.

案例:

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

1 - Foreground : It works fine - data store and can read all data.

2 - 关闭状态(退出):用户强制关闭应用,我们从 Web API 读取数据以获取基于上次时间戳的所有列表.

2 - Closed State(Exit) : User force close the app, we read data from web API to get all list based on last time stamp.

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 和背景模式".请检查

Here two cases, We are sure that , added content_available and 'Background mode' enable in xcode. Please check

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

1 - 应用未在后台运行,但我们使用 100% 确定 content_available 键添加到 FCM 的推送通知中,因此应用应带后台模式 静默推送通知 ->如果应用程序被挂起,则系统唤醒或启动您的应用程序并将其置于后台运行状态

1 - App is not running on background but we are using 100% sure content_available key added in push notification from FCM, so app should bring background mode 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 - 应用程序处于挂起状态 - 如何知道应用程序进入挂起状态或本地数据库未能将数据存储到主上下文.

2 - App is in Suspend state - How to know app went suspend state or local DB failed to store data to main context.

我们在 applicationDidEnterBackground 和每次收到推送时调用 saveContext(插入成功).

We calling saveContext on going applicationDidEnterBackground and every push received (on insert success).

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

Please share if any solution/any other possibility to handle push content to store locally like background fetch (but our app needs to update regularly on push received same as live chat)

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

Please let me know if need any more information.

谢谢!

注意:Swift 3.3

更新

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

In iOS 11, Push delegate method is not called on backgrund its a reason for above issue.

iOS 10 -> 工作正常

iOS 10 -> working fine

不适用于 iOS 11,但我们可以在调试模式下接收推送委托方法.

Not working in iOS 11 but we can able to receive push on delegate methods on debug mode.

有什么想法吗?

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

[AnyHashable("gcm.notification.type"): 0, AnyHashable("gcm.notification.msg"): {"extraType":"Text","content":"Test sound"}, AnyHashable("gcm.message_id"): 0:1531860472186830%c52fb209c52fb209, AnyHashable("google.c.a.e"): 1, AnyHashable("aps"): { alert = { body = "text body"; title = "Gopi k"; }; badge = 2; "content-available" = 1; sound = Default; }]

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

Any idea , why delegates in not called since we have added "content-available" = 1 in push messages.

谢谢!

推荐答案

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

The push notification payload in your question contains user-facing elements as well as the content-available flag that indicates a silent notification. A notification can not be both user-facing and silent.

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

Your notification payload should be two separate notifications, one for the silent push, one for the user-visible notification:

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

无声推送:

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

您可以使用我的APNS 有效负载验证工具来检查您的推送有效负载是否有效是有效的.

You can use my APNS Payload Verification Tool to check whether your push payloads are valid.

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

If the user force-closes your app a silent push will not cause the app to be woken to perform background work.

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

As far as using CoreData in the background state you will find several challenges.

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

First, the CoreData store must be writable while the app is in the background and the phone may be locked. The CoreData persistent store must be created with Data Protection values (NSPersistentStoreFileProtectionKey) that are very permissive.

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

Second, iOS will terminate your application (exception code 0xdead10cc) if you leave a CoreData store open too long while the app is in any state but active. This means that as the app transitions from the foreground or active states the CoreData store should be saved and removed from memory - and this must be done in a background task assertion. Cleaning up a CoreData store can take time, and the system may terminate the app in the middle of a save without a background task assertion. When the application is woken to do background work by a silent push it will then have to re-create the CoreData store, perform whatever work it must do, then cleanly save and remove the store from memory. No CoreData files should be left open when the application is done.

这篇关于如何在后台处理/存储推送内容到核心数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆