PhotoKit是iOS8出的一个新的照片库,用以取代AssetsLibrary
保存图片到相册
- 方式1:只能保存UIImage
// Add it to the photo library.
PHPhotoLibrary.shared().performChanges({
PHAssetChangeRequest.creationRequestForAsset(from: image)
}, completionHandler: {success, error in
if !success { print(error ?? "") }
})
问题:保存图片到某个相册中,按照苹果推荐的做法结果却始终保存失败
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetChangeRequest *createAssetRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:image];
PHObjectPlaceholder *assetPlaceholder = createAssetRequest.placeholderForCreatedAsset;
PHAssetCollectionChangeRequest *albumChangeRequest =
[PHAssetCollectionChangeRequest changeRequestForAssetCollection:self.cameraRollAlbum];
[albumChangeRequest addAssets:@[assetPlaceholder]];
} completionHandler:^(BOOL success, NSError * _Nullable error) {
if (success) {
NSLog(@"保存成功");
}else {
NSLog(@"error:%@",error);
}
}];
,不知为何,self.cameraRollAlbum表示相机胶卷这个相册,之后查看了苹果官方的demo,豁然开朗,原来这个相册是不能添加asset(图片或者视频)的.
用户创建的自定义相册是可以添加的,苹果创建的系统相册(相机胶卷、最近添加...)是不可以添加的,可以通过PHCollection的下面这个方法判断:
assetCollection.canPerform(.addContent)
- 方式2:iOS9新出的方法,保存图片的data数据
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
[[PHAssetCreationRequest creationRequestForAsset] addResourceWithType:PHAssetResourceTypePhoto data:imageData options:nil];
} completionHandler:^(BOOL success, NSError * _Nullable error) {
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"%d,%@",success,error);
});
}];
补充:如果需要保存图片的NSData数据,通过方式2可以做到,但是这个方法只有iOS9后才有,如果需要支持iOS8,需要利用旧版的AssetsLibrary去处理
监听相册的变化
通过实现下面这个代理去监听,注意:这个代理并不是在主队列中执行的,而是一个内部的串行队列中执行,如果要更新UI,要派发到主队列中
@protocol PHPhotoLibraryChangeObserver <NSObject>
// This callback is invoked on an arbitrary serial queue. If you need this to be handled on a specific queue, you should redispatch appropriately
- (void)photoLibraryDidChange:(PHChange *)changeInstance;
@end
发现个奇怪的问题,保存图片的时候发现这个代理方法会调用多次,这并不是bug,可能苹果出于某种原因导致的,所以千万不要暴力的在这个代理回调里重新reload所有数据源,这么做会比较耗费CPU和内存,而应该通过代理的参数changeInstance去做判断更新指定的相册的变化