web-dev-qa-db-ja.com

ウォッチコンプリケーションのデータをいつどこで取得するか

複雑な問題を数日間処理した後、所定の間隔で発生する更新の更新プロセスについて、次のように自信を持って言えます。

  • システムはrequestedUpdateDidBegin() [.____を呼び出します。]
    • ここで、データが変更されたかどうかを判断できます。そうでない場合、アプリは何もする必要はありません。データが変更された場合は、次のいずれかを呼び出す必要があります:
      • reloadTimelineForComplicationすべてのデータをリセットする必要がある場合。
      • extendTimelineForComplication合併症のタイムラインの最後に新しいアイテムを追加するだけでよい場合。
    • 注:1日のコンプリケーションの時間予算を使いすぎた場合、システムは実際にrequestedUpdateBudgetExhausted()ではなくrequestedUpdateDidBegin()を呼び出すことがあります。これがこの質問の理由です。
  • reloadTimelineForComplicationを呼び出した場合、システムはgetCurrentTimelineEntryForComplicationを呼び出します(タイムトラベル設定に応じて、配列を取得する将来および過去のバリアントとともに)。
  • まだテストしていないのでこれは推測ですが、extendTimelineForComplicationを呼び出した場合、getTimelineEntriesForComplication(... afterDate date: NSDate ...)のみが呼び出されると思います。
  • その後、システムはgetNextRequestedUpdateDateWithHandlerを呼び出します。これにより、合併症が新しい更新を必要とするまでの時間を指定できます。

Appleのドキュメントでは、更新を頻繁に要求したり、複雑なコードで過度の処理を実行したりしないでください。そうしないと、時間の予算を使い果たして、複雑な更新が停止します。だから、私の質問は:どこでいつ更新を行うのですか?

コンテキストとして、私のシナリオは、1時間に最大2回変化する戻りデータを含むURLです。

URLフェッチコードを配置する最も明白な場所はfunc requestedUpdateDidBegin()です。データをフェッチして格納し、変更がない場合は単に戻ります。変更があった場合は、タイムラインを延長または再ロードします。

ただし、URLフェッチはコストがかかる可能性があります。代替案:

  • コードを電話アプリに配置してWCSessionで送信しますが、ユーザーがそのアプリを閉じると、更新は行われなくなります。
  • プッシュ更新を使用しますが、これはWebアプリではないため、そこから送信する場所がありません。
  • もちろん、ユーザーが時計アプリを操作するときにすべてのデータを更新しますが、これは、ユーザーがアプリを使用したときにのみ更新されることを意味し、複雑さの必要がなくなります。

他にどこにありますか?合併症の一部ではない時計アプリに定期的な機能を持たせることはできますか?コンプリケーションの更新のためにデータをフェッチする適切な場所はどこですか?

31
El Tea

WatchOS 3の場合、Apple複雑化データソースの使用から切り替えることをお勧めします getNextRequestedUpdateDate 複雑化を更新するためにスケジュールされた更新。

WatchOS 2の古い方法

requestedUpdateDidBegin()は、複雑さを更新するためだけに設計されています。複雑な機能(およびウォッチアプリ)を最新の状態に保つには、通常、タイムラインをリロードする(そして非同期にデータを取得することは、古いアプローチではうまく収まらない)よりもはるかに多くのことを伴います。

WatchOS 3の新しい方法

新しい、より良いアプローチは バックグラウンド更新アプリタスク を使用することです。一連のバックグラウンドタスクを使用して schedule および handle アプリの拡張機能をバックグラウンドで起動し、次のことができます。

  • 新しいデータを取得する

  • データが到着したらモデルを更新し、
  • (タイムラインをリロードまたは拡張することにより)モデルから複雑化を更新し、最後に
  • アプリのドックのスナップショットを更新して、ドックにデータを表示します

タスクが完了したらすぐに、各タスクのsetTaskCompletedメソッドを呼び出します。

アプリタスクを使用するその他の利点

このデザインの重要な機能の1つは、時計の拡張機能がさまざまなフォアグラウンドおよびバックグラウンドのシナリオを処理できるようになったことです。

  • アプリ/コンプリケーションの開始時に最初にデータをロードし、
  • 拡張機能がバックグラウンドタスクによって起こされたときに、バックグラウンドでデータを更新します。
  • ユーザーがドックからアプリを再開すると、フォアグラウンドでデータが更新されます。

Appleは、アプリがフォアグラウンドにあるかバックグラウンドにあるかに関係なく与えられた機会をすべて使用することをお勧めします複雑さ、アプリ、およびドックのスナップショットを維持します現在まで。

制限はありますか?

1日あたりの利用可能なタスクの合計数は、ドック内のアプリの数で割られます。ドック内のアプリが少ないほど、アプリが使用できるタスクが多くなります。ドック内のアプリが多いほど、利用できる数が少なくなります。

  • 合併症がアクティブな場合、アプリは少なくとも1時間に4回目覚めることができます。

  • 合併症がアクティブでない場合、アプリは少なくとも1時間に1回は起こされることが保証されています。

アプリがバックグラウンドで実行されているので、バックグラウンドタスクを効率的かつ迅速に完了することが期待されます。

バックグラウンドタスクは、許容されるCPU時間とCPU使用量によって制限されます。 CPU時間を超えた場合(またはバックグラウンドでCPUの10%以上を使用した場合)、システムはアプリを終了します(クラッシュ)。

詳細については

  • 時計アプリを更新する時期と理由を説明する良い入門書は Designing Great Apple Watch Experiences で説明されています。

  • 詳細については、 ウォッチアプリを最新の状態に保つ セッションで、複雑な機能、アプリ、ドックのスナップショットを最新の状態に保つために必要なすべての情報を取り上げます。

  • WatchBackgroundRefresh サンプルコードは、WKRefreshBackgroundTaskを使用してWatchKitアプリをバックグラウンドで更新する方法を示しています。

24
user4151918

編集:El Tea(op)が https://stackoverflow.com/a/32994055/630614

これは興味深い質問/問題であり、私は同じことの多くについて疑問に思っています!

ほとんどの場合、私が新しい合併症に取り組んでいるとき、私は前に戻り、いつ更新するのかしたいかを確認する必要があるようです。 「カウントダウン」コンプリケーションは、「終了日」が設定されている場合、将来のすべてのタイムラインエントリを一度に設定できます。 Webサービスの現在のステータスを表示するアプリでは、APNSが通過したときに、関連データがNSUserDefaultsに保存される可能性があります。

APNSにアクセスできない場合、iOSアプリをバックグラウンドモードで実行したくない場合、およびApple=からHTTPリクエストを作成したくない場合は、他の2つのオプション。

1)ローカル通知をスケジュールします。良い点は、あなたのApple WatchがdidReceiveLocalNotificationを実行する必要があることです、しかし、悪い点は、中断することなく単にステータスを確認しようとすると、ユーザーに通知が表示されることです。

2)reloadTimelineForComplicationメソッドの sendMessage(_:replyHandler:errorHandler:) を介してiOSにメッセージを送信し、 nilreplyHandlerに設定すると、可能な限り速くなります。

WatchKit拡張機能がアクティブで実行中にこのメソッドを呼び出すと、対応するiOSアプリがバックグラウンドで起動し、到達可能になります。

IOSアプリは、必要なネットワーク要求をすべて実行してから情報を保存するか、Apple Watchにプッシュします。残念ながら、Watch拡張機能にsession.didReceive...は実行するまで呼び出されましたが、次のrequestedUpdateDidBeginの呼び出しでデータにアクセスできました。

私が言ったように、私はこれと同じことに非常に興味があるので、いくつかの考えを投稿してください。おそらく、ここでいくつかのベストプラクティスを推定することができます。

4