簡體   English   中英

帶有圖像的推送通知-iOS-Swift

[英]Push Notification with Image - iOS - Swift

嗨,我只想顯示帶圖像的推送通知。 我用下面的代碼,我不確定我在哪里做錯了我三個多星期,我經歷了很多鏈接,但仍然無法解決。 以下是我的應用程序委托代碼

AppDelegate.Swift

import UIKit
import UserNotifications

var deviceTokenString:String = ""
var badgeCount = 0

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {

var window: UIWindow?


func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

    // Push Notification

    if #available(iOS 10.0, *)
    {
        let center = UNUserNotificationCenter.current()
        center.requestAuthorization(options: [.alert, .badge, .sound]) { (granted, error) in

            // actions based on whether notifications were authorised or not

            guard error == nil else {

                //Display Error.. Handle Error.. etc..

                return
            }

            if granted
            {

                //Do stuff here..

            }

            else {

                //Handle user denying permissions..

            }

        }

        application.registerForRemoteNotifications()
    } else {
        // Fallback on earlier versions
    }




    registerForRemoteNotification()


    // iOS 10 support
    if #available(iOS 10, *) {
        UNUserNotificationCenter.current().requestAuthorization(options:[.alert, .sound]){ (granted, error) in }
        application.registerForRemoteNotifications()
    }
        // iOS 9 support
    else if #available(iOS 9, *) {
        UIApplication.shared.registerUserNotificationSettings(UIUserNotificationSettings(types: [.sound, .alert], categories: nil))
        UIApplication.shared.registerForRemoteNotifications()
    }
        // iOS 8 support
    else if #available(iOS 8, *) {
        UIApplication.shared.registerUserNotificationSettings(UIUserNotificationSettings(types: [.sound, .alert], categories: nil))
        UIApplication.shared.registerForRemoteNotifications()
    }
        // iOS 7 support
    else {
        application.registerForRemoteNotifications(matching: [.sound, .alert])
    }

    return true
}

func registerForRemoteNotification() {
    if #available(iOS 10.0, *) {
        let center  = UNUserNotificationCenter.current()
        center.delegate = self
        center.requestAuthorization(options: [.sound, .alert]) { (granted, error) in
            if error == nil{
                UIApplication.shared.registerForRemoteNotifications()

             //   UIApplication.shared.applicationIconBadgeNumber = 5
            }
        }
    }
    else {
        UIApplication.shared.registerUserNotificationSettings(UIUserNotificationSettings(types: [.sound, .alert], categories: nil))
        UIApplication.shared.registerForRemoteNotifications()

      //  UIApplication.shared.applicationIconBadgeNumber = 5
    }
}

func incrementBadgeNumberBy(badgeNumberIncrement: Int)
{
    let currentBadgeNumber = UIApplication.shared.applicationIconBadgeNumber
    let updatedBadgeNumber = currentBadgeNumber + badgeNumberIncrement
    if (updatedBadgeNumber > 0)
    {
        UIApplication.shared.applicationIconBadgeNumber = updatedBadgeNumber
    }
    else
    {
        UIApplication.shared.applicationIconBadgeNumber = 0
    }
}

func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
    print("Couldn't register: \(error)")
}

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {

    deviceTokenString = deviceToken.hexString()

    //  deviceTokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)})
    print("device token: \(deviceTokenString)")


}

// Push notification received
func application(_ application: UIApplication, didReceiveRemoteNotification data: [AnyHashable : Any]) {
    // Print notification payload data

    badgeCount = badgeCount + 1
    self.incrementBadgeNumberBy(badgeNumberIncrement: badgeCount)

    print("Push notification received: \(data)")

}

//  Notification will present call back
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
    completionHandler([.alert, .sound, .badge])


    print("UserInfo: \(notification.request.content.userInfo)")

    var userinfo = NSDictionary()
    userinfo = notification.request.content.userInfo as NSDictionary

    let imgData = userinfo.value(forKey: "data")! as! NSDictionary

    let url = imgData.value(forKey: "attachment-url")

    let imgUrl = URL(string: url as! String)!

    //  1. Create Notification Content
    let content = UNMutableNotificationContent()


    //  2. Create Notification Attachment

    URLSession.shared.downloadTask(with: imgUrl)
    {(location, response, error) in

        print("location: \(location!)")

        if error == nil
        {
            if let location = location
            {
                // Move temporary file to remove .tmp extension

                let tmpDirectory = NSTemporaryDirectory()

                let tmpFile = "file://".appending(tmpDirectory).appending(imgUrl.lastPathComponent)

                print("tmpFile: \(tmpFile)")

                let tmpUrl = URL(string: tmpFile)!

                print("tmpUrl: \(tmpUrl)")

                try! FileManager.default.moveItem(at: location, to: tmpUrl)

                // Add the attachment to the notification content

                if let attachment = try? UNNotificationAttachment(identifier: "attachment", url: tmpUrl) {

                    content.attachments = [attachment]

                    print("attachment: \(content.attachments)")

                    //  3. Create Notification Request

                    let request = UNNotificationRequest.init(identifier: String.UNNotificationRequest.NormalLocalPush.rawValue,

                                                             content: content, trigger: nil)

                    content.title = "\(userinfo.value(forKeyPath: "aps.alert.title")!)"
                    content.body = "\(userinfo.value(forKeyPath: "aps.alert.body")!)"
                    content.sound = UNNotificationSound.default()
                    content.badge = (UIApplication.shared.applicationIconBadgeNumber + 1) as NSNumber;
                    content.categoryIdentifier = String.UNNotificationCategory.Normal.rawValue

                    //  4. Add to NotificationCenter

                    let center = UNUserNotificationCenter.current()

                    center.add(request)
                }
            }
        }
        else
        {
            print("Error: \(error!)")
        }
        }.resume()
}

@available(iOS 10.0, *)
//  Notification interaction response call back
func userNotificationCenter(_ center: UNUserNotificationCenter,
                            didReceive response: UNNotificationResponse,
                            withCompletionHandler completionHandler: @escaping () -> Void) {

    print("\(response.notification.request.content.userInfo)")

    var userinfo = NSDictionary()
    userinfo = response.notification.request.content.userInfo as NSDictionary

    let imgData = userinfo.value(forKey: "data")! as! NSDictionary

    let url = imgData.value(forKey: "attachment-url")

    let imgUrl = URL(string: url as! String)!

    //  1. Create Notification Content
    let content = UNMutableNotificationContent()
    content.title = "\(userinfo.value(forKeyPath: "aps.alert.title")!)"
    content.body = "\(userinfo.value(forKeyPath: "aps.alert.body")!)"
    content.sound = UNNotificationSound.default()
    content.badge = (UIApplication.shared.applicationIconBadgeNumber + 1) as NSNumber;
    content.categoryIdentifier = String.UNNotificationCategory.Normal.rawValue   //  設置通知類型標示

    //  2. Create Notification Attachment

    URLSession.shared.downloadTask(with: imgUrl) { (location, response, error) in

        if let location = location {

            // Move temporary file to remove .tmp extension

            let tmpDirectory = NSTemporaryDirectory()

            let tmpFile = "file://".appending(tmpDirectory).appending(imgUrl.lastPathComponent)

            let tmpUrl = URL(string: tmpFile)!

            try! FileManager.default.moveItem(at: location, to: tmpUrl)



            // Add the attachment to the notification content

            if let attachment = try? UNNotificationAttachment(identifier: "", url: tmpUrl) {

                content.attachments = [attachment]
            }
        }

        // Serve the notification content

        // self.contentHandler!(content)

        }.resume()

    //        if let attachement = try? UNNotificationAttachment(identifier: "attachment", url: imgUrl, options: nil)
    //        {
    //            content.attachments = [attachement]
    //        }

    //  3. Create Notification Request
    let request = UNNotificationRequest.init(identifier: String.UNNotificationRequest.NormalLocalPush.rawValue,
                                             content: content, trigger: nil)

    //  4. Add to NotificationCenter
    let center = UNUserNotificationCenter.current()
    center.add(request)

    let responseNotificationRequestIdentifier = response.notification.request.identifier

    if responseNotificationRequestIdentifier == String.UNNotificationRequest.NormalLocalPush.rawValue ||
        responseNotificationRequestIdentifier == String.UNNotificationRequest.LocalPushWithTrigger.rawValue ||
        responseNotificationRequestIdentifier == String.UNNotificationRequest.LocalPushWithCustomUI1.rawValue ||
        responseNotificationRequestIdentifier == String.UNNotificationRequest.LocalPushWithCustomUI2.rawValue {

        let actionIdentifier = response.actionIdentifier
        switch actionIdentifier {
        case String.UNNotificationAction.Accept.rawValue:

            break
        case String.UNNotificationAction.Reject.rawValue:

            break
        case String.UNNotificationAction.Input.rawValue:

            break
        case UNNotificationDismissActionIdentifier:

            break
        case UNNotificationDefaultActionIdentifier:

            break
        default:
            break
        }
    }
    completionHandler();
}


}

extension Data
{
func hexString() -> String
{
    return self.reduce("") { string, byte in
        string + String(format: "%02X", byte)
    }
}
}

以下是我用於自定義推送通知的擴展代碼,

擴展名

import Foundation

extension String {

enum UNNotificationAction : String {
    case Accept
    case Reject
    case Input
}

enum UNNotificationCategory : String {
    case Normal
    case Cheer
    case CheerText
}

enum UNNotificationRequest : String {
    case NormalLocalPush
    case LocalPushWithTrigger
    case LocalPushWithCustomUI1
    case LocalPushWithCustomUI2
}
}

extension URL {

enum ResourceType : String {
    case Local
    case Local1
    case Remote
    case AttachmentRemote
}

static func resource(type :ResourceType) -> URL
{
    switch type {
    case .Local:
        return Bundle.main.url(forResource: "cheer", withExtension: "png")!
    case .Local1:
        return Bundle.main.url(forResource: "hahaha", withExtension: "gif")!
    case .Remote:
        return URL(string: "http://ww1.sinaimg.cn/large/65312d9agw1f59leskkcij20cs0csmym.jpg")!
    case .AttachmentRemote:
        return URL(string: "https://assets-cdn.github.com/images/modules/open_graph/github-mark.png")!
    }
    }
}

extension URLSession {

class func downloadImage(atURL url: URL, withCompletionHandler completionHandler: @escaping (Data?, NSError?) -> Void) {
    let dataTask = URLSession.shared.dataTask(with: url) { (data: Data?, response: URLResponse?, error: Error?) in
        completionHandler(data, error as NSError?)
    }
    dataTask.resume()
}
}

我的Api回應是

[AnyHashable("aps"):
 {
alert =     {
    body = test;
    title = "N-Gal";
};
"mutable-content" = 1;
sound = default;
}, 
AnyHashable("data"): 
{
"attachment-url" = "https://www.n-gal.com/image/cache/catalog/HomeBanner/Banners/1172X450-N-Gal-Footwear-Banner-100x100.jpg";
}]

該代碼基於https://github.com/maquannene/UserNotifications教程。 請給我一個解決此問題的解決方案...預先感謝...!

從您的代碼片段中,我得出結論,您正在談論遠程通知。 這是一個重要的區別。 如果要“豐富”遠程通知(例如添加圖像),則需要UNNotificationServiceExtension

對於本地通知,該應用在創建其余通知內容時會添加附件。 要將附件添加到遠程通知中,請使用通知服務擴展在通知內容發送之前對其進行修改 有關實現通知服務擴展的更多信息,請參見UNNotificationServiceExtension

資料來源: Apple文檔 (強調我的)

該擴展程序位於您的應用程序外部,並在用戶看到遠程通知之前被調用。 這樣,您就有機會在計划發送通知之前加載所有遠程資源。 有關擴展的生命周期以及它們如何與主機應用通信的更多信息,請參閱“ 應用擴展編程指南”

要在Xcode中添加擴展名,請轉到File > New > Target然后選擇Notification Service擴展名

新目標面板

這將創建新的擴展目標並將其嵌入主機目標中:

新的擴展目標

NotificationService.swift文件中,您將找到可以自定義通知內容的入口點。

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)

        if let bestAttemptContent = bestAttemptContent {
            // Modify the notification content here...
            bestAttemptContent.title = "\(bestAttemptContent.title) [modified]"

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

}

請確保查看UNNotificationServiceExtension類概述以獲取更多詳細信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM