생각보다 매우 까다로웠다. 삽질을 아주아주 많이 거쳐 구현을 해냈다.
덕분에 Target Extension도 처음 사용해보고 아주 흥미로운 작업이었다.
우선 FCM 푸시알림은 구현이 되었다는 가정 하에, 이미지 url을 받아와 적용하는 법을 알아보자.
(기본적인 FCM 푸시알림은 다음을 참고 -> FCM 푸시 설정)
1. Notification Service Extension 추가
프로젝트 - TARGETS 하단의 + 버튼을 눌러주면 다음과 같이 새로운 타겟을 추가해줄 수 있다.
custom으로 푸시 알림을 설정할 수 있도록 Notification Service Extension을 추가해준다.
Product Name : ServiceExtension으로 설정해주고 finish 해주면, ServiceExtension 타겟과 폴더가 생성이 된다.
2. Signing & Capabilities
ServiceExtension 타겟과 함께 생성된 BundleID 로 새로운 프로비저닝 파일도 만들어 적용해 줘야한다.
그런 다음, + Capability 에서 Push Notifications를 추가해준다.
* 주의사항 : ServiceExtension Target - General - Deployment Info 의 iOS 버전을 프로젝트 파일과 동일하게 설정해주는 걸 잊지 않도록! 기본으로 설정되어있던 iOS 14.5로 테스트 하고 잘 되다가 갑자기 다른 기기로 테스트 했는데 안되서 아주 의뭉스러웠다. ㅋㅋㅋㅋ 지원버전문제였으..
3. NotificationService.swift 파일 수정
ServiceExtension 폴더안에 자동으로 NotificationService 파일이 생성된 것을 확인할 수 있다.
검색해보면 푸시 이미지를 받아오는 다양한 방법들이 있지만 나는 다음 영상을 참고하여 코드를 작성해주었다.
참고 : Youtube - Manipulating push notifications with service extension
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 {
let imageData = request.content.userInfo["fcm_options"] as? [String : Any]
guard let attachmentString = imageData?["image"] as? String else {
contentHandler(bestAttemptContent)
return
}
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()
}
}
}
override func serviceExtensionTimeWillExpire() {
if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent {
contentHandler(bestAttemptContent)
}
}
}
4. 이미지 푸시 테스트
Firebase 클라우드 메시징에서 다음과 같이 테스트 알림을 보낼 수 있다.
FCM 토큰 입력 후 테스트 메시지를 전송하면 아래와 같이 이미지가 잘 뜨는 것을 볼 수 있다. 오른쪽은 꾹 눌러 푸시 메시지 펼쳤을 때.
전송한 push 메시지의 데이터는 userInfo를 통해서 다음과 같은 구조로 받아올 수 있다.
[ ...
"fcm_options": {
image = "<imageURL>";
}, "aps": {
alert= {
body = (메시지);
title = (타이틀);
};
"mutable-content" = 1;
}
... ]
서버에서도 위의 형식으로 데이터를 받아오면 된다.
타이틀, 메시지와 함께 이미지를 보내면 위와 같이 받아올 수도 있고, 이미지 url을 따로 빼서 받아올 수도 있다.
하나 주의할 점은 "mutable-content" = 1 을 함께 받아와야 Notification Service Extension에서 푸시 재편집 권한을 가져와 이미지 푸시를 출력할 수 있다고 한다.
6. Notification Service Extension 디버깅 하는 법
문제가 발생했다. 정말 이상하게도 실행은 잘 되는데 콘솔에 로그는 하나도 안찍히는 것이었다!! 분명히 Extension 코드가 실행은 되고 있는 것 같은데 로그가 찍히지 않으니 문제가 발생해도 디버깅을 할 수가 없다능.... Extension을 처음 사용해보는거라 몰랐는데 찾아보니
확장 프로그램은 앱 외부에서 실행되기 때문에 기존 앱을 실행했을 때는 디버깅을 할 수 없다고 한다.
그렇다면 notification extension은 어떻게 디버그를 할 수 있는걸까!
1. Debug > Attach to Process > ServiceExtension 선택 (해보고 안되면 다음방법으로)
2. Product > Scheme > ServiceExtension 선택
3. Product > Scheme > New Scheme > ServiceExtension 추가
참고 : How to Debug Notification Extensions
+ 이미지 링크를 http://로 받아오면 다음과 같은 에러가 날 수 있다.
App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Use HTTPS instead or add Exception Domains to your app's Info.plist.
그럴경우 Info.plist에서 Allow Arbitary Loads를 추가해 YES로 값을 설정해주어 HTTP 접근을 허용해줄 수 있다.
어디서 Extension에 Firebase/Messeging을 추가로 pod 설치 해줘야 한다는 말도 봤는데 나는 안해도 작동 잘 되더라. 필요 없을듯?!
그래도 궁금해서 찾아본 muliple targets with CocoaPods 설치 및 사용법
혹시나 제 글이 도움이 되셨다면 하트 한번 눌러주시면 감사하겠습니다 🥰
iOS 개발자분들 모두 화이팅입니다👍🏻
'초보 iOS 개발자의 일상 > 개발 업무' 카테고리의 다른 글
[Swift iOS] MTMapView 다음 카카오맵 지도 사용해보기 (0) | 2021.07.30 |
---|---|
[Swift iOS] 푸시 메시지 클릭시 url로 WebView 이동시키기 (0) | 2021.07.28 |
[Swift iOS] Localization in Storyboard (0) | 2021.07.20 |
mobile ffmpeg 4.3 버전 업 후 발생하는 문제들 (0) | 2021.07.20 |
[Swift iOS] Add instructions guide to iOS app (0) | 2021.07.01 |