工作原因主儡,需要處理接入一個(gè)視頻模塊暑诸,在視頻選擇的時(shí)候遇到了一個(gè)不太容易發(fā)現(xiàn)的bug,產(chǎn)生的原因是由于手機(jī)內(nèi)存小峰搪,而用戶又打開了相冊(cè)同步iCloud岔冀,
加載中的圖片
在這時(shí),如果本地可用內(nèi)存過小概耻,會(huì)導(dǎo)致
將本地相冊(cè)中的圖片或視頻刪除只留縮略圖使套,如果App調(diào)用的時(shí)候想要選取這種圖片就需要從iCloud云中進(jìn)行下載,
才能獲取原圖或原視頻鞠柄。
下面po下解決方案:
如果你之前處理過相冊(cè)問題侦高,那么對(duì)如下的代碼肯定不陌生,就是很普通的兩個(gè)系統(tǒng)級(jí)別的請(qǐng)求回調(diào)厌杜,獲取對(duì)應(yīng)的圖片奉呛,視頻。
// get Image
[[PHImageManager defaultManager] requestImageDataForAsset:asset options:nil resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) {
}];
// get Video
[[PHImageManager defaultManager] requestPlayerItemForVideo:asset options:nil resultHandler:^(AVPlayerItem * _Nullable playerItem, NSDictionary * _Nullable info) {
if (completion) completion(playerItem,info);
}];
但是往往之前沒有注意到第二個(gè)輸入 options
是用來干嘛的夯尽,
其實(shí)解決方案就來自于這個(gè) PHImageRequestOptions
瞧壮,PHVideoRequestOptions
。
這這兩個(gè) options
都有一個(gè)共同的參數(shù)就是
@property (nonatomic, assign, getter=isNetworkAccessAllowed) BOOL networkAccessAllowed;
// if necessary will download the image from iCloud (client can monitor or cancel using progressHandler). Defaults to NO (see start/stopCachingImagesForAssets)
系統(tǒng)的解釋也很詳細(xì)匙握,如果賦值 YES
咆槽,那么允許從 iCloud
中獲取圖片和視頻,默認(rèn)是 NO
肺孤。
雖然這個(gè)問題解決不是很難罗晕,但是往往容易被忽略济欢,所以記錄一下赠堵。
這里非常感謝@半遲塵大大的TZImagePickerController的源碼小渊,這個(gè)是一個(gè)非常靠譜的相冊(cè)選擇圖片視頻的庫(kù)茫叭,并且處于仍在維護(hù)中酬屉。感興趣的可以鏈接過去看一看源碼,寫的很好揍愁。
博主博客@HarwordLiu
下面po一下完整的這個(gè)問題的解決代碼:
/// Get Video
- (void)getVideoOutputPathWithAsset:(PHAsset *)asset completion:(void (^)(NSString *outputPath))completion {
PHVideoRequestOptions* options = [[PHVideoRequestOptions alloc] init];
options.version = PHVideoRequestOptionsVersionOriginal;
options.deliveryMode = PHVideoRequestOptionsDeliveryModeAutomatic;
options.networkAccessAllowed = YES;
[[PHImageManager defaultManager] requestAVAssetForVideo:asset options:options resultHandler:^(AVAsset* avasset, AVAudioMix* audioMix, NSDictionary* info){
// NSLog(@"Info:\n%@",info);
AVURLAsset *videoAsset = (AVURLAsset*)avasset;
// NSLog(@"AVAsset URL: %@",myAsset.URL);
[self startExportVideoWithVideoAsset:videoAsset completion:completion];
}];
}
/// Get Image
- (PHImageRequestID)getPhotoWithAsset:(PHAsset *)asset photoWidth:(CGFloat)photoWidth completion:(void (^)(UIImage *, NSDictionary *, BOOL isDegraded))completion {
PHAsset *phAsset = (PHAsset *)asset;
CGFloat aspectRatio = phAsset.pixelWidth / (CGFloat)phAsset.pixelHeight;
CGFloat pixelWidth = photoWidth * 2.0;
CGFloat pixelHeight = pixelWidth / aspectRatio;
CGSize imageSize = CGSizeMake(pixelWidth, pixelHeight);
// 修復(fù)獲取圖片時(shí)出現(xiàn)的瞬間內(nèi)存過高問題
PHImageRequestOptions *option = [[PHImageRequestOptions alloc] init];
option.resizeMode = PHImageRequestOptionsResizeModeFast;
PHImageRequestID imageRequestID = [[PHImageManager defaultManager] requestImageForAsset:asset targetSize:imageSize contentMode:PHImageContentModeAspectFill options:option resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
BOOL downloadFinined = (![[info objectForKey:PHImageCancelledKey] boolValue] && ![info objectForKey:PHImageErrorKey]);
if (downloadFinined && result) {
if (completion) completion(result,info,[[info objectForKey:PHImageResultIsDegradedKey] boolValue]);
}
// Download image from iCloud / 從iCloud下載圖片
if ([info objectForKey:PHImageResultIsInCloudKey] && !result) {
PHImageRequestOptions *option = [[PHImageRequestOptions alloc]init];
option.networkAccessAllowed = YES;
option.resizeMode = PHImageRequestOptionsResizeModeFast;
[[PHImageManager defaultManager] requestImageDataForAsset:asset options:option resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) {
UIImage *resultImage = [UIImage imageWithData:imageData scale:0.1];
if (completion) completion(resultImage,info,[[info objectForKey:PHImageResultIsDegradedKey] boolValue]);
}];
}
}];
return imageRequestID;
}