LoginSignup
69
66

More than 5 years have passed since last update.

PHImageManager - requestImageForAsset が二回 handler を呼ぶ事案

Last updated at Posted at 2014-09-20

新生 ALAssetsLibrary であるところの PHPhotoLibrary ですが、まあ互換性をぶち壊したのもさることながら多少理解し難い API にもなっている所があります。

- requestImageForAsset が二回 handler を呼ぶ

PHImageManager - requestImageForAsset:targetSize:contentMode:options:resultHandler: こいつの resultHandler は二回以上呼ばれます。

というのも、解像度が低い画像を先に渡して、あとから取得した解像度の高い画像を渡す、という仕様になっているようです。
想定用途は、「画像の取得には時間がかかるから、サムネイルを表示してお茶を濁してくれ」ということらしいですね。

また、二回と書きましたが取得するサイズによっては数回に渡って resultHandler を渡す可能性があります。

というわけで、画像を取ってきて xx する、といった処理にこいつを使うと想定外の動作をする可能性があります。注意が必要です。
冪等な操作でも、例えばフィルタ等重い処理が複数回走るとアプリの体験を損なう可能性があります。

これを防止する方法としては、次の 3 つがあります。

解決策1 - infoPHImageResultIsDegradedKey を見る

resultHandler の第二引数である info に、 PHImageResultIsDegradedKeyBOOL が入っているのでこいつを見ます。
コードとしては、

[[PHImageManager defaultManager] requestImageForAsset:asset targetSize:size contentMode:PHImageContentModeDefault options:nil resultHandler:^(UIImage *result, NSDictionary *info) {
    BOOL isDegraded = [info[PHImageResultIsDegradedKey] boolValue];
    if (isDegraded == YES) { return; }

    // なんかする
}];

解決策2 - PHImageRequestOptionsdeliveryMode を設定する

Option の deliveryMode でこれを制御しているらしいので、こいつを PHImageRequestOptionsDeliveryModeHighQualityFormat に設定すれば必ず指定したサイズの画像を持ってきてくれるようになります。

コードとしては

PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
options.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;

[[PHImageManager defaultManager] requestImageForAsset:asset targetSize:size contentMode:PHImageContentModeDefault options:options resultHandler:^(UIImage *result, NSDictionary *info) {
    // なんかする
}];

解決策3 - - requestImageDataForAsset を使う

- requestImageDataForAsset:options:resultHandler: は今の所一回しか呼ばないような感じなので、こっちを使うと変に悩みません。ただしサイズの指定は出来ません。

まとめ

次は Apple 様が ALAssetsLibrary をぶち壊しになられた事案について書きたいと思います。

参考資料

69
66
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
69
66