Help us understand the problem. What is going on with this article?

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

More than 5 years have passed since last update.

新生 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 をぶち壊しになられた事案について書きたいと思います。

参考資料

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away