ios - 如何使用 PHAssetResourceRequestOptions progressHandler/PHAssetResourceProgressHandler

标签 ios objective-c swift progress phasset

我正在尝试检索/下载 Live Photo 的视频/帧。 至于 API 文档,有一种可能的情况是 Live Photos 将存储在 iCloud 中。为了也检索它们,您需要声明

let options = PHAssetResourceRequestOptions()
        options.networkAccessAllowed = true  

我正在尝试在下载 Live Photo 时创建进度条。根据 API,您需要声明此属性:

public var progressHandler: PHAssetResourceProgressHandler?

progress    
A floating-point value indicating the progress of the download. 
A value of 0.0 indicates that the download has just started,
and a value of 1.0 indicates the download is complete. 

我还没有找到检索它们的正确方法。有什么建议吗?

完整代码:

 let assestResource = PHAssetResource.assetResourcesForAsset(asset)
 let options = PHAssetResourceRequestOptions()
 options.networkAccessAllowed = true
for assetRes in assestResource {
            print(assetRes.type.rawValue)
            if (assetRes.type == .PairedVideo) {
                print("imageTaken")
                manager.writeDataForAssetResource(assetRes, toFile: documentsURL,    options: options, completionHandler: { (error) -> Void in
                    if error == nil
                    {

                    }
                    else
                    {
                        print(error)
                    }
                })

最佳答案

是的,不幸的是,iCloud 下载 + PHAssetResourceManager 存在 Apple 错误。无论 Assets 类型如何,我都会收到以下错误:

Error: Missing resource download context

改为使用 PHImageManager。您需要对每种类型的 PHAsset 有一个独特的请求:

- (void)downloadAsset:(PHAsset *)asset toURL:(NSURL *)url completion:(void (^)(void))completion
{
    if (asset.mediaType == PHAssetMediaTypeImage && (asset.mediaSubtypes & PHAssetMediaSubtypePhotoLive))
    {
        PHLivePhotoRequestOptions *options = [PHLivePhotoRequestOptions new];
        options.networkAccessAllowed = YES;
        [[PHImageManager defaultManager] requestLivePhotoForAsset:asset targetSize:CGSizeZero contentMode:PHImageContentModeAspectFill options:options resultHandler:^(PHLivePhoto * _Nullable livePhoto, NSDictionary * _Nullable info) {
            if ([info objectForKey:PHImageErrorKey] == nil)
            {
                NSData *livePhotoData = [NSKeyedArchiver archivedDataWithRootObject:livePhoto];
                if ([[NSFileManager defaultManager] createFileAtPath:url.path contents:livePhotoData attributes:nil])
                {
                    NSLog(@"downloaded live photo:%@", url.path);
                    completion();
                }
            }
        }];
    }
    else if (asset.mediaType == PHAssetMediaTypeImage)
    {
        PHImageRequestOptions *options = [PHImageRequestOptions new];
        options.networkAccessAllowed = YES;
        [[PHImageManager defaultManager] requestImageDataForAsset:asset options:options resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) {
            if ([info objectForKey:PHImageErrorKey] == nil
                && [[NSFileManager defaultManager] createFileAtPath:url.path contents:imageData attributes:nil])
            {
                NSLog(@"downloaded photo:%@", url.path);
                completion();
            }
        }];
    }
    else if (asset.mediaType == PHAssetMediaTypeVideo)
    {
        PHVideoRequestOptions *options = [PHVideoRequestOptions new];
        options.networkAccessAllowed = YES;
        [[PHImageManager defaultManager] requestExportSessionForVideo:asset options:options exportPreset:AVAssetExportPresetHighestQuality resultHandler:^(AVAssetExportSession * _Nullable exportSession, NSDictionary * _Nullable info) {
            if ([info objectForKey:PHImageErrorKey] == nil)
            {
                exportSession.outputURL = url;

                NSArray<PHAssetResource *> *resources = [PHAssetResource assetResourcesForAsset:asset];
                for (PHAssetResource *resource in resources)
                {
                    exportSession.outputFileType = resource.uniformTypeIdentifier;
                    if (exportSession.outputFileType != nil)
                        break;
                }

                [exportSession exportAsynchronouslyWithCompletionHandler:^{
                    if (exportSession.status == AVAssetExportSessionStatusCompleted)
                    {
                        NSLog(@"downloaded video:%@", url.path);
                        completion();
                    }
                }];
            }
        }];
    }
}

关于ios - 如何使用 PHAssetResourceRequestOptions progressHandler/PHAssetResourceProgressHandler,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35241449/

相关文章:

ios - 如何根据坐标获得世界国家边界?

objective-c - 如何使用 block 和 Xcode 在新行上用大括号格式化源代码?

Swift 2.x -> String.fromCString 的 Swift 3.0 转换问题

ios - 解析和 Swift : How use advance targeting push to specific devices without users?

ios - Firebase Analytics - 禁用,从自动跟踪中排除一些屏幕。操作系统

ios - 有没有办法以编程方式从 ios 应用商店下载应用程序

ios - Apple MapkitcalculateETAWithCompletionHandler 通过数组循环

ios - 在 UIPopoverController 中移动框架

ios - 如何判断 CLLocationManager 何时锁定​​了用户位置

ios - 从 Controller 内的页面更改 PageViewController 中的页面?