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

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

问题描述

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

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-从推入核心数据中插入新数据(所有核心数据处理仅在单个类和单个上下文中进行处理)

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和'Background mode'启用.请检查

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%确保在FCM的推送通知中添加了content_available键,因此应用程序应进入后台模式silent push notification -> if app is suspended then the system wakes up or launches your app and puts it into the background running state

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-应用程序处于挂起状态-如何知道应用程序处于挂起状态或本地DB无法将数据存储到主上下文.

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中,在backgrund上未调用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":文本",内容":测试声音"},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存储区必须是可写的,并且手机可能已锁定.必须使用非常允许的数据保护值(NSPersistentStoreFileProtectionKey)创建CoreData持久性存储.

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天全站免登陆