applicationWillResignActive とか、どうすんの

いやー、マジはまった。

ライフサイクルの話ね。GPS とか方角を使うアプリ作ってて、こういうアプリはすごい電池喰うから、バックグラウンドに回ったら中断、フォアグラウンドに回ったら再開ってことにしたかったのね。車で言うところの、アイドリングストップ機能っての?

こういうのは、AppDelegate で定義するってのは知ってて、さあやろうとしたら、あれおかしいな、うまくいかない。なんでなんで?

理由は iOS 13 からは、SceneDelegate って概念が導入されていて、従来は AppDelegate で担っていた一部のライフサイクルを、SceneDelegate が担うことになったと。template も対応していて、勝手にファイルが作られてて、method も作られているから、どの method は AppDelegate で、SceneDelegate はこの method ってのは file  を見たらわかるはず。

それで、「バックグラウンドに回ったら」ってのは、applicationWillResignActive なんだけど、その際、ViewController で起動していた locationManager を stop したいわけだ。SceneDelegate 内で、ViewController の locationManager って記述ができなくて・・・新たに instance 作ればできるよ。でも、起動中の ViewController を捕まえるのは難しくないか?

こういう時は、delegate を新設すればよいのでは? ってことで、SceneDelegate って名前だけど、このファイルに SceneDelegateDelegate って protcol を新設した訳よ。なんか違うくね?と思いつつ。だって、元々 delegate って名前がついているファイルに delegate を設定する訳だぜ。おかしいだろと。そしたら、ViewController ではこの delegate を全く受けてくれないのね。これは困った。このままでは省電力設計できないじゃん。エコれないじゃん。でも、最近の OS はバックグラウンドに回ったら、勝手に中止するような気がしてならなくて、わざわざ method 用意しなくてよくね?ってのも思った。いやいや、悪魔の囁きに耳を貸してはいけない。ちゃんと省電力を実装しないと。進歩しないと。

いろいろ調べた結果、そもそも、notification center に通知されているか、ViewController でそれを受け取ればよいってことでこんな感じ。

- (void) viewWillAppear:(BOOL)animated

{

    [super viewWillAppear:animated];

    

    // 省電力の設定

    [[NSNotificationCenter defaultCenter]

     addObserver:self

     selector:@selector(applicationWillResignActive) name:UIApplicationWillResignActiveNotification

     object:nil];

    

    [[NSNotificationCenter defaultCenter]

     addObserver:self

     selector:@selector(applicationDidBecomeActive) name:UIApplicationDidBecomeActiveNotification

     object:nil];

}

selector に対応する method は ViewController に書いておけと。

ふぅ、マジ疲れた・・・