问题
I have integrated APNS and want to display image in remote notification like below;
I have used below code with reference link;
AppDelegate.h
#import <UserNotifications/UserNotifications.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate,UNUserNotificationCenterDelegate>
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[self registerForRemoteNotification];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
UIViewController *vc1 = [storyboard instantiateViewControllerWithIdentifier:@"mainscreen"];
self.window.rootViewController = vc1;
return YES;
}
- (void)registerForRemoteNotification
{
if(SYSTEM_VERSION_GRATERTHAN_OR_EQUALTO(@"10.0")) {
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
[center requestAuthorizationWithOptions:(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge) completionHandler:^(BOOL granted, NSError * _Nullable error){
[[UIApplication sharedApplication] registerForRemoteNotifications];
}];
}
else {
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{
DeviceToken = [[NSString alloc]initWithFormat:@"%@",[[[deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]] stringByReplacingOccurrencesOfString:@" " withString:@""]];
NSLog(@"Device Token = %@",DeviceToken);
}
Then, I have created new target with UNNotificationServiceExtension and created new bundle id "com.RichPush.app.Service-Extension" , I have also created new certificate and provision profile with above bundle for UNNotificationServiceExtension.
NotificationService.h
#import <UserNotifications/UserNotifications.h>
@interface NotificationService : UNNotificationServiceExtension
@end
NotificationService.m
#import "NotificationService.h"
@interface NotificationService ()
@property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver);
@property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent;
@end
@implementation NotificationService
- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
self.contentHandler = contentHandler;
self.bestAttemptContent = [request.content mutableCopy];
// Modify the notification content here...
//self.bestAttemptContent.body = [NSString stringWithFormat:@"%@ [modified]", self.bestAttemptContent.body];
// check for media attachment, example here uses custom payload keys mediaUrl and mediaType
NSDictionary *userInfo = request.content.userInfo;
if (userInfo == nil) {
[self contentComplete];
return;
}
NSString *mediaUrl = userInfo[@"mediaUrl"];
NSString *mediaType = userInfo[@"mediaType"];
if (mediaUrl == nil || mediaType == nil) {
[self contentComplete];
return;
}
// load the attachment
[self loadAttachmentForUrlString:mediaUrl
withType:mediaType
completionHandler:^(UNNotificationAttachment *attachment) {
if (attachment) {
self.bestAttemptContent.attachments = [NSArray arrayWithObject:attachment];
}
[self contentComplete];
}];
}
- (void)serviceExtensionTimeWillExpire {
// Called just before the extension will be terminated by the system.
// Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
[self contentComplete];
}
- (void)contentComplete {
self.contentHandler(self.bestAttemptContent);
}
- (NSString *)fileExtensionForMediaType:(NSString *)type {
NSString *ext = type;
if ([type isEqualToString:@"image"]) {
ext = @"jpg";
}
return [@"." stringByAppendingString:ext];
}
- (void)loadAttachmentForUrlString:(NSString *)urlString withType:(NSString *)type completionHandler:(void(^)(UNNotificationAttachment *))completionHandler {
__block UNNotificationAttachment *attachment = nil;
NSURL *attachmentURL = [NSURL URLWithString:urlString];
NSString *fileExt = [self fileExtensionForMediaType:type];
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
[[session downloadTaskWithURL:attachmentURL
completionHandler:^(NSURL *temporaryFileLocation, NSURLResponse *response, NSError *error) {
if (error != nil) {
NSLog(@"%@", error.localizedDescription);
} else {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *localURL = [NSURL fileURLWithPath:[temporaryFileLocation.path stringByAppendingString:fileExt]];
[fileManager moveItemAtURL:temporaryFileLocation toURL:localURL error:&error];
NSError *attachmentError = nil;
attachment = [UNNotificationAttachment attachmentWithIdentifier:@"" URL:localURL options:nil error:&attachmentError];
if (attachmentError) {
NSLog(@"%@", attachmentError.localizedDescription);
}
}
completionHandler(attachment);
}] resume];
}
@end
I used below plist for service extension:
My Playload is;
{
"aps": {
"alert": {
"title": "title",
"body": "Your message Here",
"mutable-content": "1",
"category": "myNotificationCategory"
}
},
"mediaUrl": "https://upload.wikimedia.org/wikipedia/commons/thumb/2/2a/FloorGoban.JPG/1024px-FloorGoban.jpg",
"mediaType": "image"
}
Please let me know where I am wrong.
Thanks in Advance.
回答1:
You need to put the "mutable-content": "1", flag outside the "alert"-object in your payload.
回答2:
You have a mistake here:
Then, I have created new target with UNNotificationServiceExtension and created new bundle id "com.RichPush.app.Service-Extension" , I have also created new certificate and provision profile with above bundle for UNNotificationServiceExtension.
use UNNotificationContentExtension instead of UNNotificationServiceExtension
after create new target, xcode will create swift (obj- c) file and storyboard interface
I have a simple example on swift code, which load image and show on large push notification view
class NotificationViewController: UIViewController, UNNotificationContentExtension {
//image provided from storyboard
@IBOutlet weak var image: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any required interface initialization here.
}
func didReceive(_ notification: UNNotification) {
let userInfo = notification.request.content.userInfo
// get image url
// and load image here
}
}
From Apple doc:
UNNotificationServiceExtension Modifies the content of remote notifications before they are delivered to the user.
and
UNNotificationContentExtension Presents a custom interface for a delivered local or remote notification.
回答3:
Your notification payload should be like this:
aps = {
alert = {
body = Testing;
title = Dining;
};
badge = 1;
"content-available" = 1;
"mutable-content" = 1;
sound = "Bleep-Sound.wav";
};
}
Content-available and mutable-content should be outside the alert and also you should add the badge count too....
来源:https://stackoverflow.com/questions/41845900/display-image-in-notification-bar-with-remote-notificationrich-media-push-notif