[watchOS 3] WKApplicationRefreshBackgroundTask を使用して watchOS アプリをバックグラウンドで更新する

2016.10.28

はじめに

こんにちは。モバイルアプリサービス部の平屋です。

本記事では watchOS 3.0 で追加された新クラス WKApplicationRefreshBackgroundTask の使用方法を紹介します。

検証環境

  • Xcode Version 8.1
  • iPhone 7, iOS 10.1
  • Apple Watch, watchOS 3.1

WKApplicationRefreshBackgroundTask

WKApplicationRefreshBackgroundTask はバックグラウンドでアプリの状態を更新するためのクラスです。このクラスのインスタンスは WKExtension の機能を使用して作成します。開発者側で直接作成することはできません。

タスクを追加

まずは、WKExtensionscheduleBackgroundRefresh(withPreferredDate:userInfo:scheduledCompletion:) メソッドを使用してバックグラウンドタスクをスケジューリングします。

1 つめの引数にタスクを実行させたい時間を指定します。指定した時間以降のどこかで実行される感じのようです。以下の実装例では 120 秒後を指定しています。

2 つめの引数にはタスクに関係するオブジェクトを格納できます。

3 つめの引数にはブロックを指定します。このブロックが使用されるタイミングについて、リファレンスには「ブロックはタスクが完了した時に呼ばれる」という説明が書いてあります。しかし、コードを実行してみたところ scheduleBackgroundRefresh(withPreferredDate:userInfo:scheduledCompletion:) を実行した直後に呼ばれました。

@IBAction func buttonTapped() {
    // fire in 120 seconds
    let fireDate = Date(timeIntervalSinceNow: 120.0)

    WKExtension.shared().scheduleBackgroundRefresh(withPreferredDate: fireDate,
                                                   userInfo: nil,
                                                   scheduledCompletion: { (error) in
                                                    if (error == nil) {
                                                        print("success!")
                                                    }
    })
}

タスクの実行をハンドリング

バックグラウンドタスクの実行が始まると、システムはアプリをバックグラウンドで起動させ、WKApplicationRefreshBackgroundTask を作成します。

そして、この作成された WKApplicationRefreshBackgroundTaskWKExtensionDelegatehandle(_ backgroundTasks: Set) メソッドで取得することができます。

何らかの処理を行い、処理が完了したらタスクの setTaskCompleted() メソッドを呼びます。

// 任意のタイミングで delegate を設定しておく
override func awake(withContext context: Any?) {
    super.awake(withContext: context)

    WKExtension.shared().delegate = self
}

func handle(_ backgroundTasks: Set<WKRefreshBackgroundTask>) {
    for task : WKRefreshBackgroundTask in backgroundTasks {
        // ...

        if task is WKApplicationRefreshBackgroundTask {
            // 何らかの処理を行う
            // ...

            // タスクを完了にする
            task.setTaskCompleted()
        }

        // ...
    }
}

処理が完了したタイミングなどで、再度 WKExtension クラスの scheduleBackgroundRefresh(withPreferredDate:userInfo:scheduledCompletion:) メソッドを使用すれば、次回のバックグラウンドタスクをスケジューリングすることができます。

動作結果

バックグラウンドタスクが 2 分後に実行されるように指定してみたところ、8分後ぐらいに実行されました。数分のズレは発生するようです。

2016-10-28 04:19:46 +0000 buttonTapped() 120 fireDate: 13:21:46 GMT+9
2016-10-28 04:19:46 +0000 buttonTapped() 126 success!
2016-10-28 04:27:24 +0000 handle 55 received background task: <WKApplicationRefreshBackgroundTask: 0x14568c80>

さいごに

本記事では watchOS 3.0 で追加された新クラス WKApplicationRefreshBackgroundTask の使用方法を紹介しました。watchOS 2 以前の OS ではバックグラウンドで動作可能な時間に制限がありましたが、watchOS 3.0 では開発者が希望する時間にタスクを実行できるようになりました。

次の記事では WKSnapshotRefreshBackgroundTask の使用方法を紹介します。

参考資料