なぜ?
UIApplication のライフサイクルはいろんなところで書かれていますが、Silent Notification を考慮した記事が見つからなかったので調べようと思いました。
「ユーザーがアプリを起動/再開した時に何らかの通信処理をしたいが、Silent Notification によって起動/再開した時にはその通信をさせたくないよ!」などという要求が満たせれば、と思います。
確認は iOS9 で行っています。
※ Silent Notification とは、content-available:1
のアレです
https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/ApplePushService.html
起動系
ホーム画面でアイコンをタップして起動した時
1. application:WillFinishLaunchingWithOptions: (launchOptions=nil)
2. application:didFinishLaunchingWithOptions: (launchOptions=nil)
3. applicationDidBecomeActive:
ホーム画面でアイコンをタップして再開した時
1. applicationWillEnterForeground:
2. applicationDidBecomeActive:
Silent Notification を受け取って起動した時
1. application:WillFinishLaunchingWithOptions: (launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey]=通知ペイロード)
2. application:didFinishLaunchingWithOptions: (launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey]=通知ペイロード)
3. application:didReceiveRemoteNotification:fetchCompletionHandler:
Silent Notification を受け取って再開した時
1. application:didReceiveRemoteNotification:fetchCompletionHandler:
終了系
ホームボタンを押してアプリを中断した時
1. applicationWillResignActive:
2. applicationDidEnterBackground:
通知受信処理内で CompletionHandler を呼んで中断されるとき
ライフサイクル系の delegate は何も呼ばれません
調査結果
上記の結果を見ると、ユーザーがアイコンタップしたときの起動/再開時にのみしたい処理は applicationDidBecomeActive:
に書くと良さそうです。が、 applicationDidBecomeActive:
はアプリ内で各種ダイアログを閉じた時にも呼ばれてしまうため、冒頭の要求のためには適切ではありません。
まとめ
ということで、Silent Notification を使っているアプリでユーザーのタップでの起動/再開時のみに処理を行いたいときは、以下のように書くと良さそうです。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if( launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey] == nil ){
[self onFinishLaunchingByUserControl];
[self onBecomeActiveByUserControl];
}
return YES;
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
[self onBecomeActiveByUserControl];
}
/// ユーザーの操作によってアプリが起動した時の処理
- (void)onFinishLaunchingByUserControl{
}
/// ユーザーの操作によってアプリが起動/再開したときの処理
- (void)onBecomeActiveByUserControl{
}
リモート通知やローカル通知をタップした時の挙動については必要になったら調べて追記します。