Сохранение изображения в библиотеку фотографий с использованием фоторамки
Мое приложение вылетает каждый раз, когда я пытаюсь сохранить изображение с помощью фоторамки.
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
_mChangeRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:[info valueForKey:UIImagePickerControllerOriginalImage]];
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
_mChangeRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:[info valueForKey:UIImagePickerControllerOriginalImage]];
} completionHandler:^(BOOL success, NSError *error) {
if (success) {
PHObjectPlaceholder *assetPlaceholder = _mChangeRequest.placeholderForCreatedAsset;
}
else {
NSLog(@"write error : %@",error);
}
}];
}
crash : NSInternalInconsistencyException', reason: 'This method can only be called from inside of -[PHPhotoLibrary performChanges:completionHandler:] or -[PHPhotoLibrary performChangesAndWait:error:]'
4 ответа
Все, что вам нужно сделать, это вызвать запрос на создание. Как говорится в ошибке, вы можете получить доступ к запросу на изменение только внутри performChanges
блок.
Чтобы сохранить изображение, вы должны сделать что-то вроде этого:
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
[PHAssetChangeRequest creationRequestForAssetFromImage:[info valueForKey:UIImagePickerControllerOriginalImage]];
} completionHandler:^(BOOL success, NSError *error) {
if (success) {
NSLog(@"Success");
}
else {
NSLog(@"write error : %@",error);
}
}];
Если вам нужно что-то сделать с заполнителем вновь созданного актива, вы можете получить к нему доступ в том же performChanges
блок:
PHAssetChangeRequest *changeRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:[info valueForKey:UIImagePickerControllerOriginalImage]];
PHObjectPlaceholder *assetPlaceholder = changeRequest.placeholderForCreatedAsset;
В Swift 3 я делаю это, чтобы сохранить видео в библиотеке.
if mediaType.isEqual(to: (kUTTypeMovie as NSString) as String) {
if let videoURL = info[UIImagePickerControllerMediaURL] as? URL {
PHPhotoLibrary.shared().performChanges({
_ = PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: videoURL)
}, completionHandler: { (success, error) in
if success {
print("ok")
let videoData = NSData(contentsOf: videoURL)
// use videoData here if needed...
if let posterImage = self.firstFrame(videoURL: videoURL) {
self.imageView.image = posterImage
}
picker.dismiss(animated: true) { () -> Void in
}
}
else {
print(error?.localizedDescription)
}
})
}
}
Вот пример кода, как вы можете написать / сохранить изображение в библиотеке фотографий, используя UIImageWriteToSavedPhotosAlbum
функция:
- (void)saveImage:(UIImage *)image {
UIImageWriteToSavedPhotosAlbum(self.image, self, @selector(image:didFinishSavingWithError:contextInfo:), NULL);
}
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo;
{
if (!error) {
// saved successfully
PHFetchOptions *fetchOptions = [PHFetchOptions new];
fetchOptions.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:NO]];
PHAsset *asset = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:fetchOptions].firstObject;
if (asset != nil) {
// here you can use asset of your image
}
} else {
NSLog(@"save image error: %@", error);
}
}
Не забудьте добавить в свой Info.plist
пара ключ-значение Privacy - Camera Usage Description
с описанием использования.
- удалить третью строку кода
- Убедитесь, что _mChangeRequest является переменной __block
- скомпилировать и запустить
вы увидите это изображение в приложении фотографий
Вы измените код, вероятно, так...
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
__block PHAssetChangeRequest *_mChangeRequest = nil;
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
_mChangeRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:[info valueForKey:UIImagePickerControllerOriginalImage]];
} completionHandler:^(BOOL success, NSError *error) {
if (success) {
PHObjectPlaceholder *assetPlaceholder = _mChangeRequest.placeholderForCreatedAsset;
}
else {
NSLog(@"write error : %@",error);
}
}];
}