まーぽんって誰がつけたの?

iOS→Scala→インフラなおじさん技術メモ

iOSでカメラと写真の利用許可の確認方法

そもそもどんな制限が可能か

  • 機能制限(デバイス全体で使わせない)
  • プライバシー制限(アプリごとに選べる)

iOS7とiOS8でブライバシーの概念が違う

要はカメラの利用をアプリにさせるかってのはiOS8からできるようになったって話。

OS カメラ 写真(ライブラリ)
iOS7 制限なし ユーザーが選べる
iOS8 ユーザーが選べる ユーザーが選べる

カメラの利用制限の確認方法

カメラ機能制限の確認

機能制限の確認方法なんだけど、AVAuthorizationStatusRestrictedがあるからそれでいけんのかと思ったんだけど、そこに来ない。isSourceTypeAvailableで見るしかないっぽい。カメラの機能制限か、単純にデバイスにカメラが存在しない(昔のiPodとか?)の場合。ただしどちらかは判別不可能。

if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
    // do something
}

カメラプライバシーの確認

AVAuthorizationStatusがあるからそれで簡単にわかる。インストール直後は、AVAuthorizationStatusNotDeterminedに来るのでそこでユーザーに確認するダイアログを表示して、そこにブロックで処理を書いておく。

AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
    
switch (status) {
    case AVAuthorizationStatusAuthorized:
        // プライバシー設定でカメラの使用が許可されている場合
        break;
    case AVAuthorizationStatusDenied:
        // プライバシー設定でカメラの使用が禁止されている場合
        break;
    case AVAuthorizationStatusRestricted:
        // 機能制限の場合とあるが、実際にこの値をとることがなかった
        break;
    case AVAuthorizationStatusNotDetermined:
        // 初回起動時に許可設定を促すダイアログが表示される
        [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
            if (granted) {
                // 許可された場合の処理
                dispatch_async(dispatch_get_main_queue(), ^{
                    // do something
                });
            } else {
                // 許可してもらえない場合
                dispatch_async(dispatch_get_main_queue(), ^{
                    // do something
                });
            }
        }];
        break;
    default:
        break;
}

写真の利用制限の確認方法

写真の方は機能制限もプライバシーもALAuthorizationStatusで素直に確認できた。

ALAuthorizationStatus status = [ALAssetsLibrary authorizationStatus];

switch (status) {
    case ALAuthorizationStatusAuthorized:
        // 写真へのアクセスが許可されている状態
        break;
    case ALAuthorizationStatusNotDetermined:
    {
        // 初回起動時に許可設定を促すダイアログが表示される
        ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
        [library enumerateGroupsWithTypes:ALAssetsGroupAll
                               usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
                                   // 許可された場合
                                   dispatch_async(dispatch_get_main_queue(), ^{
                                       // do something
                                   });
                                }
                              failureBlock:^(NSError *error) {
                                   // 許可してもらえない場合
                                   dispatch_async(dispatch_get_main_queue(), ^{
                                   });
                               }];
    }
        break;
    case ALAuthorizationStatusDenied:
        // プライバシーで許可されていない状態
        break;
    case ALAuthorizationStatusRestricted:
       // 機能制限されている場合
        break;
    default:
        break;
}

iOS8から設定画面にアプリの設定画面に飛べるようになった

NSURL *settingsURL = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
[[UIApplication sharedApplication] openURL:settingsURL];

NotDetermindのテストが面倒過ぎてヤバいと思ったけど・・!!

Stackoverflowで探しててアプリ消して再起動して時間を動かしてやらないといけないって書いてあって死ぬかと思ってた。でも、コメントにちょう簡単な方法があった。iPhoneの設定画面からリセットできる。開発端末ならいくらでもリセットしても気にならないしね。

rmaddyさんのコメント

Why not simply do it the easy way? Settings -> General -> Reset -> Rest Location & Privacy – rmaddy Jan 1 at 0:23

これでリセットできます。

Settings -> General -> Reset -> Rest Location & Privacy

参考記事

  1. Xcode5によるiOS8対応 - Qiita
  2. iOS Tips #6 写真のアクセス制限 | Developers.IO
  3. カメラ, カメラロール, フォトアルバムから画像を選択してメール添付する - Javaな日々