iOS基于Firebase+Objective-C实现通知栏图片推送(富推送)问题咨询
用Firebase + Objective-C实现iOS富推送(通知栏显示图片)
嘿,我之前刚搞定过类似的需求,咱们一步步拆解怎么让你的通知栏显示图片。iOS 10+的富推送核心是用Notification Service Extension来修改推送内容,结合Firebase的推送配置就能实现,具体步骤如下:
一、添加Notification Service Extension到项目
首先得给项目加个通知服务扩展,这个扩展会在推送到达时被系统调用,用来下载图片并修改通知内容:
- 打开Xcode,选菜单栏的
File > New > Target - 在模板里找到Notification Service Extension,点击Next
- 给扩展起个名字(比如
ImageNotificationExtension),语言选Objective-C,然后Finish - 弹出是否激活方案的提示,选Activate就行
二、配置Firebase推送的Payload
要让系统触发扩展处理,推送的payload必须包含mutable-content: 1,同时要带上图片的URL。不管你是用Firebase控制台发送,还是用API调用,APNs的payload格式要像这样:
{ "aps": { "alert": { "title": "富推送测试", "body": "看看这张图片!" }, "sound": "default", "mutable-content": 1 }, "attachment-url": "https://你的图片地址.jpg" }
注意:
attachment-url是我们自定义的字段,用来传递图片URL,后面在扩展里会读取这个字段。
三、修改Notification Service Extension的代码
打开扩展的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]; // 读取自定义的图片URL字段 NSString *imageURLString = self.bestAttemptContent.userInfo[@"attachment-url"]; if (imageURLString && ![imageURLString isEqualToString:@""]) { NSURL *imageURL = [NSURL URLWithString:imageURLString]; // 下载图片 NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithURL:imageURL completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { if (!error) { // 保存图片到临时目录 NSString *tempDir = NSTemporaryDirectory(); NSString *filePath = [tempDir stringByAppendingPathComponent:@"notification_image.jpg"]; [data writeToFile:filePath atomically:YES]; // 创建通知附件 NSError *attachmentError = nil; UNNotificationAttachment *attachment = [UNNotificationAttachment attachmentWithIdentifier:@"image" URL:[NSURL fileURLWithPath:filePath] options:nil error:&attachmentError]; if (!attachmentError && attachment) { self.bestAttemptContent.attachments = @[attachment]; } } // 交付修改后的通知内容 self.contentHandler(self.bestAttemptContent); }]; [task resume]; } else { // 没有图片URL,直接交付原内容 self.contentHandler(self.bestAttemptContent); } } - (void)serviceExtensionTimeWillExpire { // 超时处理,交付原内容 self.contentHandler(self.bestAttemptContent); } @end
代码里的注意点:
- 确保图片的扩展名和实际格式一致(比如用
.png如果是PNG图片) - 临时文件要正确保存,否则附件创建会失败
- 处理超时情况:如果下载图片超时,要调用
contentHandler交付原内容,避免通知丢失
四、主App的配置
在你的主App的AppDelegate.m里,要确保正确配置通知权限和UserNotifications代理:
#import <UserNotifications/UserNotifications.h> #import <FirebaseMessaging/FirebaseMessaging.h> @interface AppDelegate () <UNUserNotificationCenterDelegate, FIRMessagingDelegate> @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // 初始化Firebase [FIRApp configure]; // 配置UserNotifications UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; center.delegate = self; // 请求通知权限 [center requestAuthorizationWithOptions:(UNAuthorizationOptionAlert | UNAuthorizationOptionSound | UNAuthorizationOptionBadge) completionHandler:^(BOOL granted, NSError * _Nullable error) { if (granted) { [[UIApplication sharedApplication] registerForRemoteNotifications]; } }]; // 设置Firebase Messaging代理 [FIRMessaging messaging].delegate = self; return YES; } // iOS 10+ 前台收到通知的处理(可选) - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler { completionHandler(UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionSound | UNNotificationPresentationOptionBadge); } // 点击通知的处理(可选) - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)(void))completionHandler { completionHandler(); } @end
五、测试注意事项
- 必须用真机测试,模拟器对富推送的支持有限
- 确保你的推送证书包含了扩展的权限(Xcode会自动处理,但如果遇到问题可以检查证书配置)
- 图片URL必须是HTTPS的,或者在主App和扩展的
Info.plist里配置ATS例外(不推荐,尽量用HTTPS) - 如果测试时推送没显示图片,检查控制台日志,看扩展是否被调用,有没有下载错误
这样一套下来,你的通知栏就能正常显示图片啦!
内容的提问来源于stack exchange,提问作者Sibin Francis
相关产品推荐
相关产品推荐

