UNNotificationContentExtension で 画像をダウンロードしたり、AppGroupでアプリ本体と情報共有したり
httpで通信してて工数殺したので自戒の念を込めて書いてたんですが、
Extensionで画像をダウンロードしてーってQiita無いなって思ったのでそれも含めて書いてます。
なお、今更HTTPを使うなというのがAppleの意向なのでそれに従う必要があります。1
あと、AppGroupsをこのExtensionで使ったってQiitaもないのでTIPSにいれておきました。
httpsを使わないと
UNErrorDomain
が Throw されます。
前提
- 既に
UNNotificationContentExtension
を使ったものが実装されてる
実装
- 画像ファイルは存在している.サーバー側に問題は無い。
- Extensionじゃない本体では、
App Transport Security Settings
を設定している
- 本体側ではhttp通信をしている箇所がある
-
import UserNotifications
import UIKit
だけ使いたい。
- 画像(png/jpg)をダウンロードするコードは以下
myNotificationExtension.swift
import UserNotifications
import UIKit
class NotificationService: UNNotificationServiceExtension {
var contentHandler: ((UNNotificationContent) -> Void)?
var bestAttemptContent = UNMutableNotificationContent.init()
// ...
// 割愛
// ...
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
self.contentHandler = contentHandler
bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)!
let host = "https://abcdefg-hogetarou.tv" // httpだと出来ない!!!
let image = "/terebibangumi.png"
let fileManager = FileManager.default
let tmpSubFolderName = ProcessInfo.processInfo.globallyUniqueString
let tmpSubFolderURL = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(tmpSubFolderName, isDirectory: true)
let session = URLSession(configuration: URLSessionConfiguration.default)
let task = session.dataTask(with: URL(string: host + image)!, completionHandler: { (data, response, error) in
do {
self.bestAttemptContent.title = "\(self.bestAttemptContent.title)"
try fileManager.createDirectory(at: tmpSubFolderURL, withIntermediateDirectories: true, attributes: nil)
let imageFileIdentifier = "banbumi.png"
let fileURL = tmpSubFolderURL.appendingPathComponent(imageFileIdentifier)
try data?.write(to: fileURL)
let imageAttachment = try UNNotificationAttachment.init(identifier: imageFileIdentifier, url: fileURL, options: nil)
self.bestAttemptContent.attachments = [imageAttachment]
} catch let e {
self.bestAttemptContent.body = "\(String.init(describing: e))"
}
contentHandler(self.bestAttemptContent)
})
task.resume()
// ....
// 割愛
// ....
UNNotificationContentExtension
を使ったものが実装されてる- 画像ファイルは存在している.サーバー側に問題は無い。
- Extensionじゃない本体では、
App Transport Security Settings
を設定している- 本体側ではhttp通信をしている箇所がある
-
import UserNotifications
import UIKit
だけ使いたい。 - 画像(png/jpg)をダウンロードするコードは以下
myNotificationExtension.swift
import UserNotifications
import UIKit
class NotificationService: UNNotificationServiceExtension {
var contentHandler: ((UNNotificationContent) -> Void)?
var bestAttemptContent = UNMutableNotificationContent.init()
// ...
// 割愛
// ...
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
self.contentHandler = contentHandler
bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)!
let host = "https://abcdefg-hogetarou.tv" // httpだと出来ない!!!
let image = "/terebibangumi.png"
let fileManager = FileManager.default
let tmpSubFolderName = ProcessInfo.processInfo.globallyUniqueString
let tmpSubFolderURL = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(tmpSubFolderName, isDirectory: true)
let session = URLSession(configuration: URLSessionConfiguration.default)
let task = session.dataTask(with: URL(string: host + image)!, completionHandler: { (data, response, error) in
do {
self.bestAttemptContent.title = "\(self.bestAttemptContent.title)"
try fileManager.createDirectory(at: tmpSubFolderURL, withIntermediateDirectories: true, attributes: nil)
let imageFileIdentifier = "banbumi.png"
let fileURL = tmpSubFolderURL.appendingPathComponent(imageFileIdentifier)
try data?.write(to: fileURL)
let imageAttachment = try UNNotificationAttachment.init(identifier: imageFileIdentifier, url: fileURL, options: nil)
self.bestAttemptContent.attachments = [imageAttachment]
} catch let e {
self.bestAttemptContent.body = "\(String.init(describing: e))"
}
contentHandler(self.bestAttemptContent)
})
task.resume()
// ....
// 割愛
// ....
☝️ 色んな者を do
で囲むのは Exception
投げられたときに追いづらくなる可能性があるので、上記のようにせずきちんと分けることをオススメします。
TIPS
- エラーの時にタイトルを変えられるが、ユーザーにエラーがおこってるな?と思われてはいけない(と思うので)タイトルの最後に
.
とか ,
とか付けてデバッグデバッグ出来るようにしてる。
- 上記では、 eをそのままbodyにいれている。これは開発用なので参考にする人がいれば注意.
- 画像がhttp通信が原因で、Exceptionが投げられると
UNErrorDomain
で Invalid attachment file URL
みたいなのが届く。HTTPSを使えば解消できる。
アプリ本体と情報共有
.
とか ,
とか付けてデバッグデバッグ出来るようにしてる。
- 上記では、 eをそのままbodyにいれている。これは開発用なので参考にする人がいれば注意.
UNErrorDomain
で Invalid attachment file URL
みたいなのが届く。HTTPSを使えば解消できる。AppGroupsを使えば、アプリ本体から情報をもらうことができる。
1. Developer Center で App Groups を定義
2. Xcodeで機能を有効にして、AppGroupを追加する
3. 実装する
取得する方法:
myNotificationExtension.swift
let groupName = "group.terebi.dayo"
if let userDefaults = UserDefaults(suiteName: groupName) {
let key = "video_killed_the radio_star"
userDefaults.synchronize() //念のため
let savedCount = userDefaults.integer(forKey: key) // 取れる yay
// 割愛
設定する方法:
Interactor.swift
let groupName = "group.terebi.dayo"
if let userDefaults = UserDefaults(suiteName: groupName) {
let key = "video_killed_the radio_star"
userDefaults.set(0, forKey: key) // 設定できる yay
userDefaults.synchronize() //念のため
}
最後に
3ヶ月前にも同じ事をやってこの現象の原因は知っていたが、今回も1日掛かってしまった。
ちなみに前回は3日間かかった。
自戒の念を込めてTIPSを残す。
-
ATS使えば通信できるかも??かも??でも明日には使え無くなる可能性有るかも?? ↩
Author And Source
この問題について(UNNotificationContentExtension で 画像をダウンロードしたり、AppGroupでアプリ本体と情報共有したり), 我々は、より多くの情報をここで見つけました https://qiita.com/YKEI_mrn/items/ad3b52e8614cbf37486f著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .