最近公司有個需求,需要快取資訊中要傳送的照片,下次開啟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) {
// 處理照片刪除的情況
}
複製程式碼