読者です 読者をやめる 読者になる 読者になる

ObjecTips

基本Objective-Cで iOS とか OS X とか

WatchKit Extension から親アプリを起動した時の挙動

Objective-C Tips WatchKit WKInterfaceController UIApplication

WKInterfaceControlleropenParentApplication: メソッドから親アプリが起動された際にどのような処理の流れになるのか確認してみた。
確認方法は以下

  • 親アプリとエクステンションの両方に NSLog を仕込む
  • Xcode で WatchKit App をターゲットにしてrunする
  • ログ出力を確認する
    • シミュレータの場合 コンソール.app で system.log を見る
    • 実機の場合 Xcode のメニューの Window>Devices からデバイスのログを見る

仕込んだログは以下

    NSLog(@"%s", __func__);

ログ結果は以下

May  6 19:55:58 iMac.local Test WatchKit Extension[13991]: -[InterfaceController awakeWithContext:]
May  6 19:55:58 iMac.local Test WatchKit Extension[13991]: -[InterfaceController willActivate]
May  6 19:56:10 iMac.local Test WatchKit Extension[13991]: -[InterfaceController openParentApplication]
May  6 19:56:10 iMac.local Test[13995]: -[AppDelegate application:didFinishLaunchingWithOptions:]
May  6 19:56:10 iMac.local Test[13995]: -[ViewController viewDidLoad]
May  6 19:56:10 iMac.local Test[13995]: -[ViewController viewWillAppear:]
May  6 19:56:10 iMac.local Test[13995]: -[AppDelegate application:handleWatchKitExtensionRequest:reply:]
May  6 19:56:10 iMac.local Test WatchKit Extension[13991]: __44-[InterfaceController openParentApplication]_block_invoke
May  6 19:56:10 iMac.local Test[13995]: -[ViewController viewDidAppear:]
~
May  6 20:06:26 iMac.local Test[13995]: -[AppDelegate applicationWillEnterForeground:]
May  6 20:06:27 iMac.local Test[13995]: -[AppDelegate applicationDidBecomeActive:]

という事で、
まずテクステンションの initialController の awakeWithContext: willActivate が呼ばれる。
そしてエクステンションから openParentApplication: を呼ぶと

  1. application:didFinishLaunchingWithOptions: が呼ばれてアプリが起動する
  2. initialViewController が生成され viewDidLoad が呼ばれる
  3. viewWillAppear: が呼ばれる
  4. エクステンションとの連携を行う application:handleWatchKitExtensionRequest:reply: が呼ばれる
  5. エクステンション側に reply ブロックが返される
  6. viewDidAppear: が呼ばれる

この時アプリは裏で起動するが、iPhone上にアプリの画面が表示される事はない。

この後ホーム画面から親アプリを開くと
applicationWillEnterForeground: applicationDidBecomeActive: が呼ばれる。
initialViewController は既に表示済みの状態になっているので、改めて viewWillAppear: viewDidAppear: が呼ばれる事はない。