Я использую push-уведомления для приложения чата iOS.
Я успешно внедрил и получил push-уведомления, а также реализовал фоновую выборку.
Когда я загружаю новую сборку либо для TestFlight, либо через его хранилище, я могу корректно запускать функцию didReceiveRemoteNotification вплоть до завершенияHandler только для нескольких push-уведомлений. (около 10 или около того) в фоновом режиме.
После этого функция не запускается в фоновом режиме. Он либо не синхронизируется, либо перестает работать. Я знаю, что Apple ограничивает приложения в фоновом режиме, но не уверен, что это так, поскольку этот вызов функции в моем случае занимает менее одной секунды для обработки:
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
let state = UIApplication.shared.applicationState
if state == .background {
if saveNotificationData(userInfo: userInfo) {
completionHandler(UIBackgroundFetchResult.newData)
} else {
completionHandler(UIBackgroundFetchResult.noData)
}
} else {
completionHandler(UIBackgroundFetchResult.noData)
}
}
private func saveNotificationData(userInfo: [AnyHashable: Any]) -> Bool {
let context = self.privateContext
var result = false
if let chatRoomId = (userInfo["chatRoomId"] as? String) {
do {
let fetchRequest: NSFetchRequest<Room> = Room.fetchRequest()
fetchRequest.predicate = NSPredicate(format: "chatRoomId == %@", chatRoomId)
let fetchedResults = try context.fetch(fetchRequest)
if fetchedResults.count > 0 {
let message = Message(context: context)
message.messageRoomId = userInfo["chatRoomId"] as? String
message.messageCreatorUserId = userInfo["user_id"] as? String
message.messageText = userInfo["message_text"] as? String
message.messageChatRoom = fetchedResults.first!
do {
try context.save()
result = true
} catch {
print(error)
}
}
} catch {
// error fetching list
print("Could not fetch \(error)")
}
}
return result
}
Я пробовал так много разных способов сделать это, включая использование основного контекста вместо определенного фонового контекста. Помещение функции сохранения в блок context.perform, отправка в основную очередь перед возвратом завершениеHandler.
Но результат всегда один и тот же. Функции запускаются, как ожидается, для первых нескольких уведомлений, а затем перестают работать в фоновом режиме Либо не синхронизировано, либо просто заблокировано. Кажется, что предыдущее выполнение функции продолжается, когда получено следующее нажатие, которое выбрасывает вещи из строя.
Я также реализую didReceive и willPresent, но я полностью удалил их, чтобы увидеть, если это что-то изменило, но это не так. На самом деле застрял здесь и не знаю, что является причиной проблемы.
Интересно, не является ли это несинхронизированным случаем, если при выполнении нового нажатия я могу отменить то, что происходит из предыдущего? Но это может и не быть проблемой.