iOS本地推送简介

序言

推送消息是APP中重要的一个部分,它可以在用户不打开APP的情况下,告知用户一些APP内的消息,甚至是进行一些简易操作。推送一般分为两种,本地推送远程推送。本篇文章主要介绍本地推送。

UserNotification

在iOS10中,苹果升级了推送系统,使推送不仅仅能显示文字,还能够显示更多类型的信息,以及进行操作。因此,苹果废弃了UILocalNotification等API,而改用UserNotification来实现推送的功能。

让我们先来看看UserNotification都由哪些部分组成。


UserNotifications库目录概览

从上至下依次来解释一下这些文件的作用。

  • NSString+UserNotifications.h
    该文件是NSString的Category,提供了一个方法用来将文本信息进行本地化处理。

  • UNError.h
    该文件定义了一个枚举类UNErrorCode,用来标示不同种类的错误。

  • UNNotification.h
    这个类是推送的基础类。

  • UNNotificationAction.h
    这个类定义了推送通知中的交互操作。
    它还有个子类UNTextNotificationAction,负责定义推送通知中的文本框。

  • UNNotificationAttachment.h
    这个类定义了推送通知中的附件。

  • UNNotificationCategory.h
    这个类定义了推送通知的类别,与UNNotificationAction搭配使用。

  • UNNotificationContent.h
    这个类定义了推送通知中的内容。
    它还有个子类UNMutableNotificationContent,是可变版本。

  • UNNotificationRequest.h
    这个类是用来发起推送请求的

  • UNNotificationResponse.h
    这个类是在推送的回调中用来返回一些信息的。

  • UNNotificationServiceExtension.h
    这个类是在收到远程推送后更改推送内容再向用户展示的。

  • UNNotificationSettings.h
    这个类定义了推送通知的详细设置,例如声音、弹窗、红点等。

  • UNNotificationSound.h
    这个类定义了推送通知的声音。

  • UNNotificationTrigger.h
    这个类定义了推送通知的触发器。
    它有个子类UNPushNotificationTrigger,定义了基于远程推送的触发器。
    它有个子类UNTimeIntervalNotificationTrigger,定义了基于定时器的触发器。
    它有个子类UNCalendarNotificationTrigger,定义了基于日期的触发器。
    它有个子类UNLocationNotificationTrigger,定义了基于位置的触发器。

  • UNUserNotificationCenter.h
    这个类定义了管理中心,管理所有推送通知的行为。

  • UserNotifications.apinotes
    包含了这个模块的一些注释,主要是方便swift调用框架时的映射。

  • UserNotifications.h
    该文件引入了上述头文件,方便外界引用。

实际应用

1. 获取用户授权
[[UNUserNotificationCenter currentNotificationCenter]requestAuthorizationWithOptions:UNAuthorizationOptionAlert|
                                                                                     UNAuthorizationOptionSound|
                                                                                     UNAuthorizationOptionBadge|
                                                                                     UNAuthorizationOptionCarPlay
                                                                   completionHandler:^(BOOL granted, NSError * _Nullable error) {
        //granted代表用户是否同意授权。
}];

UNAuthorizationOptions的定义如下,每一条的作用已经标在注释里

typedef NS_OPTIONS(NSUInteger, UNAuthorizationOptions) {
    UNAuthorizationOptionBadge   = (1 << 0),//是否可以更新App的小红点
    UNAuthorizationOptionSound   = (1 << 1),//是否可以播放声音
    UNAuthorizationOptionAlert   = (1 << 2),//是否可以显示消息
    UNAuthorizationOptionCarPlay = (1 << 3),//是否可以在车载模式下推送
    UNAuthorizationOptionCriticalAlert __API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) = (1 << 4),//是否可以播放警告消息的声音
    UNAuthorizationOptionProvidesAppNotificationSettings __API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) = (1 << 5),//是否可以显示推送设置的按钮
    UNAuthorizationOptionProvisional __API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) = (1 << 6),//是否为临时授权,临时授权下用户可以在收到推送的时候设置授权
    UNAuthorizationOptionAnnouncement __API_AVAILABLE(ios(13.0), watchos(6.0)) __API_UNAVAILABLE(macos, tvos) = (1 << 7),//是否允许Siri自动播报
} __API_AVAILABLE(macos(10.14), ios(10.0), watchos(3.0), tvos(10.0));
2. 带文字的通知
UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc]init];
content.title = [NSString localizedUserNotificationStringForKey:@"title" arguments:nil];
content.subtitle = [NSString localizedUserNotificationStringForKey:@"subtitle" arguments:nil];
content.body = [NSString localizedUserNotificationStringForKey:@"body" arguments:nil];
    
UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:10.0 
                                                                                                repeats:NO];
UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:@"identifier" 
                                                                      content:content 
                                                                      trigger:trigger];
[[UNUserNotificationCenter currentNotificationCenter]addNotificationRequest:request 
                                                      withCompletionHandler:^(NSError * _Nullable error) {
        
}];

显示效果如下

预览
3. 带图片的通知

在原有代码上额外添加下面几行

NSString *path = [[NSBundle mainBundle]pathForResource:@"TestImage" ofType:@"png"];
NSURL *URL = [NSURL fileURLWithPath:path];
UNNotificationAttachment *attachment = [UNNotificationAttachment attachmentWithIdentifier:@"attachment"
                                                                                      URL:URL
                                                                                  options:nil
                                                                                    error:nil];
content.attachments = @[attachment];

显示效果如下

预览
预览(长按后)
4. 带视频的通知

和带图片的通知是一样的创建方式

NSString *path = [[NSBundle mainBundle]pathForResource:@"TestVideo" ofType:@"mov"];
NSURL *URL = [NSURL fileURLWithPath:path];
UNNotificationAttachment *attachment = [UNNotificationAttachment attachmentWithIdentifier:@"attachment"
                                                                                      URL:URL
                                                                                  options:nil
                                                                                    error:nil];
content.attachments = @[attachment];

显示效果如下

预览
5. 推送声音设置
content.sound = [UNNotificationSound soundNamed:@"sound.caf"];//自定义声音
//or
content.sound = [UNNotificationSound defaultSound];//默认声音
//or
content.sound = [UNNotificationSound defaultCriticalSound];//默认警告声
6. UNNotificationAction
UNNotificationAction * action = [UNNotificationAction actionWithIdentifier:@"action" 
                                                                     title:@"action" 
                                                                   options:UNNotificationActionOptionForeground];
NSArray *actionArr = @[action];
UNNotificationCategory * categoryNotification = [UNNotificationCategory categoryWithIdentifier:@"categoryOperationAction"
                                                                                       actions:actionArr
                                                                             intentIdentifiers:@[]
                                                                                       options:UNNotificationCategoryOptionCustomDismissAction];
NSSet *categories = [NSSet setWithObject:categoryNotification];
[[UNUserNotificationCenter currentNotificationCenter]setNotificationCategories:categories];
content.categoryIdentifier = @"categoryOperationAction";

其中UNNotificationAction定义的是一个按钮,动作,UNNotificationCategory则相当于一组Action的容器,方便管理。

UNNotificationActionOptions的定义如下。

typedef NS_OPTIONS(NSUInteger, UNNotificationActionOptions) {
    // 该操作是否只能在一个已解锁的设备上执行
    UNNotificationActionOptionAuthenticationRequired = (1 << 0),
    // 该操作是否是一个破坏性的操作,例如删除
    UNNotificationActionOptionDestructive = (1 << 1),
    // 该操作是否会导致APP进入前台
    UNNotificationActionOptionForeground = (1 << 2),
} __API_AVAILABLE(macos(10.14), ios(10.0), watchos(3.0)) __API_UNAVAILABLE(tvOS);

UNNotificationCategoryOptions的定义如下。

typedef NS_OPTIONS(NSUInteger, UNNotificationCategoryOptions) {
    // 是否要让Dismiss的操作也通过UNUserNotificationCenter的delegate回调
    UNNotificationCategoryOptionCustomDismissAction = (1 << 0),
    // 是否可以在车载模式中出现
    UNNotificationCategoryOptionAllowInCarPlay __API_UNAVAILABLE(macos) = (1 << 1),
    // 是否要显示标题,即使用户已经设置不可预览通知
    UNNotificationCategoryOptionHiddenPreviewsShowTitle __API_AVAILABLE(macos(10.14), ios(11.0)) __API_UNAVAILABLE(watchos, tvos) = (1 << 2),
    // 是否要显示副标题,即使用户已经设置不可预览通知
    UNNotificationCategoryOptionHiddenPreviewsShowSubtitle __API_AVAILABLE(macos(10.14), ios(11.0)) __API_UNAVAILABLE(watchos, tvos) = (1 << 3),
    // 是否允许Siri自动播报
    UNNotificationCategoryOptionAllowAnnouncement __API_AVAILABLE(ios(13.0), watchos(6.0)) __API_UNAVAILABLE(macos, tvos) = (1 << 4),
} __API_AVAILABLE(macos(10.14), ios(10.0), watchos(3.0)) __API_UNAVAILABLE(tvOS);

显示效果如下

预览
7. UNTextInputNotifactionAction
UNTextInputNotificationAction *action = [UNTextInputNotificationAction actionWithIdentifier:@"textAction"
                                                                                      title:@"textAction"
                                                                                    options:UNNotificationActionOptionNone
                                                                       textInputButtonTitle:@"send"
                                                                       textInputPlaceholder:@"placeholder"];

剩余代码与UNNotificationAction的一样。

点击后会显示输入框,显示效果如下


预览
8. Action回调

Action的回调是通过UNNotificationDelegate中的方法返回的

- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
         withCompletionHandler:(void(^)(void))completionHandler {
    if ([response isKindOfClass:[UNTextInputNotificationResponse class]]) {
        UNTextInputNotificationResponse *textResponse = (UNTextInputNotificationResponse *)response;
        NSString *text = textResponse.userText;
        // text为用户输入的文本
    } else {
        if ([response.actionIdentifier isEqualToString:@"action"]) {
            // 此为标识符为action的操作
        }
    }
    completionHandler();
}

尾声

创建一个本地推送的基本流程就是这样,不过iOS上推送能做到的远不止如此。通过UserNotificationsUI库,开发者还可以自定义推送展开页面,限于篇幅,本篇文章就不作展开了。

你可能感兴趣的:(iOS本地推送简介)