Push 메세지에 이미지 표시하는 기능을 원해서 만들어 봤다.

 

1. Menu  :Xcode > New > Target

   - Notification Service Extension 선택

 

[Push Message 전문]

"extra" 는 테스트용으로 추가한 데이터로 상황에 맞게 JSON 형태로 변경해서 사용하면 됨.

/* 시뮬레이터 테스트용 test.apns 파일
  test.apns 파일을 생성해서 시뮬레이터에 드레그 하면 알림이 발생
*/
{
  "aps": {
    "alert": {
      "title": "Push 테스트",
      "subtitle" : "Notification subtitle",
      "body": "🥳 Woohoo! Push notification in simulator! 🎉",
      "sound": "default"
    },
    "badge": 1
    
  },
  "extra" : {
     "img_url" : "https://t1.daumcdn.net/cfile/tistory/994BEF355CD0313D05",
  },
  "Simulator Target Bundle": "내 앱 번들아이디 넣는곳"
}

2. KNotificationServiceExtension 폴더 생성됨.

    - NotificationService Swift 코드에 기능 추가하면됨.

import UserNotifications
import MobileCoreServices

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 {
        
			// Push Message 전문에 포함됨 extra 데이터 추출
            // 이미지 URL을 받아서 푸쉬 메세지에 표시
            guard let extraString = request.content.userInfo["extra"] as? String else {
                return
            }
            
            print("extra 2 : \(extraString)")
            guard let extraData = extraString.data(using: .utf8) else {
                return
            }
            
            do {
                let extraDic = try JSONSerialization.jsonObject(with: extraData, options: []) as? Dictionary<String,Any> ?? [:]
                
                guard let imgUrl = extraDic["img_url"] as? String else {
                    contentHandler(bestAttemptContent)
                    return
                }
                
                let attachmentString = imgUrl.replacingOccurrences(of: "\\", with: "")
                if let attachmentUrl = URL(string: attachmentString) {
                    let session = URLSession(configuration: URLSessionConfiguration.default)
                    let downloadTask = session.downloadTask(with: attachmentUrl, completionHandler: { (url, _, error) in
                        if let error = error {
                            print("Error downloading attachment: \(error.localizedDescription)")
                        } else if let url = url {
                            let attachment = try! UNNotificationAttachment(identifier: attachmentString, url: url, options: [UNNotificationAttachmentOptionsTypeHintKey : kUTTypePNG])
                            bestAttemptContent.attachments = [attachment]
                        }
                        contentHandler(bestAttemptContent)
                    })
                    downloadTask.resume()
                }
                
            } catch {
                print("NotificationService Json Error : \(error.localizedDescription)")
                
            }
        }
    }

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

}

+ Recent posts