1

私が達成したいことは次のとおりです。

  1. コンプリケーションは 30 分間隔でバックグラウンドで更新されます
  2. 時計アプリが実行され、独自の更新されたデータを受信するたびに、コンプリケーションが更新されます
  3. コンプリケーションは、iOS アプリが実行され、ユーザーが時計データに影響する設定を変更するたびに更新されます (気象観測の場所や表示単位の変更など)。

項目 1. と 2. はわかりやすいように見えますが、ここで適切に対処されています: Apple Watch のコンプリケーション データを更新するフローは何ですか?

ただし、項目 3 については、iOS アプリで WCSession インスタンスをセットアップし、transferCurrentComplicationUserInfo を呼び出して、新しい設定を NSDictionary として送信します。ウォッチ拡張機能では、これにより WCSessionDelegate で didReceiveUserInfo が呼び出されます。

- (void)session:(WCSession *)session didReceiveUserInfo:(NSDictionary<NSString *,id> *)userInfo {
    // Code here to apply the new settings
    // ....
    // Invoke a NSUSRLSession-based web query to get new data
    [self queryForNewDataWithCompletionHandler:^(NCUpdateResult result) {
        if (result == NCUpdateResultNewData) {
            // Have new data from web to display
            CLKComplicationServer *server = [CLKComplicationServer sharedInstance];
            for (CLKComplication *complication in server.activeComplications) {
                [server reloadTimelineForComplication:complication];
            }
        }
        // Set date for next complication update to 30 mins from now
        // ...
    }];
}

私が抱えている問題は、watchOS が、didReceiveUserInfo を呼び出した直後に、requestedUpdateDidBegin を別のスレッドで呼び出しており、アプリから新しく受信した UserInfo ディクショナリの新しい設定を使用して更新されたデータを取得する前に、これが実行を開始することです。

その結果、コンプリケーションは短時間で 2 回連続して更新されます。1 回目は、WatchOS が requestedUpdateDidBegin を呼び出して、既存の (古い) データでコンプリケーションを再更新した後、すぐに Web から新しいデータを受け取り、それらを更新する必要があります。再び自分のコードで。

これは不必要であり、リソースの浪費であり、Apple が許可している限られた更新の予算 (おそらく 1 時間に 2 回) は言うまでもありません。

私はここで何か悪いことをしていますか? Web から新しいデータを取得する前に、watchOS2 が requestedUpdateDidBegin を呼び出さないようにするにはどうすればよいですか?

4

1 に答える 1

2

の目的は、transferCurrentComplicationUserInfo現在の合併症データを拡張機能にすぐに渡すことです。コードでは、設定を渡していますが、気象データは含まれていません。

表示されている問題は、拡張機能内で新しいデータを非同期的にフェッチしようとしたことに起因します(データが利用可能になる前に返されます)。

これを処理するには、新しい設定に基づいて電話で現在の気象データを取得し、現在のコンプリケーション ユーザー情報で気象データを (新しい設定と共に) 渡す必要があります。

- (void)session:(WCSession *)session didReceiveUserInfo:(NSDictionary<NSString *,id> *)userInfo {
    // Code here to apply the new settings for future updates
    // ....
    // Code here to update cache/backing store with current weather data just passed to us
    // ....

    CLKComplicationServer *server = [CLKComplicationServer sharedInstance];
    for (CLKComplication *complication in server.activeComplications) {
        [server reloadTimelineForComplication:complication];
    }
}

このようにして、コンプリケーション サーバーは、ウォッチに転送したばかりの現在のコンプリケーション データを使用してタイムラインを即座に更新できます。

古いデータや不要な 2 回目の更新はありません。

于 2016-01-12T22:57:39.853 に答える