ALAssetsLibrary assetForURL:在iOS 8.1的“我的照片stream”中总是返回零

此代码在iOS 7中运行良好,但在iOS 8.1中,位于“我的照片stream”专辑中的所有资源都不在结果块内。 (failureBlock不叫。)普通的专辑和共享相册工作得很好。

我尝试从接受的答案: 尝试从assetForURL中分配__block ALAsset时出错:resultBlock:

也就是说,我持有一个对ALAssetsLibrary对象的引用,监听ALAssetsLibraryChangedNotification事件(这不是偶然发生的,但是哦)。我确定我的应用程序有权访问照片,我在无线上,我在我的tableView中看到了照片的缩略图。 只是当我尝试使用assetForURL:加载它们时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!"); }]; 

有没有人看到这个问题?

我有同样的问题。 切换到照片框架在这一刻不是我的select,但幸运的是我find了一个解决方法。 您可能会发现这是一个很大的丑陋,我怀疑它可能会工作缓慢,当照片stream包含大量的照片,但总比没有好。

这个想法是枚举照片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(); } ]; } 

希望这可以帮助。

从iOS 8.0及更高版本开始,您必须使用Photos框架而不是Assets Library框架。

在这里输入图像说明

在iOS 8.1上使用iPad mini进行testing,您应该如何使用新的Photos Framework进行testing :

 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 }]; 

我已经做了一个观察,试图检索资产使用assetForURL 内writeImage toSavedPhotosAlbum成功块为同一资产将产生零(大部分时间)的资产。

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

等待1秒钟的工作,而等待只有300毫秒没有。 但是这当然会因为每个设备和情况而有所不同。

这并没有真正以令人满意的方式回答这个问题,但也许它帮助别人找出潜在的问题。

在任何地方都找不到任何答案之后,我创build了以下扩展名,它适用于iOS 8.2,但是我认为它理论上很慢。 尽pipe先前的评论之一说这是固定在iOS8.2testing版上,但现在iOS8.2已经发布,这个bug仍然存在。

 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 } } }