最近公司有個需求,需要緩存信息中要發送的照片,下次打開viewController的時候直接顯示照片。思路是在退出viewcontroller的時候儲存PHAsset,下一次打開那個viewController的時候通過PHAsset去加載這個圖片。
百度上搜索出的只有說需要儲存PHAsset的localIdentifier,實際上看完我也很蒙,并沒有人列出代碼說具體的做法。下面描述一下我的具體做法。
說在最前面,我確實是通過localIdentifier儲存PHAsset的。
點到PHAsset的頭文件里面會發現沒有localIdentifier這個屬性,這個時候你再往父類里點,也就是PHObject里,就會發現有了。
首先我們需要保存localIdentifier(如何存儲NSString這里就不說了):
NSString *localIdentifier = asset.localIdentifier;
// 本地存儲
把這個字符串存下來是沒有什么疑問了,然后下一次要怎么用呢?
PHFetchResult *fetchResult = [PHAsset fetchAssetsWithLocalIdentifiers:@[str] options:nil];
PHAsset *asset = fetchResult.firstObject;
上述這段代碼就可以根據localIdentifier返回PHAsset,但是先返回的是一個PHFetchResult類型的對象,這個對象是什么呢,點到頭文件里:
@interface PHFetchResult<ObjectType> : NSObject <NSCopying, NSFastEnumeration>
可以看出來他實現了NSCopying和NSFastEnumeration協議,也就是說他可以使用快速枚舉和copy方法,而且從它的屬性可以看出來它像是一個array。
+ (PHFetchResult<PHAsset *> *)fetchAssetsWithLocalIdentifiers:(NSArray<NSString *> *)identifiers options:(nullable PHFetchOptions *)options;
因為上述這個方法是要傳一個string泛型的數組進去,所以我傳一個進去實際上就拿到一個PHAsset。
所以
PHAsset *asset = fetchResult.firstObject;
PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
options.synchronous = YES;
[[PHImageManager defaultManager]requestImageForAsset:asset targetSize:CGSizeMake(asset.pixelWidth, asset.pixelHeight) contentMode:PHImageContentModeDefault options:options resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
[photos addObject:result];
}];
使用上述代碼就可以通過PHAsset再次拿到你上次拿到的照片了。
最后還有一個重點:
有時候用戶會把手機上的照片刪除了,如果刪除的包含APP里儲存的PHAsset,那么這種情況需要進行錯誤處理,不然會導致crash。在這種情況下使用fetchAssetsWithLocalIdentifiers這個方法返回的PHFetchResult為空,所以如下判斷即可:
PHAsset *asset = fetchResult.firstObject;
if (!asset) {
// 處理照片刪除的情況
}