У меня проблемы с RealmSwift
с Notification Service Extension
. Я надеюсь, что каждый может помочь мне или дать мне совет. Я искренне благодарю вас всех! И мой английский не очень хороший, дайте мне знать, если что-то неясно.
Сначала я использовал FCM для отправки сообщения на мое устройство ios
, мне нужно сохранить свое push-уведомление на устройстве ios
(используя Realm
).
Есть только два случая, которые могут успешно сохранить.
1.app работает
2.app убит / фон, и нажмите, чтобы отправить уведомления баннера. Я надеюсь, что я могу отключить приложение / фон и сохранить его, не нажимая на уведомление баннера.
Итак, я использовал следующий метод
1.Добавить Notification Service Extension
в проект
2. Включение фоновой выборки / Удаленные уведомления
3.Проект и Notification Service Extension
добавлены в группы приложений
Я знаю, что расширение не может обмениваться данными, поэтому я изменил путь по умолчанию Realm
.
Я добавил следующий код в AppDelegates.swift
и добавил тот же код в NotificationService.swift
.
как это
let sharedDirectory: URL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.myapp")! as URL
let sharedRealmURL = sharedDirectory.appendingPathComponent("db.realm")
Realm.Configuration.defaultConfiguration = Realm.Configuration(fileURL: sharedRealmURL)
После того, как я добавил эти коды, когда приложение убито или фон, push-сообщение может быть успешно сохранено в Realm, но не каждый раз, 10 push-уведомлений сохранят только 5, и самое главное, функциональность, которая могла бы иметь были сохранены в приложении, запущенном или щелкнувшем по баннеру уведомление не удалось.
(Но он сохраняется, потому что если я отменю код, который изменяет путь к Realm по умолчанию, данные, которые не были сохранены, будут отображены снова)
My Realm class
import Foundation
import RealmSwift
class Order: Object {
@objc dynamic var id = UUID().uuidString
@objc dynamic var name = ""
@objc dynamic var amount = ""
@objc dynamic var createDate = Date()
override static func primaryKey() -> String? {
return "id"
}
}
import UIKit
import RealmSwift
class RealmDao: NSObject {
static let shared = RealmDao()
private var realm: Realm!
private override init() {
self.realm = try! Realm()
}
func getRealmObject() -> Realm {
return self.realm
}
}
Часть моего AppDelegate.swift
let realm = try! Realm()
let order: Order = Order()
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
////share Realm
let sharedDirectory: URL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.myapp")! as URL
let sharedRealmURL = sharedDirectory.appendingPathComponent("db.realm")
Realm.Configuration.defaultConfiguration = Realm.Configuration(fileURL: sharedRealmURL)
tainerURL(forSecurityApplicationGroupIdentifier: "group.myapp")
FirebaseApp.configure()
if #available(iOS 10.0, *) {
UNUserNotificationCenter.current().delegate = self
Messaging.messaging().delegate = self // For iOS 10 data message (sent via FCM)
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge], completionHandler: { granted, error in
if granted {
print("ok...")
} else {
print("no...")
}
})
} else {
let settings: UIUserNotificationSettings =
UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
application.registerUserNotificationSettings(settings)
}
application.registerForRemoteNotifications()
return true
}
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
let sharedDirectory: URL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.myapp")! as URL
let sharedRealmURL = sharedDirectory.appendingPathComponent("db.realm")
Realm.Configuration.defaultConfiguration = Realm.Configuration(fileURL: sharedRealmURL)
let userInfo = notification.request.content.userInfo
print("userInfo: \(userInfo)")
guard
let aps = userInfo[AnyHashable("aps")] as? NSDictionary,
let alert = aps["alert"] as? NSDictionary,
let body = alert["body"] as? String,
let title = alert["title"] as? String
else {
// handle any error here
return
}
print("Title: \(title) \nBody:\(body)")
order.name = title
order.amount = body
try! realm.write {
realm.add(order)
}
completionHandler([.badge, .sound, .alert])
}
Все мои NotificationService.swift
import UserNotifications
import Firebase
import UIKit
import RealmSwift
import Realm
class NotificationService: UNNotificationServiceExtension {
let realm = try! Realm()
let order: Order = Order()
var contentHandler: ((UNNotificationContent) -> Void)?
var bestAttemptContent: UNMutableNotificationContent?
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
let sharedDirectory: URL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.myapp")! as URL
let sharedRealmURL = sharedDirectory.appendingPathComponent("db.realm")
Realm.Configuration.defaultConfiguration = Realm.Configuration(fileURL: sharedRealmURL)
self.contentHandler = contentHandler
bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
let message = request.content.userInfo
print("userInfo: \(message)")
guard
let aps = message[AnyHashable("aps")] as? NSDictionary,
let alert = aps["alert"] as? NSDictionary,
let title = alert["body"] as? String,
let body = alert["title"] as? String
else {
// handle any error here
return
}
print("Title: \(title) \nBody:\(body)")
order.name = title
order.amount = body
try! realm.write {
realm.add(order)
}
if let bestAttemptContent = bestAttemptContent {
// Modify the notification content here...
bestAttemptContent.body = "\(bestAttemptContent.body) [fortest]"
contentHandler(bestAttemptContent)
}
}
override func serviceExtensionTimeWillExpire() {
if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent {
contentHandler(bestAttemptContent)
}
}
}
Я думаю, что моя проблема, по-видимому, связана с изменением пути по умолчанию, потому что когда я меняю путь, push-уведомление при выполнении сохраняется, но отображается код, который должен удалить путь изменения! Это то, что я пропустил, что заставляет исходный путь все еще существовать (таким образом, push-уведомление в запущенном приложении будет сохранено в другой таблице данных?)