My Objective-C iOS app schedules a local notification that has a userInfo dictionary and one small JPEG image attachment.
The image is attached like this:
content.attachments = @[[UNNotificationAttachment attachmentWithIdentifier:myIdentifier
URL:[imageURL filePathURL]
options:@{UNNotificationAttachmentOptionsTypeHintKey : UTTypeJPEG}
error:&error]];
This works fine. The notification is correctly scheduled.
If I ignore the Watch and let the notification appear on my phone's Lock Screen, the image is there.
Going back to the Watch. The Watch app receives the notification, and the didReceive
method is called in the NotificationController
.
No matter what I try, I can't get the image from the notification.
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.
NotificationController.swift: (image
is an Image
type, and is sent to the NotificationView
to use as the background.)
guard let attachment = notification.request.content.attachments.first
else {
print("Couldn't get the first attachment, using default image")
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("Couldn't access the file, using default")
image = Image.init(kDefaultImageMasked)
}
I always get told I can't access the file in the security scoped bit.
If I take out that check I get Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value
because the code doesn't put anything into image
.
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.
I've also tried this:
if(attachment.url.isFileURL) {
print("attachment image is a file url")
}
It does print out that it's a file url, and it's: file:///var/mobile/Library/BulletinDistributor/Attachments/com.mycompany.myapp/<UUID>.jpeg
.
But this fails, so the file doesn't exist at that path, or I'm not allowed to load files from there (?):
if(FileManager.default.fileExists(atPath: attachment.url.path)) {
...
How do I get the image from the attachment? I've tried getting the image as Data
, as an Image
, as a UIImage
. Nothing works.
This was simple to do in the old Objective-C WatchKit extension stuff:
NSArray *attachments = notification.request.content.attachments;
if(attachments.count == 1) {
[_backgroundGroup setBackgroundImage:attachments[0]];
}
No problems there; it always worked.
Any ideas?