最近公司有个需求,需要缓存信息中要发送的照片,下次打开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) {
// 处理照片删除的情况
}