LoginSignup
10
12

More than 5 years have passed since last update.

Today Extensionメモ&サンプル

Last updated at Posted at 2016-05-28

Today Extensionは通知センター内に表示するウィジェットを提供するエクステンションです。

today_extension.jpg

iPhoneのモーションセンサが計測した歩数を表示するサンプルを作成しました。
https://github.com/imk2o/Try-AppExtensions

処理の流れ

  • ビューコントローラがインスタンス化される
  • ウィジェットのマージンを求める
    • NCWidgetProviding#widgetMarginInsetsForProposedMarginInsets(_:)
  • データを取得し、ウィジェットを更新する
    • NCWidgetProviding#widgetPerformUpdateWithCompletionHandler(_:)
  • ユーザアクションに応じ、アプリを起動する
    • NSExtensionContext#openURL(_:completionHandler:)

widgetPerformUpdateWithCompletionHandler(_:)

データ取得等を行い、ウィジェットの更新を行うロジックを実装します。
更新完了時は必ず、以下のいずれかの値とともにcompletionHandlerを呼び出す必要があります。

  • NCUpdateResult.Failed: エラーが発生した
  • NCUpdateResult.NoData: 更新を行わなかった
  • NCUpdateResult.NewData: 更新を行った
    func widgetPerformUpdateWithCompletionHandler(completionHandler: ((NCUpdateResult) -> Void)) {
        guard CMPedometer.isStepCountingAvailable() else {
            completionHandler(.Failed)
            return
        }

        // 今日の00:00から現時刻までの歩数を求め、これを表示する
        let now = NSDate()
        let calendar = NSCalendar.currentCalendar()
        let dateComponents = calendar.components([NSCalendarUnit.Year, NSCalendarUnit.Month, NSCalendarUnit.Day], fromDate: now)
        let startDate = calendar.dateFromComponents(dateComponents)

        self.pedometer.queryPedometerDataFromDate(startDate!, toDate: now) { (data, error) in
            if let _ = error {
                completionHandler(.Failed)
            } else if let steps = data?.numberOfSteps {
                self.stepsLabel.text = "\(steps) steps"
                completionHandler(.NewData)
            } else {
                completionHandler(.NoData)
            }
        }
    }

widgetMarginInsetsForProposedMarginInsets(_:) (optional)

通常は通知センター内に一定のマージンを取った内側にウィジェットが表示されますが、このマージンを調整することができます。

アプリの起動

アプリへの導線を追加する場合は、UIViewController#extensionContextopenURL()を利用します。

    @IBAction func viewDidTap(sender: AnyObject) {
        // URLスキームでアプリを起動
        if let appURL = NSURL(string: "myapp://") {
            self.extensionContext?.openURL(appURL, completionHandler: nil)
        }
    }

メモ

「高負荷な処理を行ってはいけない」や「横スクロールできてはいけない」等、いくつかのガイドラインに従い実装する必要があります。

参考

https://www.gaprot.jp/pickup/ios8/today-extension
http://sonson.jp/blog/2014/09/18/Widget/

10
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
12