web-dev-qa-db-ja.com

ALAssetsLibrary assetForURL:iOS 8.1の「マイフォトストリーム」の写真に対して常にnilを返す

このコードはiOS 7では問題なく機能しましたが、iOS 8.1では、「マイフォトストリーム」アルバムにあるすべてのアセットが結果ブロック内からnilになります。 (failureBlockは呼び出されません。)通常のアルバムと共有アルバムは問題なく機能します。

私は次の受け入れられた回答を試しました: assetForURL:resultBlock内から__block ALAssetを割り当てようとしてエラーが発生しました

つまり、ALAssetsLibraryオブジェクトへの参照を保持し、ALAssetsLibraryChangedNotificationイベントをリッスンしています(これは発生しませんが、まあ。)アプリに写真へのアクセス権限があることを確認しました。 m wi-fiの場合、tableViewに写真のサムネイルが表示されます。 assetForURL:でそれらをロードしようとしたときだけです。それらは常にnilです。

// example URL: assets-library://asset/asset.JPG?id=1ECB69B9-DC7A-45A7-B135-F43317D3412C&ext=JPG
[self.library assetForURL:[NSURL URLWithString:url] resultBlock:^(ALAsset *asset) {
    NSLog(@"Asset: %@", asset); // nil :(
} failureBlock:^(NSError *error) {
    NSLog(@"Failure, wahhh!");
}];

他の誰かがこの問題を見ていますか?

25
taber

私も同じ問題を抱えていました。現在のところ、写真フレームワークに切り替えることは選択肢ではありませんが、幸い、回避策を見つけました。見づらいかもしれませんが、フォトストリームに多くの写真が含まれていると、動作が遅くなる可能性がありますが、何もしないよりはましです。

アイデアは、フォトストリームアセットグループ内のすべてのアイテムを列挙し、必要なURLを各アイテムのURLと比較することです。幸いにも、それはまだ動作します。

私はこのようなメソッドを持っています(ライブラリは同じクラスのALAssetsLibraryプロパティです。このコード内で初期化する必要があるかもしれません):

- (void)loadItem:(NSURL *)url withSuccessBlock:(void (^)(void))successBlock andFailureBlock:(void (^)(void))failureBlock {

[library assetForURL:url
        resultBlock:^(ALAsset *asset)
        {
            if (asset){
                //////////////////////////////////////////////////////
                // SUCCESS POINT #1 - asset is what we are looking for 
                //////////////////////////////////////////////////////
                successBlock();
            }
            else {
                // On iOS 8.1 [library assetForUrl] Photo Streams always returns nil. Try to obtain it in an alternative way

                [library enumerateGroupsWithTypes:ALAssetsGroupPhotoStream
                                       usingBlock:^(ALAssetsGroup *group, BOOL *stop)
                 {
                     [group enumerateAssetsWithOptions:NSEnumerationReverse usingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
                         if([result.defaultRepresentation.url isEqual:url])
                         {
                             ///////////////////////////////////////////////////////
                             // SUCCESS POINT #2 - result is what we are looking for
                             ///////////////////////////////////////////////////////
                             successBlock();
                             *stop = YES;
                         }
                     }];
                 }

                                     failureBlock:^(NSError *error)
                 {
                     NSLog(@"Error: Cannot load asset from photo stream - %@", [error localizedDescription]);
                     failureBlock();

                 }];
            }

        }
        failureBlock:^(NSError *error)
        {
            NSLog(@"Error: Cannot load asset - %@", [error localizedDescription]);
            failureBlock();
        }
  ];
}

お役に立てれば。

30

IOS 8.0以降では、Appleはアセットライブラリフレームワークの代わりに写真フレームワークを使用することをお勧めします。

enter image description here

2
Ratan

AssetForURL writeImage toSavedPhotosAlbum成功ブロック内を使用してアセットを取得しようとすると、同じアセットでnil(ほとんどの場合)のアセットが生成されることがわかりました。

ただし、assetForURLでアセットを取得するしばらくしてから writeImage成功ブロックの実行が完了した場合、正しいアセットが生成されます。

1秒間待機しても動作しましたが、300ミリ秒しか待機しませんでした。ただし、これはもちろん、デバイスや状況によって異なります。

これは満足のいく方法で実際に質問に答えることはできませんが、おそらく他の誰かが根本的な問題を理解するのに役立ちます。

2
Thomas Hilbert

IOS 8.1のiPad miniでテストされています。これは、新しい Photos Framework で行う方法です。

NSURL *url = /* your asset url from the old ALAsset library prior to iOS 8 */
PHFetchResult<PHAsset *> *assets = [PHAsset fetchAssetsWithALAssetURLs:@[url]
                                                               options:nil];
assert(assets.count == 1);
PHAsset *asset = assets.firstObject;

[[PHImageManager defaultManager] requestImageForAsset:asset
                   targetSize:CGSizeMake(800, 800) // TODO: your target size
                  contentMode:PHImageContentModeDefault
                      options:nil
                resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info)
 {
     // Do whatever you want to the result
 }];
1
Yuchen Zhong