iOS的推送功能有本地推送和远程推送,此处完整描述一下本地推送的功能。当前iOS系统使用版本基本都已经超过iOS10,10以下的实现不再描述,也避免调用方法混淆。

简介

iOS的本地推送主要有两种用法,一种是App外推送,另一种是App内也推送。

前者可以视为后者的简单实现,关键在于是否实现UNUserNotificationCenterDelegate的协议。如果不实现该协议,则只有当App不在前台的时候,推送才会出现,如果推送的时候App是打开的,则推送不会发出。

此处我们先实现App外推送,再实现App内推送及通知点击回调功能,一步步拆分本地推送的相关功能,明确各个功能对应的模块。

此外,调用推送功能的时候需要引入头文件:

#import <UserNotifications/UserNotifications.h>

在使用推送相关代码时都需提前引入该头文件。

推送授权

要实现推送功能就需要先实现推送的授权功能,授权最好在AppDelegate的didFinishLaunchingWithOptions里实现。如果没有开启通知权限,则无法进行推送。

- (void)registerAPN {
    UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
    [center requestAuthorizationWithOptions:(UNAuthorizationOptionAlert + UNAuthorizationOptionSound) completionHandler:^(BOOL granted, NSError * _Nullable error) {
    }];
}

推送功能实现

如果只需要实现App外推送,到这里功能就足够了,获取通知权限并设置推送内容。

以下为发送通知代码:

- (void)addLocalAPNS {
    UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
    content.title = @"App推送";
    //content.subtitle = @"测试通知副标题";
    content.body = @"这是一条测试通知";
    content.sound = [UNNotificationSound defaultSound];
    // 添加自定义声音
    //content.sound = [UNNotificationSound soundNamed:@"alert.caf"];
    // 设置触发条件(如 5 秒后)及是否重复推送
    UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:5 repeats:NO];
    // 创建请求
    NSString *identifier = @"localNotification";
    UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:identifier content:content trigger:trigger];
    // 添加到通知中心
    [[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
        if (error) {
            NSLog(@"Failed to schedule notification: %@", error.localizedDescription);
        }
    }];
}

完整推送功能

要实现App开启的时候也进行推送及获取推送消息和点击通知后的回调,需设置及实现UNUserNotificationCenterDelegate协议。

设置代理

代理可一样放在didFinishLaunchingWithOptions方法处。

代理方法:

[UNUserNotificationCenter currentNotificationCenter].delegate = self;

实现协议方法

远程推送的内容也同样是在此处做处理,只是远程推送正常关联第三方比如极光等实现,此处不展开讨论。

处理前台收到通知的代理方法

当App打开时,收到推送,则该方法会调用,可以解析notification参数获取推送的内容并做对应处理。

具体代码:

-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
    completionHandler(UNNotificationPresentationOptionSound|UNNotificationPresentationOptionBadge|UNNotificationPresentationOptionAlert);
}
  • 此处可设置通知的样式,根据需要使用对应的UNNotificationPresentationOptions类,选择自己想要展示的通知类型。
  • 如果不需要展示通知,也可以使用UNNotificationPresentationOptionNone作为参数传入。

notification参数内容:

// 解析通知内容
UNNotificationContent *content = notification.request.content;
NSString *title = content.title;
NSString *body = content.body;
NSDictionary *userInfo = content.userInfo;

NSLog(@"Received Notification in foreground: %@", userInfo);
处理点击通知之后的代理方法

当用户点击顶部通知时,无论App在前台还是后台,该方法都会调用,此处同样可以解析response参数获取推送的相关信息,并做对应处理。正常点击通知跳转到对应的页面和功能都是在此处处理。

- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler {
    UNNotificationContent *content = response.notification.request.content;
    NSDictionary *userInfo = content.userInfo;
    NSLog(@"User tapped on notification: %@", userInfo);
    // 自定义行为(如跳转页面)
    if ([response.actionIdentifier isEqualToString:UNNotificationDefaultActionIdentifier]) {
        NSLog(@"Default action triggered");
        // 可以在这里跳转到具体页面
    }
    completionHandler();
}

response参数内容:

// 解析通知内容
UNNotificationContent *content = response.notification.request.content;
NSDictionary *userInfo = content.userInfo;
NSLog(@"User tapped on notification: %@", userInfo);

Lynx
206 声望3 粉丝

步步