[英]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.