[image_picker] Check for failure in iOS metadata updates (#4215)

diff --git a/packages/image_picker/image_picker/CHANGELOG.md b/packages/image_picker/image_picker/CHANGELOG.md
index e7048c3..bd0a7a0 100644
--- a/packages/image_picker/image_picker/CHANGELOG.md
+++ b/packages/image_picker/image_picker/CHANGELOG.md
@@ -1,6 +1,7 @@
-## NEXT
+## 0.8.3
 
 * Move `ImagePickerFromLimitedGalleryUITests` to `RunnerUITests` target.
+* Improved handling of bad image data when applying metadata changes on iOS.
 
 ## 0.8.2
 
@@ -53,8 +54,8 @@
 ## 0.8.0
 
 * BREAKING CHANGE: Changed storage location for captured images and videos to internal cache on Android,
-to comply with new Google Play storage requirements. This means developers are responsible for moving 
-the image or video to a different location in case more permanent storage is required. Other applications 
+to comply with new Google Play storage requirements. This means developers are responsible for moving
+the image or video to a different location in case more permanent storage is required. Other applications
 will no longer be able to access images or videos captured unless they are moved to a publicly accessible location.
 * Updated Mockito to fix Android tests.
 
diff --git a/packages/image_picker/image_picker/example/ios/RunnerTests/MetaDataUtilTests.m b/packages/image_picker/image_picker/example/ios/RunnerTests/MetaDataUtilTests.m
index e1dbfad..54f9469 100644
--- a/packages/image_picker/image_picker/example/ios/RunnerTests/MetaDataUtilTests.m
+++ b/packages/image_picker/image_picker/example/ios/RunnerTests/MetaDataUtilTests.m
@@ -60,7 +60,7 @@
   NSString *tmpFile = [NSString stringWithFormat:@"image_picker_test.jpg"];
   NSString *tmpDirectory = NSTemporaryDirectory();
   NSString *tmpPath = [tmpDirectory stringByAppendingPathComponent:tmpFile];
-  NSData *newData = [FLTImagePickerMetaDataUtil updateMetaData:metaData toImage:dataJPG];
+  NSData *newData = [FLTImagePickerMetaDataUtil imageFromImage:dataJPG withMetaData:metaData];
   if ([[NSFileManager defaultManager] createFileAtPath:tmpPath contents:newData attributes:nil]) {
     NSData *savedTmpImageData = [NSData dataWithContentsOfFile:tmpPath];
     NSDictionary *tmpMetaData =
@@ -71,6 +71,14 @@
   }
 }
 
+- (void)testUpdateMetaDataBadData {
+  NSData *imageData = [NSData data];
+
+  NSDictionary *metaData = [FLTImagePickerMetaDataUtil getMetaDataFromImageData:imageData];
+  NSData *newData = [FLTImagePickerMetaDataUtil imageFromImage:imageData withMetaData:metaData];
+  XCTAssertNil(newData);
+}
+
 - (void)testConvertImageToData {
   UIImage *imageJPG = [UIImage imageWithData:ImagePickerTestImages.JPGTestData];
   NSData *convertedDataJPG = [FLTImagePickerMetaDataUtil convertImage:imageJPG
diff --git a/packages/image_picker/image_picker/ios/Classes/FLTImagePickerMetaDataUtil.h b/packages/image_picker/image_picker/ios/Classes/FLTImagePickerMetaDataUtil.h
index d5a20ff..72a36a5 100644
--- a/packages/image_picker/image_picker/ios/Classes/FLTImagePickerMetaDataUtil.h
+++ b/packages/image_picker/image_picker/ios/Classes/FLTImagePickerMetaDataUtil.h
@@ -27,7 +27,11 @@
 
 + (NSDictionary *)getMetaDataFromImageData:(NSData *)imageData;
 
-+ (NSData *)updateMetaData:(NSDictionary *)metaData toImage:(NSData *)imageData;
+// Creates and returns data for a new image based on imageData, but with the
+// given metadata.
+//
+// If creating a new image fails, returns nil.
++ (nullable NSData *)imageFromImage:(NSData *)imageData withMetaData:(NSDictionary *)metadata;
 
 // Converting UIImage to a NSData with the type proveide.
 //
diff --git a/packages/image_picker/image_picker/ios/Classes/FLTImagePickerMetaDataUtil.m b/packages/image_picker/image_picker/ios/Classes/FLTImagePickerMetaDataUtil.m
index 1419584..45bcaa7 100644
--- a/packages/image_picker/image_picker/ios/Classes/FLTImagePickerMetaDataUtil.m
+++ b/packages/image_picker/image_picker/ios/Classes/FLTImagePickerMetaDataUtil.m
@@ -49,16 +49,27 @@
   return metadata;
 }
 
-+ (NSData *)updateMetaData:(NSDictionary *)metaData toImage:(NSData *)imageData {
-  NSMutableData *mutableData = [NSMutableData data];
-  CGImageSourceRef cgImage = CGImageSourceCreateWithData((__bridge CFDataRef)imageData, NULL);
-  CGImageDestinationRef destination = CGImageDestinationCreateWithData(
-      (__bridge CFMutableDataRef)mutableData, CGImageSourceGetType(cgImage), 1, nil);
-  CGImageDestinationAddImageFromSource(destination, cgImage, 0, (__bridge CFDictionaryRef)metaData);
++ (NSData *)imageFromImage:(NSData *)imageData withMetaData:(NSDictionary *)metadata {
+  NSMutableData *targetData = [NSMutableData data];
+  CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)imageData, NULL);
+  if (source == NULL) {
+    return nil;
+  }
+  CGImageDestinationRef destination = NULL;
+  CFStringRef sourceType = CGImageSourceGetType(source);
+  if (sourceType != NULL) {
+    destination =
+        CGImageDestinationCreateWithData((__bridge CFMutableDataRef)targetData, sourceType, 1, nil);
+  }
+  if (destination == NULL) {
+    CFRelease(source);
+    return nil;
+  }
+  CGImageDestinationAddImageFromSource(destination, source, 0, (__bridge CFDictionaryRef)metadata);
   CGImageDestinationFinalize(destination);
-  CFRelease(cgImage);
+  CFRelease(source);
   CFRelease(destination);
-  return mutableData;
+  return targetData;
 }
 
 + (NSData *)convertImage:(UIImage *)image
diff --git a/packages/image_picker/image_picker/ios/Classes/FLTImagePickerPhotoAssetUtil.m b/packages/image_picker/image_picker/ios/Classes/FLTImagePickerPhotoAssetUtil.m
index ab88179..4c705fe 100644
--- a/packages/image_picker/image_picker/ios/Classes/FLTImagePickerPhotoAssetUtil.m
+++ b/packages/image_picker/image_picker/ios/Classes/FLTImagePickerPhotoAssetUtil.m
@@ -86,7 +86,11 @@
                                                 usingType:type
                                                   quality:imageQuality];
   if (metaData) {
-    data = [FLTImagePickerMetaDataUtil updateMetaData:metaData toImage:data];
+    NSData *updatedData = [FLTImagePickerMetaDataUtil imageFromImage:data withMetaData:metaData];
+    // If updating the metadata fails, just save the original.
+    if (updatedData) {
+      data = updatedData;
+    }
   }
 
   return [self createFile:data suffix:suffix];
diff --git a/packages/image_picker/image_picker/pubspec.yaml b/packages/image_picker/image_picker/pubspec.yaml
index e5ecfeb..f56250f 100755
--- a/packages/image_picker/image_picker/pubspec.yaml
+++ b/packages/image_picker/image_picker/pubspec.yaml
@@ -3,7 +3,7 @@
   library, and taking new pictures with the camera.
 repository: https://github.com/flutter/plugins/tree/master/packages/image_picker/image_picker
 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+image_picker%22
-version: 0.8.2
+version: 0.8.3
 
 environment:
   sdk: ">=2.12.0 <3.0.0"