カメラへのアクセスを要求するダイアログを再度出す

とても忘れてしまうので覚え書き。

iOSアプリの開発をやってて(やっているという前提で)、カメラへのアクセスを要求するダイアログを出そうって事になった際(アクセスを要求するのはカメラに限った話じゃない)、そもそもに前面であり背面でありカメラがあるかどうかのチェックはするんですけど、ありますよって段になったら

+ (void)requestAccessForMediaType:(NSString *)mediaType completionHandler:(void (^)(BOOL granted))handler

とかなんとかを使ってダイアログを出すんでありますが、この時の設定ってアプリを消去しても端末の中に記録され続けるようで、再インストールして起動してチェックしようとしても、もはやAVAuthorizationStatusNotDeterminedは呼ばれなくなってしまうんですよね。

そういうときは、他のもまるごとになっちゃうけどプライバシーの設定をリセットします。 これ、できれば開発用の端末で行いたいところ。

設定 > 一般 > リセット > 位置情報とプライバシーをリセット

で行います。 パスコードの入力が必要になりますが、これでリセットされます。
続けて端末と開発機を結んでるUSBケーブル(Lightningケーブル)を抜き差ししますと、「このコンピュータを信頼しますか?」というおなじみのダイアログが出ますんで、「信頼」をタップ。(信頼しない、をタップするとXcodeで「ペアリングできてないぞ」って言われちゃう)。

ちなみにチェックはこんな感じのコードでいいんじゃないかと思います。

__block int retInt = 0;
	
switch ([AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo]) {
		
	// カメラの使用が許可されている
	case AVAuthorizationStatusAuthorized: {
		retInt = 0;
	} break;
			
	// カメラの使用が許可されていない
	case AVAuthorizationStatusDenied: {
		retInt = 1;
	} break;
			
	// カメラの使用が機能制限でオフになっている
	case AVAuthorizationStatusRestricted: {
		retInt = 2;
	} break;
			
	// 初回時にカメラへのアクセスを求めるダイアログが出る
	case AVAuthorizationStatusNotDetermined: {
		__block BOOL isHandled = NO;
		
		[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo
					  completionHandler:^(BOOL handler)
		 {
			 dispatch_async(dispatch_get_main_queue(), ^{
				 if (handler) {
					 // 許可された場合の処理
					 retInt = 0;
				 } else {
					 // 許可してもらえない場合
					 retInt = 1;
				 }
				 
				 isHandled = YES;
			 });
		 }];
			
		while (!isHandled) {
			[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
		}
	} break;
}

NSLog(@"retInt :: %d" , retInt);

どこかで機能制限のやつ(AVAuthorizationStatusRestricted)が呼ばれないというのを呼んだことがありますが、iOS9だからなのか、ちゃんと呼ばれます。 ちなみに前述のカメラの存在をチェックする話でと絡めると、機能制限をした場合は「カメラがない」ものとして扱われるようです。

また、主題のダイアログが出た場合、ループに入れてどちらか選択したのを待つようにしています。 そうしないとダイアログは出たけど処理が進んでしまい、(この場合だと)許可されたものだと解釈されちゃう。

と、そんなこんなです。