I have implemented NotificationServiceExtension in my target application, and it is working fine.
Created AppgroupID
lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator? = {
var coordinator: NSPersistentStoreCoordinator? = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
let options = [
NSMigratePersistentStoresAutomaticallyOption: true,
NSInferMappingModelAutomaticallyOption: true
]
let oldStoreUrl = self.applicationDocumentsDirectory.appendingPathComponent("Model.sqlite")
let directory: NSURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: AppGroupID)! as NSURL
let newStoreUrl = directory.appendingPathComponent("Model.sqlite")!
var targetUrl : URL? = nil
var needMigrate = false
var needDeleteOld = false
if FileManager.default.fileExists(atPath: oldStoreUrl.path){
needMigrate = true
targetUrl = oldStoreUrl
}
if FileManager.default.fileExists(atPath: newStoreUrl.path){
needMigrate = false
targetUrl = newStoreUrl
if FileManager.default.fileExists(atPath: oldStoreUrl.path){
needDeleteOld = true
}
}
if targetUrl == nil {
targetUrl = newStoreUrl
}
if needMigrate {
do {
try coordinator?.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: targetUrl!, options: options)
if let store = coordinator?.persistentStore(for: targetUrl!) {
do {
try coordinator?.migratePersistentStore(store, to: newStoreUrl, options: options, withType: NSSQLiteStoreType)
} catch let error {
print("migrate failed with error : \(error)")
}
}
} catch let error {
//CrashlyticsHelper.reportCrash(err: error as NSError, strMethodName: "migrateStore")
print(error)
}
}
if needDeleteOld {
self.deleteDocumentAtUrl(url: oldStoreUrl)
self.deleteDocumentAtUrl(url: self.applicationDocumentsDirectory.appendingPathComponent("Model.sqlite-shm"))
self.deleteDocumentAtUrl(url: self.applicationDocumentsDirectory.appendingPathComponent("Model.sqlite-wal"))
}
do {
try coordinator!.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: targetUrl, options: options)
} catch var error as NSError {
coordinator = nil
NSLog("Unresolved error \(error), \(error.userInfo)")
abort()
} catch {
fatalError()
}
return coordinator
}()
**EDIT:**
lazy var applicationDocumentsDirectory: URL = {
let urls = Foundation.FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
return urls[urls.count-1]}()
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
self.contentHandler = contentHandler
bestAttemptContent = (request.content.mutableCopy() as?
UNMutableNotificationContent)
if let bestAttemptContent = bestAttemptContent {
// Modify the notification content here...
print("Mutable Data %@",bestAttemptContent)
bestAttemptContent.title = "\(bestAttemptContent.title)"
//bestAttemptContent.title = "Notification"
let apnsDic = bestAttemptContent.userInfo["aps"] as! NSDictionary
// NotificationManager.sharedInstance.handlePushNotification(byUserTapped: true, content: apnsDic)
contentHandler(bestAttemptContent)
} }
// Storing APNS dictionary into database from extension
func handlePushNotification(byUserTapped : Bool,content : NSDictionary) {
let moduelDataDic = content.mutableCopy() as! NSMutableDictionary
let entity2 = NSEntityDescription.entity(forEntityName: "TextMessage",
in: CoreDataStorage.sharedInstance.mainQueueCtxt!)
let textMsg = NSManagedObject(entity: entity2!,
insertInto: CoreDataStorage.sharedInstance.mainQueueCtxt) as? TextMessage
let trimmedMessage = (moduelDataDic.object(forKey: "msgbody")! as AnyObject).trimmingCharacters(in: .whitespacesAndNewlines)
textMsg?.message = trimmedMessage
msgInfo?.toText = textMsg
rosterInfo.time = composeMsgDate as Date
rosterInfo.addToToMessageInfo(NSSet(object: msgInfo!))
DispatchQueue.main.async {
let context = CoreDataStorage.sharedInstance.mainQueueCtxt
if let moc = context {
if moc.hasChanges {
do {
try moc.save()
} catch {
let nserror = error as NSError
print("Could not save In NotficationManager \(nserror), \(nserror.userInfo)")
}
}
}
} }
In application background mode here I am fetching data which are stored in above method of NotificationServiceExtension and in my result i can get data from manageObject table (messageInfo) but no any data into relationship "let setArray = rosterInfo?.toMessageInfo"
let resultPredicate = NSPredicate(format: "messageID == %@",
moduelDataDic.object(forKey: "message_id")! as! CVarArg)
let messageInfoAry =
self.fetchMessagesFromCoreDataWithPredicate(resultPredicate:
resultPredicate, sortDescriptorKey: "time", isAscending: true,
fetchLimit: false, managedContext: self.getManageObjectContext())
if messageInfoAry.count > 0 {
let rosterInfo = (messageInfoAry[0] as! MessageInfo).toRoster
let msgInfo = messageInfoAry[0] as! MessageInfo
// Here i don't see msgInfo in this relationship but after relaunching my application i can able to see that same object
let setArray = rosterInfo?.toMessageInfo
Any help from anyone?
Try adding the following code to your AppDelegate
class and test it.
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
completionHandler(.newData)
performSelector(inBackground: #selector(saveNewNotificationInBackground(userInfo:)), with: userInfo)
}
@objc func saveNewNotificationInBackground(userInfo: [AnyHashable: Any]) -> Void {
//save notification using core data
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With