LoginSignup
14
8

More than 5 years have passed since last update.

iOS11でカメラロールから写真が取得できない(PHImageManager)不具合の解決策

Last updated at Posted at 2017-12-08

某Web系の会社の画像投稿系SNSサービスでエンジニアリングをしています。
今まで面倒でqiitaを書いてこなかったのですが、これから知見の整理として気が向いたら書いていこうと思います。

カメラロールからPHImageManagerを使ってカメラロールの画像を取得できない場合がある。

iOS11がリリースされてから、カメラロールから画像が選択できないなどの声が多くなってきました。

iOS11のリリース以前もいくつかこういったユーザさんの声はあったのですが、iOS11から現象が多くなりました。

はじめは、カメラロールに大量に画像があることが問題なのか?と考えその線で調査していたのですが
PHImageManagerのロードをページングしたり、端末の空き容量がほぼないとアラートを出してストレージの残容量を確保していただいたりしていましたが、全くの的外れでした。

以下で、原因から解決策を解説していきます。

原因

iCloudフォトライブラリが原因でした。

setting.png

上のように、「iCloudフォトライブラリ」を有効にしていて、「iPhoneのストレージを最適化」を有効にしていると
起こりやすいです。

何が起きていたか

  • iCloudフォトライブラリを有効にしている

この状態にすると、カメラロールの画像の実データが端末に存在せず、サムネイルのみ保持している状態が起こりうる状態になります。

ただ、これだけだとそんなにすぐに現象は発生しないので、以下のいずれかの状況が並行して起きている可能性が高いです。

  • ストレージが圧迫気味
  • 同じiCloudアカウントを複数の端末で使っている

ストレージが圧迫されていると、古いものから優先的に画像の実データをiCloudに飛ばされます。
また、同じiCloudアカウントを複数の端末で使っていて、別の端末で写真を撮影した場合にサムネイルだけ端末に存在する状況もあります。

なんでiOS11からこの現象が増えたの?

おそらく、iOS11からiCloudフォトライブラリを有効にするようにiOSのガイドが仕向けているのでは?と言う結論に至りました。
困ったものですね...

実はこの現象なかなか再現させるのに苦労して、同じチームのデバッグ力がすんごい人に見つけてもらいました!
感謝!!

解決策

PHImageRequestOptionsのisNetworkAccessAllowedを有効にする。
これをしないと、端末に画像のオリジナルがない場合は取得することができません。
(今まで気づかなかったw)

let options = PHImageRequestOptions()
options.isNetworkAccessAllowed = true

// open var isNetworkAccessAllowed: Bool // if necessary will download the image from iCloud (client can monitor or cancel using progressHandler). Defaults to NO (see start/stopCachingImagesForAssets)

PHImageManager.default().requestImage(for: asset, targetSize: imageSize, contentMode: .aspectFit, options: options, resultHandler: {
...
})

おまけ

iCloudに画像の実データがある時は、画像取得に時間がかかるので、取得できるまではサムネイルを表示したりするといいですね。

PHImageManager.default().requestImage(for: asset, targetSize: imageSize, contentMode: .aspectFit, options: options, resultHandler: {

  if let degraded = info?[PHImageResultIsDegradedKey] as? NSNumber, !degraded.boolValue {
     // NOTE: - 指定したサイズの画像が取得できます
  } else {
     // NOTE: - サムネイルが取得できます。(呼ばれない時もある)
  }
})

requestIdなるものが帰ってくるので、非同期で実装していい感じなUXを提供したいところです。

14
8
0

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
14
8