I've been working on rich notification experience which has been introduced in iOS10 and stuck with passing images as attachments to UNNotificationContentExtension
.
Here's my ContentExtension:
class NotificationViewController: UIViewController, UNNotificationContentExtension {
@IBOutlet weak var attachmentImage: UIImageView!
func didReceive(_ notification: UNNotification) {
if let attachment = notification.request.content.attachments.first {
if attachment.url.startAccessingSecurityScopedResource() {
attachmentImage.image = UIImage(contentsOfFile: attachment.url.path)
attachment.url.stopAccessingSecurityScopedResource()
}
}
}
}
As a tutorial, I've been following Advanced Notifications video from WWDC.
I've checked - UIImage
I'm assigning to UIImageView:
nil
CGSize
(191x191)/var/mobile/Library/SpringBoard/PushStore/Attachments/<bundle of app>/<...>.png
Here's how I send local notification from the app:
let content = UNMutableNotificationContent()
content.title = "Sample title"
content.body = "Sample body"
content.categoryIdentifier = "myNotificationCategory"
let attachement = try! UNNotificationAttachment(identifier: "image",
url: Bundle.main.url(forResource: "cat", withExtension: "png")!,
options: nil)
content.attachments = [ attachement ]
let request = UNNotificationRequest(identifier:requestIdentifier, content: content, trigger: nil)
UNUserNotificationCenter.current().delegate = self
UNUserNotificationCenter.current().add(request){(error) in
if (error != nil){
}
}
"cat.png" is just a dummy resource I've added to proj.
As you can see, notification shows the pic, so I assume, that I'm sending it correctly, but in the expanded state(in NotificationViewController
) I've never succeed at showing the same image.
What am I doing wrong? Thanks!
When you create an UIImage with contentsOfFile
, the UIImage object reads the image header only, which indicates basic info, such as image size, etc.
So, try move stopAccessingSecurityScopedResource
to [NotificationViewController dealloc]
.
Or using following:
objective-c code:
NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
UIImage *image = [UIImage imageWithData:imageData];
swift code:
let imageData = NSData(contentsOf: attachment.url)
let image = UIImage(data: imageData! as Data)
There is no document saying that contentsOfFile
only reads the image header. But when I run the following code:
NSString *docFolderPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSString *pngPath = [docFolderPath stringByAppendingPathComponent:@"test.png"];
UIImage *image = [UIImage imageWithContentsOfFile:pngPath];
[[NSFileManager defaultManager] removeItemAtPath:pngPath error:nil];
imageView.image = image;
An error occurs:
ImageIO: createDataWithMappedFile:1322: 'open' failed '/Users/fanjie/Library/Developer/CoreSimulator/Devices/FFDFCA06-A75E-4B54-9FC2-8E2AAE3B1405/data/Containers/Data/Application/E2D26210-4A53-424E-9FE8-D522CFD4FD9E/Documents/test.png'
error = 2 (No such file or directory)
So I made a conclusion that UIImage contentsOfFile
only reads the image header.
Thanks to @jeffery ,
Here is the exact code for the image shown in the notification extension:
if let attachment = notification.request.content.attachments.first {
if attachment.url.startAccessingSecurityScopedResource() {
let data = NSData(contentsOfFile: attachment.url.path);
self. attachmentImage?.image = UIImage(data: data! as Data);
attachment.url.stopAccessingSecurityScopedResource()
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With