ちょっと不便
ALAssetsLibrary
を触るときにはユーザーに AssetsLibary へのアクセスを許可してもらわないといけません。個人的には先にアクセス許可の伺いを立ててからその結果に応じてアプリとしての振る舞いを切り分けたいと思います。しかし、ALAssetsLibary
にはそのようなメソッドは提供されていません。似たようなアクセス許可を得るものには ACAccountStore
がありますが、こちらはこのようなメソッドがあり結果に応じて振り分け可能になっています。
- (void)requestAccessToAccountsWithType:(ACAccountType *)accountType options:(NSDictionary *)options completion:(ACAccountStoreRequestAccessCompletionHandler)completion
ACAccountStore Class Reference
カテゴリメソッドを書いてみた
ALAssetsLibrary でも同様の振る舞いができるようなカテゴリメソッドを書いてみました。
Category method to get permission before using ALA ...
使用例
- (void)viewDidLoad
{
[super viewDidLoad];
[ALAssetsLibrary csn_requestAccessToAssetsLibraryWithCompletionBlock:^(BOOL granted, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (granted && error == nil) {
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
[self presentViewController:picker animated:YES completion:NULL];
} else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Needs Permission" message:nil delegate:nil cancelButtonTitle:@"close" otherButtonTitles:nil];
[alert show];
}
});
}];
}
エラー処理は適当に書いていますがこれで事前にアクセス権を確認したのちに任意の処理にすすめられます。
実装のポイント
アクセス許可のアラートは実際に ALAssetsLibrary に触らないと出ません。ですので、- (void)enumerateGroupsWithTypes:(ALAssetsGroupType)types usingBlock:(ALAssetsLibraryGroupsEnumerationResultsBlock)enumerationBlock failureBlock:(ALAssetsLibraryAccessFailureBlock)failureBlock
で触ってしまいます。アラートを出してもらうのが目的なので得られた ALAssetsGroup には何もせずに即座に *stop に YES を代入して enumeration を止めつつ呼び出し元にコールバックします。
ユーザーが拒否した場合には failureBlock が呼ばれるのでそこで呼び出し元にコールバックします。
ハマったのが、この enumeration は NSArray
の enumeration と違い *stop に YES を代入しても即座にループは止まらず都合2回 usingBlock
が呼び出されます。推測ではありますが、- (void)enumerateGroupsWithTypes:(ALAssetsGroupType)types usingBlock:(ALAssetsLibraryGroupsEnumerationResultsBlock)enumerationBlock failureBlock:(ALAssetsLibraryAccessFailureBlock)failureBlock
は「列挙すべき group
がなくなった場合には group
が nil の状態で usingBlock
が呼び出される」というデザインになっています。この API デザインを踏襲するために *stop に YES が代入されてももう一度 usingBlock
が呼び出されるのだと思います。
まとめ
少しトリッキーな実装になっていますが、リファレンスやヘッダファイルに書かれていることをベースにして実装しているので特に害はないと思います。使いやすいと思うので良かったら使ってみてください。