How to handle/store push content to core data on background?

廉价感情. 提交于 2019-12-14 02:52:41

问题


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,

Steps we followed:

1 - Push received in didReceiveRemoteNotification method.

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 - On screen, reading all saved list from core data and display.

Cases:

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

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 - Background:

 -> 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 ).

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 - 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 - App is in Suspend state - How to know app went suspend state or local DB failed to store data to main context.

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.

Thanks!

Note: Swift 3.3

Update

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

iOS 10 -> working fine

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

Any idea?

[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; }]

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

Thanks!


回答1:


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,
}

Silent push:

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

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.

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

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.

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.



来源:https://stackoverflow.com/questions/51352652/how-to-handle-store-push-content-to-core-data-on-background

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!