25

此代码在 iOS 7 中运行良好,但在 iOS 8.1 中,位于“我的照片流”相册中的所有资产在结果块中均为零。(不调用 failureBlock。)常规相册和共享相册工作得很好。

我尝试了以下接受的答案:尝试从assetForURL内部分配__block ALAsset时出错:resultBlock:

也就是说,我持有对 ALAssetsLibrary 对象的引用,监听ALAssetsLibraryChangedNotification事件(顺便说一句,这不会发生,但是哦。)我确保我的应用程序有权访问照片,我在 wi-fi,我在 tableView 中看到照片的缩略图很好。只是当我尝试加载它们时,assetForURL:它们总是为零。

// 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!");
}];

还有其他人看到这个问题吗?

4

5 回答 5

30

我有同样的问题。目前,切换到照片框架对我来说不是一个选择,但幸运的是我找到了一种解决方法。您可能会发现它非常丑陋,我怀疑当 Photo Stream 包含大量照片时它可能会运行缓慢,但总比没有好。

这个想法是枚举照片流资产组中的所有项目,并将必要的 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();
        }
  ];
}

希望这可以帮助。

于 2014-10-23T10:31:47.083 回答
2

从 iOS 8.0 及更高版本开始,Apple 建议使用 Photos 框架而不是 Assets Library 框架。

在此处输入图像描述

于 2014-10-21T06:56:20.013 回答
2

我观察到,尝试在 writeImage toSavedPhotosAlbum 成功块中使用assetForURL 检索同一资产的资产将产生零资产(大多数情况下)。

但是,在 writeImage 成功块完成执行后的某个时间使用assetForURL 检索资产确实会产生正确的资产。

等待 1 秒确实有效,而仅等待 300 毫秒则没有。但这对于每种设备和情况当然会有所不同。

这并不能真正以令人满意的方式回答问题,但也许它可以帮助其他人找出潜在的问题。

于 2017-11-28T13:49:57.527 回答
1

在 iOS 8.1 上使用 iPad mini 进行了测试,这就是你应该如何使用新的照片框架

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
 }];
于 2016-02-18T16:16:56.380 回答
-1

在任何地方都没有找到任何答案后,我为 PHAsset 创建了以下扩展,它在 iOS 8.2 中运行良好,尽管我认为它在理论上很慢。尽管先前的评论之一说这已在 iOS8.2 测试版中修复,但现在 iOS8.2 发布后,我仍然存在该错误。

import Photos
import UIKit

extension PHAsset {
    class func fetchAssetWithALAssetURL (alURL: NSURL) -> PHAsset? {
        let phPhotoLibrary = PHPhotoLibrary.sharedPhotoLibrary()
        let assetManager = PHImageManager()
        var phAsset : PHAsset?

        let optionsForFetch = PHFetchOptions()
        optionsForFetch.includeHiddenAssets = true

        var fetchResult = PHAsset.fetchAssetsWithALAssetURLs([alURL], options: optionsForFetch)
        if fetchResult?.count > 0 {
            return fetchResult[0] as? PHAsset
        } else {
            var str = alURL.absoluteString!
            let startOfString = advance(find(str, "=")!, 1)
            let endOfString = advance(startOfString, 36)
            let range = Range<String.Index>(start:startOfString, end:endOfString)
            let localIDFragment = str.substringWithRange(range)
            let fetchResultForPhotostream = PHAssetCollection.fetchAssetCollectionsWithType(PHAssetCollectionType.Album, subtype: PHAssetCollectionSubtype.AlbumMyPhotoStream, options: nil)
            if fetchResultForPhotostream?.count > 0 {
                let photostream = fetchResultForPhotostream![0] as PHAssetCollection
                let fetchResultForPhotostreamAssets = PHAsset.fetchAssetsInAssetCollection(photostream, options: optionsForFetch)
                if fetchResultForPhotostreamAssets?.count >= 0 {
                    var stop : Bool = false
                    for var i = 0; i < fetchResultForPhotostreamAssets.count && !stop; i++ {
                        let phAssetBeingCompared = fetchResultForPhotostreamAssets[i] as PHAsset
                        if phAssetBeingCompared.localIdentifier.rangeOfString(localIDFragment, options: nil, range: nil, locale: nil) != nil {
                            phAsset = phAssetBeingCompared
                            stop = true
                        }
                    }
                    return phAsset
                }
            }
            return nil
        }
    }
}
于 2015-03-17T06:08:22.100 回答