title: IOS: Writing EXIF to ImageData not Reflecting unless I append data to original EXIF Dictionary fetched from ImageData
body: <p>I am working on a camera app. I want to append DateTimeOriginal &amp; DateTimeDigitized to the exif metadata. I have created Swift category Class for getting and saving Exif.</p>
  
  <pre><code>import ImageIO
  
  extension NSData {
  
      func exifNSDict() -&gt; NSDictionary? {
          return _exifCFDict() as NSDictionary?
      }
  
      func exifCFDict() -&gt; CFDictionaryRef? {
          return _exifCFDict()
      }
  
      func imageNSUTI() -&gt; NSString? {
          return _imageUTI() as NSString?
      }
  
      func imageCFUTI() -&gt; CFStringRef? {
          return _imageUTI()
      }
  
      func appendExif(exif: CFDictionaryRef) -&gt; NSData? {
          return _appendExif(exif)
      }
  }
  
  //MARK: - Private
  
  extension NSData {
  
      private func _exifCFDict() -&gt; CFDictionaryRef? {
  
          //1.(a) Create original image source ref
          let imageSource: CGImageSourceRef? =      CGImageSourceCreateWithData(self, nil)
  
          if imageSource == nil {
              return nil
          }
  
          //1.(b) Get image properties
          let imageProperties: CFDictionaryRef? = CGImageSourceCopyPropertiesAtIndex(imageSource!, 0, nil)
  
          if imageProperties == nil {
              return nil
          }
  
          //1.(b) Get original exif
          let dictKey = unsafeBitCast(kCGImagePropertyExifDictionary, UnsafePointer&lt;Void&gt;.self)
          let exif: CFDictionaryRef? = unsafeBitCast(CFDictionaryGetValue(imageProperties, dictKey), CFDictionaryRef.self)
  
          if exif == nil {
              return nil
          }
  
          return exif
      }
  
      private func _imageUTI() -&gt; CFStringRef? {
  
          let imageSource: CGImageSourceRef? = CGImageSourceCreateWithData(self, nil)
  
          if imageSource == nil {
              return nil
          }
  
          let imageUTI: CFStringRef? = CGImageSourceGetType(imageSource!)
  
          return imageUTI
      }
  
      private func _appendExif(exif: CFDictionaryRef) -&gt; NSData? {
  
          //writing both original image data and mutable exif back to a destination
          let imageSource: CGImageSourceRef? = CGImageSourceCreateWithData(self, nil)
  
          if imageSource == nil {
              return nil
          }
  
          let imageUTI: CFStringRef? = CGImageSourceGetType(imageSource!)
  
          if imageUTI == nil {
              return nil
          }
  
          //3. create a mutable data object to which the originalImageData and exif dictionary will be written.
          let finalCombinedData = NSMutableData()
  
          //4. create a destination object where the whole thing needs to be written
          let destination : CGImageDestinationRef? = CGImageDestinationCreateWithData(finalCombinedData, imageUTI!, 1, nil)
  
          if destination == nil {
              return nil
          }
  
          //5. This is the actual method that does the writing.
          CGImageDestinationAddImageFromSource(destination!, imageSource!, 0, exif);
  
          //6. Commit the writing
          let success = CGImageDestinationFinalize(destination!);
  
          if !success {//error
              return nil
          }
  
          return finalCombinedData.copy() as? NSData
      }
  }
  </code></pre>
  
  <p>Now I am able to get exif by calling exifCFDict</p>
  
  <pre><code>CFDictionaryRef exif = [imageData exifCFDict];
  </code></pre>
  
  <p>I then created a MutableCFDictionaryRef from this CFDictionaryRef, and appended values for kCGImagePropertyExifDateTimeOriginal and kCGImagePropertyExifDateTimeDigitized as follows:</p>
  
  <pre><code>1.(b) Convert original exif to mutable exif                                                            
  CFMutableDictionaryRef mutableExif = CFDictionaryCreateMutableCopy(NULL, 0, exif);
  NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
                                                           [formatter setDateFormat:@"yyyy:MM:dd HH:mm:ss"];
  NSString *nowDateStr = [formatter stringFromDate:[[NSDate alloc] init]];
  CFDictionarySetValue(mutableExif, kCGImagePropertyExifDateTimeOriginal, (__bridge const void *)nowDateStr);
  CFDictionarySetValue(mutableExif, kCGImagePropertyExifDateTimeDigitized, (__bridge const void *)nowDateStr);
  </code></pre>
  
  <p>I can see kCGImagePropertyExifDateTimeOriginal and kCGImagePropertyExifDateTimeDigitized in the mutable copy.
  I then tried to write this mutable dictionary to the imageData by calling the appendExif function in above category.</p>
  
  <pre><code>//append exif to originalImageData
  NSData *imageDataWithExif = [imageData appendExif:mutableExif];
  </code></pre>
  
  <p>However, when I tried to get exif from imageDataWithExif, I realized that kCGImagePropertyExifDateTimeOriginal &amp; kCGImagePropertyExifDateTimeDigitized are missing. All other info is present.</p>
  
  <p>After some hit and tries, I found a workaround. If instead of creating a mutable copy for exif, I just appended kCGImagePropertyExifDateTimeDigitized &amp; kCGImagePropertyExifDateTimeOriginal to original Exif fetched from Image Data and then if I pass this original exif to appendExif function, kCGImagePropertyExifDateTimeOriginal and kCGImagePropertyExifDateTimeDigitized are present in the new imageData.</p>
  
  <pre><code>CFDictionarySetValue(exif, kCGImagePropertyExifDateTimeOriginal, (__bridge const void *)nowDateStr);
  CFDictionarySetValue(exif, kCGImagePropertyExifDateTimeDigitized, (__bridge const void *)nowDateStr);
  
  //append exif to originalImageData
  NSData *imageDataWithExif = [imageData exif];
  </code></pre>
  
  <p>This has solved my problem for now, but this workaround has left me baffled.</p>
  
  <ul>
  <li>How am I able to append key values to a CFDictionaryRef?</li>
  <li>Why is it that unless I pass the original exif dictionary object that is obtained from the image data, my changes to the dictionary are getting ignored. </li>
  </ul>
  
  <p>P.S. I am fairly new to IOS development.</p>