Как реализовать расширенные уведомления в ios 10 с Firebase

Я давно искал решение для этого. Но я не могу ничего найти. Я реализовал Push-уведомления для iOS, используя FCM. Но я не знаю, поддерживает ли FCM уведомления с iOS 10. Если это произойдет, я не нашел код для его реализации. Заранее спасибо.

4 ответа

Решение

У меня тот же вопрос, почему не работает богатое уведомление.. и проблема с FCM mutable-content полезная нагрузка.. это превращается в gcm.notification.mutable-content при получении полезной нагрузки, и поэтому существует проблема, которая еще не решена.

Для получения дополнительной информации вы можете проверить эту проблему с GitHub.

Это решено сейчас.. Вы можете проверить эту ссылку, а также проверить этот ответ AL.

Просто обновление в связи с ответом @ElCaptainv2.0.

mutable_content был добавлен для FCM:

В настоящее время только для устройств iOS 10+. В iOS используйте это поле для представления изменяемого содержимого в полезной нагрузке APNS. Когда уведомление отправлено, и для него установлено значение true, содержимое уведомления можно изменить до его отображения, используя расширение приложения Notification Service. Этот параметр будет игнорироваться для Android и Интернета.

Примечание: значение параметра должно быть boolean не Integer,

Это было также упомянуто в ветке GitHub всего несколько часов назад kroikie.

Я работал над этим часами, часами, часами и часами. Все мои уведомления работали нормально, кроме rich notificationизображение никогда не будет отображаться . Вот ответ на простом английском:

Измените это:

"mutable-content": 1 // неправильный

К этому:

"mutable_content": true // правильный

Вот исходящая полезная нагрузка:

      "aps": {
    "alert": {
        "title": "Hello",
        "body": "What do you think of this image?"
    },
    "mutable_content": true
},
"media-url": "https://firebasestorage.googleapis.com/....." 

У меня сработало следующее (февраль 2023 г.)

Шаг 1. Добавьте расширение службы уведомлений

Шаг 2 — Добавьте цель в подфайл

Шаг 3. Используйте помощник по расширениям

Преобразовано в Swift:

      //
//  NotificationService.swift
//  RichNotification
//

import UserNotifications

class NotificationService: UNNotificationServiceExtension {
    var contentHandler: ((UNNotificationContent) -> Void)?
    var bestAttemptContent: UNMutableNotificationContent?
    
    override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
        self.contentHandler = contentHandler
        bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
        
        guard let bestAttemptContent = bestAttemptContent,
              let attachmentURLAsString = bestAttemptContent.userInfo["image"] as? String,
              let attachmentURL = URL(string: attachmentURLAsString) else {
            return
        }
        
        downloadImageFrom(url: attachmentURL) { (attachment) in
            if let attachment = attachment {
                bestAttemptContent.attachments = [attachment]
                contentHandler(bestAttemptContent)
            }
        }
    }

    override func serviceExtensionTimeWillExpire() {
        // Called just before the extension will be terminated by the system.
        // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
        if let contentHandler = contentHandler, let bestAttemptContent =  bestAttemptContent {
            contentHandler(bestAttemptContent)
        }
    }
    
    private func downloadImageFrom(url: URL, with completionHandler: @escaping (UNNotificationAttachment?) -> Void) {
        let task = URLSession.shared.downloadTask(with: url) { (downloadedUrl, response, error) in
            // 1. Test URL and escape if URL not OK
            guard let downloadedUrl = downloadedUrl else {
                completionHandler (nil)
                return
            }
            // 2. Get current's user temporary directory path
            var urlPath = URL(fileURLWithPath: NSTemporaryDirectory ())
            // 3. Add proper ending to url path, in the case jpg (The system validates the content of attached files before scheduling the corresponding notification request. If an attached file is corrupted,
            let uniqueURLEnding = ProcessInfo.processInfo.globallyUniqueString + ".jpg"
            urlPath = urlPath.appendingPathComponent (uniqueURLEnding)
            // 4. Move downloadedUrl to newly created urlPath
            try? FileManager.default.moveItem(at: downloadedUrl, to: urlPath)
            // 5. Try adding getting the attachment and pass it to the completion handler
            do {
                let attachment = try UNNotificationAttachment (identifier: "picture", url: urlPath, options: nil)
                completionHandler(attachment)
            }
            catch {
                completionHandler(nil)
            }
        }
        task.resume()
    }
}

extension UNNotificationRequest {
    var attachment: UNNotificationAttachment? {
        guard let attachmentURL = content.userInfo["image"] as? String, let imageData = try? Data(contentsOf: URL(string: attachmentURL)!) else {
            return nil
        }
        return try? UNNotificationAttachment(data: imageData, options: nil)
    }
}

extension UNNotificationAttachment {
    convenience init(data: Data, options: [NSObject: AnyObject]?) throws {
        let fileManager = FileManager.default
        let temporaryFolderName = ProcessInfo.processInfo.globallyUniqueString
        let temporaryFolderURL = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(temporaryFolderName, isDirectory: true)

        try fileManager.createDirectory(at: temporaryFolderURL, withIntermediateDirectories: true, attributes: nil)
        let imageFileIdentifier = UUID().uuidString + ".jpg"
        let fileURL = temporaryFolderURL.appendingPathComponent(imageFileIdentifier)
        try data.write(to: fileURL)
        try self.init(identifier: imageFileIdentifier, url: fileURL, options: options)
    }
}

cURL для отправки push-уведомления через Firebase/FCM

      curl --location --request POST 'https://fcm.googleapis.com/fcm/send' \
--header 'Authorization: key=<YOUR FCM KEY>' \
--header 'Content-Type: application/json' \
--data-raw '{
    "to": "fcm token for device or channel id",
    "content_available": true,
    "mutable_content": true,
    "notification": {
        "title": "Notification With Image",
        "mutable-content": true,
        "body": "Test Message "
    }, 
    "data": {
        "image": "https://upload.wikimedia.org/wikipedia/commons/1/16/HDRI_Sample_Scene_Balls_%28JPEG-HDR%29.jpg"
    }
}'
Другие вопросы по тегам