22

コンプリケーションの設定方法を学ぶために、インターネット上の多くのチュートリアルに従ってきました。コンプリケーションを期待どおりにセットアップするのに問題はありません。

最初のタイムライン エントリが期限切れになるまで。12時間後、複雑さを維持するために更新する方法がわかりません. 以下に私が持っているすべてを共有します。誰かが私を埋めるのを手伝ってくれることを願っています.

ここでは、コンプリケーションに表示するデータの変数を作成します。

struct data = {
var name: String
var startString: String
var startDate: NSDate
}

次の配列は、このデータのコンテナーです。

var dataArray = [data]

これにより、時計がロックされているときにコンプリケーションを表示できます。

func getPrivacyBehaviorForComplication(complication: CLKComplication, withHandler handler: (CLKComplicationPrivacyBehavior) -> Void) {
    handler(.ShowOnLockScreen)
}

これにより、コンプリケーションでタイム トラベルを進めることができます。

func getSupportedTimeTravelDirectionsForComplication(complication: CLKComplication, withHandler handler: (CLKComplicationTimeTravelDirections) -> Void) {
    handler([.Forward])
}

ここでは、タイムラインの開始時刻を現在と等しくなるように設定します。

func getTimelineStartDateForComplication(complication: CLKComplication, withHandler handler: (NSDate?) -> Void) {
    handler(NSDate())
}

ここでは、タイムラインの終了時間を今から 12 時間後に設定します。

func getTimelineEndDateForComplication(complication: CLKComplication, withHandler handler: (NSDate?) -> Void) {
    handler(NSDate(timeIntervalSinceNow: (60 * 60 * 12)))
}

ここで、コンプリケーションのテンプレートを作成します。これは、ユーザーがウォッチですべてのコンプリケーションを参照しているときに、私のコンプリケーションが表示されたときにサンプル データを表示するためです。

func getPlaceholderTemplateForComplication(complication: CLKComplication, withHandler handler: (CLKComplicationTemplate?) -> Void) {

    let headerTextProvider = CLKSimpleTextProvider(text: "Some Data")
    let body1TextProvider = CLKSimpleTextProvider(text: "Some Data Time")
    let template = CLKComplicationTemplateModularLargeStandardBody()
    template.headerTextProvider = headerTextProvider
    template.body1TextProvider = body1TextProvider

    handler(template)
}

これにより、コンプリケーションの最初のタイムライン エントリが作成されます。コンプリケーションが有効になるとすぐに、このコードが実行され、それに応じてコンプリケーションがすぐに入力されます。

func getCurrentTimelineEntryForComplication(complication: CLKComplication, withHandler handler: (CLKComplicationTimelineEntry?) -> Void) {

    createData()

    if complication.family == .ModularLarge {

        if dataArray.count != 0 {

            let firstData = dataArray[0]
            let headerTextProvider = CLKSimpleTextProvider(text: firstData.name)
            let body1TextProvider = CLKSimpleTextProvider(text: firstData.startString)
            let template = CLKComplicationTemplateModularLargeStandardBody()
            template.headerTextProvider = headerTextProvider
            template.body1TextProvider = body1TextProvider
            let timelineEntry = CLKComplicationTimelineEntry(date: NSDate(), complicationTemplate: template)
            handler(timelineEntry)
        } else {
            let headerTextProvider = CLKSimpleTextProvider(text: "No Data")
            let body1TextProvider = CLKSimpleTextProvider(text: "Create some data")
            let template = CLKComplicationTemplateModularLargeStandardBody()
            template.headerTextProvider = headerTextProvider
            template.body1TextProvider = body1TextProvider

            let timelineEntry = CLKComplicationTimelineEntry(date: NSDate(), complicationTemplate: template)
            handler(timelineEntry)
        }

    } else {
        handler(nil)
    }

}

これは、現在持っているすべてのデータのタイムライン エントリを作成する場所です。

func getTimelineEntriesForComplication(complication: CLKComplication, afterDate date: NSDate, limit: Int, withHandler handler: ([CLKComplicationTimelineEntry]?) -> Void) {

    createData()

    var entries = [CLKComplicationTimelineEntry]()

    for dataObject in dataArray {

        if entries.count < limit && data.startDate.timeIntervalSinceDate(date) > 0 {

            let headerTextProvider = CLKSimpleTextProvider(text: dataObject.name)
            let body1TextProvider = CLKSimpleTextProvider(text: dataObject.startString)
            let template = CLKComplicationTemplateModularLargeStandardBody()
            template.headerTextProvider = headerTextProvider
            template.body1TextProvider = body1TextProvider
            let timelineEntry = CLKComplicationTimelineEntry(date: NSDate(timeInterval: (-10*60), sinceDate: data.startDate), complicationTemplate: template)
            entries.append(timelineEntry)

        }

    }

    handler(entries)

}

これにより、コンプリケーション データをいつ更新するかが時計に通知されます。

func getNextRequestedUpdateDateWithHandler(handler: (NSDate?) -> Void) {
    handler(NSDate(timeIntervalSinceNow: 60 * 60 * 6))
}

これは私が問題に直面しているところです。

新しいデータを作成してタイムラインをリロードするにはどうすればよいですか? 流れは?タイムラインを延長しようとしているのではなく、完全に置き換えようとしています。私は完全に途方に暮れています。この点に関しては、Appleのドキュメントはかなりあいまいです。次のメソッドを実装する必要があることはわかっていますが、方法がわかりません。誰かがこのコードを記入するのを手伝ってくれますか?

func requestedUpdateDidBegin() {
    createData() //I assume createData() goes here? If so, how do I populate the new timeline entries based on the results?
}

func requestedUpdateBudgetExhausted() {
    //This can't possibly be the case as I haven't gotten it to work once.
}

func reloadTimelineForComplication(complication: CLKComplication!) {
      //This method appears to do nothing.
}

アップデート:

El Teaのおかげで、うまくいきました。CLKComplicationServer のインスタンスを requestedUpdateDidBegin に追加し、内部に reloadTimeline メソッドを配置する必要があります。

更新されたコードは次のとおりです。

func requestedUpdateDidBegin() {
    print("Complication update is starting")

    createData()

    let server=CLKComplicationServer.sharedInstance()

    for comp in (server.activeComplications) {
        server.reloadTimelineForComplication(comp)
        print("Timeline has been reloaded!")
    }

}

func requestedUpdateBudgetExhausted() {
    print("Budget exhausted")
}
4

2 に答える 2

27

時間間隔で実行される合併症の更新のフローは、次の順序に従います。

  • iOS は関数を呼び出します。requestedUpdateDidBegin()またはrequestedUpdateBudgetExhausted()(予算が使い果たされた場合は、実行時間が増えるまで更新が発生しません。)
  • requestedUpdateDidBegin() あなたの内部で、リロードしたい、またはデータを追加したいコンプリケーションを呼び出すreloadTimelineForComplication()か、指定する必要があります。extendTimelineForComplication()これをしないと何も始まりません!
  • reloadまたはを呼び出したかどうかに応じてextend、iOS は および の一方または両方を呼び出しますgetCurrentTimelineEntryForComplication()getTimelineEntriesForComplication()
  • コンプリケーションを更新したかどうかに関係なく、iOS はgetNextRequestedUpdateDateWithHandler()、上記の手順を次にいつ繰り返すかを調べるために呼び出します。

注: 最後の 2 つの手順は、必ずしもこの順序で行う必要はありません。

プロセスはこのように機能するため、iOS が同じデータを繰り返し再生成するように要求することはありません。requestedUpdateDidBegin()コンプリケーションを更新する必要があるかどうかを判断する機会が得られます。そうでない場合、コードは返されるはずです。(これにより、コンプリケーションの実行時間が短縮され、iOS が 1 日の予算を使い果たしたためにアプリがそれ以上の更新から切り離されるのを防ぐことができます)。ただし、新しいデータがある場合は、呼び出して iOS に通知する必要がありますreloadTimelineForComplication()extendTimelineForComplication()

私が知る限り、そこに書いたものはすべて、内部でリロードまたは拡張を要求していないことを除けば、見栄えがしますrequestedUpdateDidBegin()。コンプリケーションがウォッチフェイスの複数の位置に表示される可能性があり、テンプレートごとに表示動作が異なる可能性があるため、それらすべてを無効にする必要があります。私のコードは次のようになります。

func requestedUpdateDidBegin() {

    //Not shown: decide if you actually need to update your complication.
    //If you do, execute the following code:

    let server=CLKComplicationServer.sharedInstance()

    for comp in (server.activeComplications) {
        server.reloadTimelineForComplication(comp)
    }
}

時間間隔以外にも、プッシュ アラートを含む更新を開始する方法があることに注意してください。時計アプリの実行時にリロードを実行するか、WCSession で Watch Connectivity フレームワークを使用して電話アプリから更新データを送信し、 を介してすぐに表示されるようにしtransferCurrentComplicationUserInfo()ます。詳細については、Apple のドキュメントの「合併症データの更新」を参照してください。

10 分という短い更新間隔のシミュレーター テストに成功しました。実行時間の予算があるため、実際の時計ではそれほど頻繁に更新するべきではないかもしれませんが、これにより、12 時間待たずにコードをテストできます。

于 2015-10-07T13:51:16.707 に答える