title: How do you get the attachment image from a local notification on the Apple Watch?
body: <p>My Objective-C iOS app schedules a local notification that has a userInfo dictionary and one small JPEG image attachment.</p>
  <p>The image is attached like this:</p>
  <pre><code>content.attachments = @[[UNNotificationAttachment attachmentWithIdentifier:myIdentifier 
                          URL:[imageURL filePathURL] 
                          options:@{UNNotificationAttachmentOptionsTypeHintKey : UTTypeJPEG} 
                          error:&amp;error]];
  </code></pre>
  <p>This works fine. The notification is correctly scheduled.</p>
  <p>If I ignore the Watch and let the notification appear on my phone's Lock Screen, the image is there.</p>
  <p>Going back to the Watch. The Watch app receives the notification, and the <code>didReceive</code> method is called in the <code>NotificationController</code>.</p>
  <p>No matter what I try, I can't get the image from the notification.</p>
  <p>I've tried converting the image to NSData and adding it to the userInfo dictionary, but the data is too large despite the image actually being only a few Kb.</p>
  <p>NotificationController.swift: (<code>image</code> is an <code>Image</code> type, and is sent to the <code>NotificationView</code> to use as the background.)</p>
  <pre><code>guard let attachment = notification.request.content.attachments.first
  else {
      print(&quot;Couldn't get the first attachment, using default image&quot;)
      image = Image.init(kDefaultImage)
      return
  }
  
  // We get here, so we know there's an attachment
  if attachment.url.startAccessingSecurityScopedResource() {
      let imageData = try? Data.init(contentsOf: attachment.url)
      if let imageData = imageData {
          image = Image(uiImage: UIImage(data: imageData) ?? 
                        UIImage.init(imageLiteralResourceName: kDefaultImageMasked))
      }
      attachment.url.stopAccessingSecurityScopedResource()
  
  } else {
      print(&quot;Couldn't access the file, using default&quot;)
      image = Image.init(kDefaultImageMasked)
  }
  </code></pre>
  <p>I always get told I can't access the file in the security scoped bit.</p>
  <p>If I take out that check I get <code>Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value</code> because the code doesn't put anything into <code>image</code>.</p>
  <p>Obviously I would put the default image in there instead of crashing, but once the Watch app crashes the notification that's shown on the Watch shows the correct image, but it's obviously not using my NotificationView because that crashed. It's using the standard mirror feature to show the notification, so it's completely bypassing my code at that point.</p>
  <p>I've also tried this:</p>
  <pre><code>if(attachment.url.isFileURL) {
      print(&quot;attachment image is a file url&quot;)
  }
  </code></pre>
  <p>It does print out that it's a file url, and it's: <code>file:///var/mobile/Library/BulletinDistributor/Attachments/com.mycompany.myapp/&lt;UUID&gt;.jpeg</code>.</p>
  <p>But this fails, so the file doesn't exist at that path, or I'm not allowed to load files from there (?):</p>
  <pre><code>if(FileManager.default.fileExists(atPath: attachment.url.path)) {
      ...
  </code></pre>
  <p>How do I get the image from the attachment? I've tried getting the image as <code>Data</code>, as an <code>Image</code>, as a <code>UIImage</code>. Nothing works.</p>
  <p>This was simple to do in the old Objective-C WatchKit extension stuff:</p>
  <pre><code>NSArray *attachments = notification.request.content.attachments;
  if(attachments.count == 1) {
      [_backgroundGroup setBackgroundImage:attachments[0]];
  }
  </code></pre>
  <p>No problems there; it always worked.</p>
  <p>Any ideas?</p>