0

だから現在私はこれをやっています:

override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
    logger = AnalyticsManager.shared
    self.contentHandler = contentHandler
    bestAttemptContent = (request.content.mutableCopy() as! UNMutableNotificationContent)
    if let notificationContent = bestAttemptContent {
        extensionHandler = ServiceExtensionHandler(notificationContent: notificationContent, logger: AnalyticsManager.shared)
        extensionHandler?.handleNotificationRequest { modifiedNotificationContent in
            guard let modifiedNotificationContent = modifiedNotificationContent else {
                contentHandler(notificationContent)
                return
            }
            contentHandler(modifiedNotificationContent)
        }
    } else {
        contentHandler(request.content)
        return
    }
}

イメージのダウンロードが成功したServiceExtensionHandler場合は、変更された通知を返します。ここまでは順調ですね。

しかし、イメージのダウンロードが成功したら、イベントをログに記録したいと思います。問題はcontentHandler、OS が拡張機能を強制終了し、ログを完了する時間がないことです。

アプリ拡張機能がそのタスクを実行した (またはそれを実行するためにバックグラウンド セッションを開始した) 直後に、システムは拡張機能を終了します。

ドキュメント:アプリ拡張機能のライフ サイクル

現時点では機能していますが、追加のネットワーク呼び出しが機能することは保証されていません。

ログが返された場合にのみその completionHandler を返すことができましたが、ログが 60 秒でタイムアウトする可能性があり、それ自体も別の問題です。

誰かがこれに対する解決策を考えましたか?

4

1 に答える 1

0

あなたは正しい軌道に乗っています。

contentHandler最終的には、ロギングのネットワーク コールバックから派生したコールバックから返す必要があります。ちょっとした変更で:

ログのネットワーク呼び出しでは、URLSessionConfiguration stimeoutIntervalForRequestを 5 秒未満に設定します。このようにして、完了するまで長く待つ必要はありません。

これは疑似コードですが、ロギングを行うオブジェクトに対しては次のようにします。

if let imageData = data {
    self?.log("downloadSuccess") {
        completionHandler(imageData, nil)
   }
}

5 秒以内に成功/失敗するか、タイムアウトになる場合は 5 秒以上かかりません。

于 2020-06-11T21:41:23.677 に答える