iOS Push Notification의 경우 일반적으로 Firebase의 FCM 푸시 구성을 많이 하게 된다.
이때 Push Server로 구성한 서버에서 푸시를 전송할때 apn 항목 안아래와 같이 mutable-content 값을 1로 전송하게 되면 푸시를 재 편집 할수 있게 구성이 가능하다.
"aps": {
"mutable-content":1,
...
},
해당 글에서 코드 부분은 파란색으로 표기 됩니다.
해당 글에서 중요 부분은 붉은색으로 표기 됩니다.
1. UNNotificationServiceExtension 이란?
위의 주소를 통해 확인해 보면 원격 통지가 사용자에게 전달되기 전에 원격 통지의 내용을 수정하는 객체라고 말하고 있습니다.
1-1. Notification Service Extension과 Notification Content Extension의 차이는 무엇일까요?
Notification Service Extension의 경우는 위에서 확인해 본 것과 같이 원격 Push를 단말기에 표시하기 전에 재 편집을 하기 위한 용도로 사용되며, Notification Content Extension의 경우는 전달 받은 Push 를 3D Touch를 이용하여 펼쳐보기 시에 보여지는 화면을 수정하는 용도로 사용됩니다.
2. Notification Service Extension을 사용하는 이유는 무엇인가요?
Notification Service Extension을 사용하지 않을 경우 iOS 단말기에서는 이미지를 푸시에 등록할 수 가 없는 문제가 있습니다.
이미지 푸시를 전송하기 위해 일반적으로 이 확장 모듈을 사용합니다.
3. Notification Service Extension 프로젝트에 추가하기
3-1. Xcode -> File -> New -> Target.. 메뉴를 클릭 합니다.
3-2. Target을 클릭하여 출력되는 화면에서 Notification Service Extension을 선택 후 Next를 클릭 합니다.
3-3. 이후 추가될 Target(Notification Service Extension)의 Project Name을 지정 후 Finish를 클릭하여 Notification Service Extension 모듈이 추가된것을 확인 할 수 있습니다.
4. iOS Push로 전달 할 수 있는 데이터 사이즈 제한이 있기 때문에 이미지의 경우 URL로 전달하게 됩니다. Notification Service Extension 모듈에서는 URL 이미지를 가져올 수 있도록 처리해 주어야 합니다.
기본으로 생성되어 표시되는 부분은 파란색으로 표시하며, 추가한 부분을 붉은색으로 표시하였습니다.
[NotificationService.swift 파일 안]
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)
if let bestAttemptContent = bestAttemptContent {
// * 푸시를 실질적으로 변경하는 부분
bestAttemptContent.title = "\(bestAttemptContent.title) [modified]"
// * 이미지를 가져와서 push에 추가하는 부분
// - userInfo["image"]에서 이미지 URL 정보를 가져옵니다. (전송된 푸시 내용은 "5." 에서 확인하세요)
if let imageURLString = bestAttemptContent.userInfo["image"] as? String {
if let imagePath = self.image(imageURLString) {
let imageURL = URL(fileURLWithPath: imagePath)
do {
let attach = try UNNotificationAttachment(identifier: "image-test", url: imageURL, options: nil)
bestAttemptContent.attachments = [attach]
} catch {
print(error)
}
}
}
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)
}
}
// * 이미지를 가져오는 함수 추가 구성
func image(_ URLString: String) -> String? {
let componet = URLString.components(separatedBy: "/")
if let fileName = componet.last {
let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
if let documentsPath = paths.first {
let filePath = documentsPath.appending("/" + fileName)
if let imageURL = URL(string: URLString) {
do {
let data = try NSData(contentsOf: imageURL, options: NSData.ReadingOptions(rawValue: 0))
if data.write(toFile: filePath, atomically: true) {
return filePath
}
} catch {
print(error)
}
}
}
}
return nil
}
}
5. 서버쪽에서 PUSH 전송 시 데이터 구조는 아래와 같습니다.
{
"aps": {
"alert": {
"body": "test message",
"title": "test title",
},
"mutable-content": 1,
},
"image": "<image URL 주소>",
}
5-1. 만약 mutable-content 값이 1이나 true가 아닐 경우 Notification Service Extension에서 푸시 재 편집 권한을 가져오지 못하여, 이미지 푸시를 출력할 수 없습니다.
'개발' 카테고리의 다른 글
Cocoapods Library 등록 방법 순서대로! (0) | 2020.10.30 |
---|---|
iOS 인앱결제 개발시 샌드박스 결제 시 iTunes Store에 연결할 수 없음 오류 문제! (0) | 2020.10.21 |
iOS Silent Push Notification - 보이지 않는 푸시 구성하기 (0) | 2020.10.20 |
Swift iOS guard let vs let (0) | 2020.09.30 |
SwiftUI 알아보기 :) Image (0) | 2020.09.28 |