[iOS] 通知详解:iOS 10 UserNotifications API

通知相关系列文章
iOS10 之前通知使用介绍
[iOS] 通知详解: UIUserNotification
iOS10 相关API
[iOS] 通知详解:iOS 10 UserNotifications API
iOS10 本地/远程通知
[iOS] 通知详解: iOS 10 UserNotifications
iOS10 通知附加包
[iOS] 通知详解: iOS 10 UserNotifications – 附加包Media Attachments
iOS10 自定义UI
[iOS] 通知详解: iOS 10 UserNotifications – 自定义通知UI

iOS 10中引入 UserNotifications ,用来取代之前的通知处理方式,并增加了很多新的特性,来丰富通知的功能,使用时需要引入 UserNotifications 头文件,并遵循协议 UNUserNotificationCenterDelegate

import UserNotifications

由于UserNotifications的内容较多,开始写在一篇文章进行介绍,导致文章篇幅过长,所以进行了简单拆分,本文主要是介绍常用的一些API,如果想直接看使用方法,可以跳过,不清楚的再回来查看有无相关的介绍。

相关类库介绍

UserNotifications 模块主要涉及到以下一些类库

用户通知中心 UNUserNotificationCenter

主要管理通知相关的调度,添加,其相关的属性和方法如下

// The delegate can only be set from an application 代理
    weak open var delegate: UNUserNotificationCenterDelegate?
 // 当前设备是否支持的扩展
    // Returns YES if the current device supports content extensions
    open var supportsContentExtensions: Bool { get }

    // 获取当前的通知中心(单例)
    // The UNUserNotificationCenter for the current application
    open class func current() -> UNUserNotificationCenter

    // 请求通知的权限,参数为 UNAuthorizationOptions 的集合
    // User authorization is required for applications to notify the user using UNUserNotificationCenter via both local and remote notifications.
    open func requestAuthorization(options: UNAuthorizationOptions = [], completionHandler: @escaping (Bool, Error?) -> Void)

    // 通知快捷操作action集合,参数为 UNNotificationCategory的集合
    // Notification categories can be used to choose which actions will be displayed on which notifications.
    open func setNotificationCategories(_ categories: Set<UNNotificationCategory>)
// 获取当前添加的 Categories
    open func getNotificationCategories(completionHandler: @escaping (Set<UNNotificationCategory>) -> Void)

    // 获取通知当前的设置,详见 UNNotificationSettings
    // The application's user notification settings
    open func getNotificationSettings(completionHandler: @escaping (UNNotificationSettings) -> Void)

    // 添加通知的请求
    // Notification requests can be scheduled to notify the user via time and location. See UNNotificationTrigger for more information. Calling -addNotificationRequest: will replace an existing notification request with the same identifier. A notification request with the identifier as an existing delivered notifications will alert for the new notification request and replace the existing delivered notification when it is triggered. The number of pending notification requests that may be scheduled by an application at any one time is limited by the system.
    open func add(_ request: UNNotificationRequest, withCompletionHandler completionHandler: ((Error?) -> Void)? = nil)

    // 获取所有等待执行的通知请求
    // Notification requests that are waiting for their trigger to fire
    open func getPendingNotificationRequests(completionHandler: @escaping ([UNNotificationRequest]) -> Void)
// 取消未执行的通知请求
    open func removePendingNotificationRequests(withIdentifiers identifiers: [String])
// 取消所有未执行的通知请求
    open func removeAllPendingNotificationRequests()

    // 获取已添加到通知中心的通知
    // Notifications that have been delivered and remain in Notification Center. Notifications triggered by location cannot be retrieved, but can be removed.
    open func getDeliveredNotifications(completionHandler: @escaping ([UNNotification]) -> Void)
// 移除通知
    open func removeDeliveredNotifications(withIdentifiers identifiers: [String])

    open func removeAllDeliveredNotifications()

通知中心协议 UNUserNotificationCenterDelegate

其中主要有三个协议方法

// The method will be called on the delegate only if the application is in the foreground. If the method is not implemented or the handler is not called in a timely manner then the notification will not be presented. The application can choose to have the notification presented as a sound, badge, alert and/or in the notification list. This decision should be based on whether the information in the notification is otherwise visible to the user.
    @available(iOS 10.0, *)
    optional public func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void)

    
    // The method will be called on the delegate when the user responded to the notification by opening the application, dismissing the notification or choosing a UNNotificationAction. The delegate must be set before the application returns from application:didFinishLaunchingWithOptions:.
    @available(iOS 10.0, *)
    optional public func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void)

    
    // The method will be called on the delegate when the application is launched in response to the user's request to view in-app notification settings. Add UNAuthorizationOptionProvidesAppNotificationSettings as an option in requestAuthorizationWithOptions:completionHandler: to add a button to inline notification settings view and the notification settings view in Settings. The notification will be nil when opened from Settings.
    @available(iOS 12.0, *)
    optional public func userNotificationCenter(_ center: UNUserNotificationCenter, openSettingsFor notification: UNNotification?)

  • 第一个协议方法,是当应用在前台运行时调用,其 completionHandler 回调用于告诉系统以何种方式告知用户,来了新通知,参数为UNNotificationPresentationOptions 类型,有三个值可供选择:badge、alert、sound,如果没有调用completionHandler回调,则不会有提醒;在iOS10之前,如果应用在前台运行,来了新通知,是无法使用系统提醒的。
  • 第二个协议方法,是当应用在后台或者被杀死,当用户点击通知内容或者通知action时,会调用该方法,通过 UNNotificationResponse 实例可获取详细的信息
  • 第三个协议方法,是在app内展示通知的设置情况,需要在请求权限的options中添加 providesAppNotificationSettings,iOS12才支持

UNNotificationRequest

主要是针对本地通知,发起一个通知请求,其主要有一个初始化方法,和三个只读属性来获取相应的值;
如果是远程通知,代理方法里会有回调的UNNotificationRequest实例,直接获取相应的值即可:

// identifier: 唯一标识符
// content:要展示的消息内容,详见UNNotificationContent
// trigger:触发的方式,详见 UNNotificationTrigger
public convenience init(identifier: String, content: UNNotificationContent, trigger: UNNotificationTrigger?)

open var identifier: String { get }

    // The content that will be shown on the notification.
    @NSCopying open var content: UNNotificationContent { get }

    // The trigger that will or did cause the notification to be delivered. No trigger means deliver now.
    @NSCopying open var trigger: UNNotificationTrigger? { get }

UNNotificationContent & UNMutableNotificationContent

通知内容的承载体,远程通知回调的主要是 UNNotificationContent,创建本地通知内容的时候使用 UNMutableNotificationContent

// 通知的附件,iOS10之后,允许通知携带一张图片,一段视频,一段音频
// Optional array of attachments.
    open var attachments: [UNNotificationAttachment]

    // 角标数值
    // The application badge number. nil means no change. 0 to hide.
    @NSCopying open var badge: NSNumber?

  // 标题,限制一行,多余的以...
// The title of the notification. Use -[NSString localizedUserNotificationStringForKey:arguments:] to provide a string that will be localized at the time that the notification is presented.
    open var title: String

    // 副标题,限制一行,多余的以...
    // The subtitle of the notification. Use -[NSString localizedUserNotificationStringForKey:arguments:] to provide a string that will be localized at the time that the notification is presented.
    open var subtitle: String

    // 消息内容
    // The body of the notification. Use -[NSString localizedUserNotificationStringForKey:arguments:] to provide a string that will be localized at the time that the notification is presented.
    open var body: String

    // 所属的 category 标识符
    // The identifier for a registered UNNotificationCategory that will be used to determine the appropriate actions to display for the notification.
    open var categoryIdentifier: String

    // 点击消息启动app时的启动图
    // The launch image that will be used when the app is opened from the notification.
    open var launchImageName: String

    // 消息提示音,默认是.default
    // The sound that will be played for the notification.
    @NSCopying open var sound: UNNotificationSound?

// 消息的payload内容
  // Apps can set the userInfo for locally scheduled notification requests. The contents of the push payload will be set as the userInfo for remote notifications.
    open var userInfo: [AnyHashable : Any]


    // The unique identifier for the thread or conversation related to this notification request. It will be used to visually group notifications together.
    open var threadIdentifier: String


    /// The argument to be inserted in the summary for this notification.
    @available(iOS 12.0, *)
    open var summaryArgument: String

    
    /// A number that indicates how many items in the summary are represented in the summary.
    /// For example if a podcast app sends one notification for 3 new episodes in a show,
    /// the argument should be the name of the show and the count should be 3.
    /// Default is 1 and cannot be 0.
    @available(iOS 12.0, *)
    open var summaryArgumentCount: Int

UNNotificationTrigger 推送的触发器

是一个抽象类,他有四个子类,代表四种不同的触发方式

UNPushNotificationTrigger

远程通知触发,一般是由苹果服务器触发

UNTimeIntervalNotificationTrigger 时间间隔触发器

一定时间间隔后触发通知:

// 初始化方法,时间间隔,是否重复触发
public convenience init(timeInterval: TimeInterval, repeats: Bool)
// 时间间隔,只读
open var timeInterval: TimeInterval { get }

// 下次触发的日期
    open func nextTriggerDate() -> Date?

例如:

// 10s后触发
let timer = UNTimeIntervalNotificationTrigger(timeInterval: 10, repeats: false)
UNCalendarNotificationTrigger 日期时间触发器

在某个日期的某个事件触发通知

// 获取当前的DateComponents
open var dateComponents: DateComponents { get }

    // 初始化方法,参数是DateComponents类型
    // The next date is calculated using matching date components.
    public convenience init(dateMatching dateComponents: DateComponents, repeats: Bool)

    // 下次触发的日期
    open func nextTriggerDate() -> Date?

例如:

// 每周日的8点
        var dateCom = DateComponents()
        dateCom.weekday = 1
        dateCom.hour = 8
        
        let calendarTri = UNCalendarNotificationTrigger(dateMatching: dateCom, repeats: true)

附,从DateComponents 获取具体的时间


// 从 DateComponents 获取具体的时间信息
        let calendar = Calendar(identifier: Calendar.Identifier.gregorian)
        
        if let date = calendar.date(from: dateCom) {
            let weekday = calendar.component(Calendar.Component.weekday, from: date)
        }
UNLocationNotificationTrigger 地理位置触发器

当进入/离开某个地理范围时,触发的本地通知,需要有定位权限

@NSCopying open var region: CLRegion { get }

    // 初始化方法,参数为CLRegion
    public convenience init(region: CLRegion, repeats: Bool)

例如:

let center = CLLocationCoordinate2D(latitude: 37.33, longitude: -122.009)
        let regin = CLCircularRegion(center: center, radius: 2000, identifier: "reginid")
        regin.notifyOnExit = true
        regin.notifyOnEntry = true
        
        let locaTrig = UNLocationNotificationTrigger(region: regin, repeats: true)

通知快捷操作Action

UNNotificationAction

通知点击事件的快捷操作,其创建主要是一个初始化方法

public convenience init(identifier: String, title: String, options: UNNotificationActionOptions = [])

open var identifier: String { get }
open var title: String { get }
open var options: UNNotificationActionOptions { get }

UNTextInputNotificationAction

通知快捷回复输入框的action:

public convenience init(identifier: String, title: String, options: UNNotificationActionOptions = [], textInputButtonTitle: String, textInputPlaceholder: String)

open var textInputButtonTitle: String { get }
open var textInputPlaceholder: String { get }
UNNotificationActionOptions

快捷操作的设置选项

@available(iOS 10.0, *)
public struct UNNotificationActionOptions : OptionSet {

    public init(rawValue: UInt)

    // 需要授权验证才能响应,点击不会打开app
    // Whether this action should require unlocking before being performed.
    public static var authenticationRequired: UNNotificationActionOptions { get }

    // 红色的按钮,点击不会打开app
    // Whether this action should be indicated as destructive.
    public static var destructive: UNNotificationActionOptions { get }

    // 点击后会打开app
    // Whether this action should cause the application to launch in the foreground.
    public static var foreground: UNNotificationActionOptions { get }
}

action的响应事件会调用代理UNUserNotificationCenterDelegate的方法进行反馈。

UNNotificationCategory

// identifier :当前Category的唯一标识符
// actions:需要展示的快捷按钮集合
// intentIdentifiers:意图标识符,告诉系统该通知可能与Sari进行的请求有关
// options:如何处理该消息
public convenience init(identifier: String, actions: [UNNotificationAction], intentIdentifiers: [String], options: UNNotificationCategoryOptions = [])

    // identifier :当前Category的唯一标识符
// actions:需要展示的快捷按钮集合
// intentIdentifiers:意图标识符,告诉系统该通知可能与Sari进行的请求有关
// hiddenPreviewsBodyPlaceholder:当预览被隐藏时,替换消息内容body;例如开启隐私保护的时候,锁屏时看不到消息具体内容
// options:如何处理该消息
    @available(iOS 11.0, *)
    public convenience init(identifier: String, actions: [UNNotificationAction], intentIdentifiers: [String], hiddenPreviewsBodyPlaceholder: String, options: UNNotificationCategoryOptions = [])

    // iOS 12中的消息分组
// identifier :当前Category的唯一标识符
// actions:需要展示的快捷按钮集合
// intentIdentifiers:意图标识符,告诉系统该通知可能与Sari进行的请求有关
// hiddenPreviewsBodyPlaceholder:当预览被隐藏时,替换消息内容body;例如开启隐私保护的时候,锁屏时看不到消息具体内容
// categorySummaryFormat:分组后的消息,显示的第一则消息下面的摘要文字,默认是“还有 %d 个通知”,可以自定义,以此参数传入
// options:如何处理该消息
    @available(iOS 12.0, *)
    public convenience init(identifier: String, actions: [UNNotificationAction], intentIdentifiers: [String], hiddenPreviewsBodyPlaceholder: String?, categorySummaryFormat: String?, options: UNNotificationCategoryOptions = [])

UNNotificationCategory 创建完成后,其identifier 要赋值给UNMutableNotificationContent实例的categoryIdentifier属性

UNNotificationAttachment 通知附加包

iOS 10之后,通知允许添加一个与该通知关联的媒体文件,例如:一张图片,一段音乐或者视频,添加的文件必须保存在磁盘上。
对于本地通知,在添加通知的时候就需要创建UNNotificationAttachment实例,添加到相应的content中;如果是远程通知,需要通过扩展程序来下载附加的文件,然后创建UNNotificationAttachment实例,添加到通知中。

这里在创建 UNNotificationAttachment 实例的时候,会去校验文件的格式,如果是不支持的文件,或者超出规定大小的文件,会返回nil。

如果创建成功,文件数据将被移动到附件数据存储中;如果是本地的文件,会复制文件数据到附件数据存储中,以便于访问这些数据。

支持的文件类型及大小限制

  • Audio 声音文件 大小限制在 5Mb以内
    支持的格式有kUTTypeAudioInterchangeFileFormat、kUTTypeWaveformAudio、kUTTypeMP3、kUTTypeMPEG4Audio
  • Image图片 大小限制在 10Mb以内
    支持的格式:kUTTypeJPEG、kUTTypeGIF、kUTTypePNG
  • Movie 视频文件 最大 50Mb
    支持的格式:kUTTypeMPEG、kUTTypeMPEG2Video、kUTTypeMPEG4、kUTTypeAVIMovie

创建时,主要是有一个初始化方法:


 // Creates an attachment for the data at URL with an optional options dictionary. URL must be a file URL. Returns nil if the data at URL is not supported.
    public convenience init(identifier: String, url URL: URL, options: [AnyHashable : Any]? = nil) throws


// The identifier of this attachment
    open var identifier: String { get }

    // The URL to the attachment's data. If you have obtained this attachment from UNUserNotificationCenter then the URL will be security-scoped.
    open var url: URL { get }

    // The UTI of the attachment.
    open var type: String { get }

需要注意的是,这个初始化方法会抛出异常,需要使用try进行判断。

其参数 options是一个字典,支持以下几个key:

  • UNNotificationAttachmentOptionsTypeHintKey
    指定文件类型,其值为 String 类型,常用的有kUTTypeImage,kUTTypeJPEG2000,kUTTypeTIFF,kUTTypePICT,kUTTypeGIF ,kUTTypePNG,kUTTypeQuickTimeImage, 需要引入import MobileCoreServices
  • UNNotificationAttachmentOptionsThumbnailHiddenKey
    是否隐藏缩略图,其值为 Number 类型的Bool
  • UNNotificationAttachmentOptionsThumbnailClippingRectKey
    缩略图的裁剪区域,其值可以这样创建 ,坐标值为(0—1)
    let v = CGRect(x: 0, y: 0, width: 0.5, height: 0.5).dictionaryRepresentation
  • UNNotificationAttachmentOptionsThumbnailTimeKey
    动画图像帧数必须是NSNumber。视频时间是一个以秒为单位的NSNumber,或者是使用CMTimeCopyAsDictionary编码的CMTime

相关options介绍

UNNotificationCategoryOptions

告诉系统该如何处理该消息

@available(iOS 10.0, *)
public struct UNNotificationCategoryOptions : OptionSet {

    public init(rawValue: UInt)

    // 需要通过代理委托处理,调用UNUserNotificationCenterDelegate的相应方法
    // Whether dismiss action should be sent to the UNUserNotificationCenter delegate
    public static var customDismissAction: UNNotificationCategoryOptions { get }

    // 允许在驾驶模式下显示通知
    // Whether notifications of this category should be allowed in CarPlay
    public static var allowInCarPlay: UNNotificationCategoryOptions { get }

    // 在用户禁止显示预览的情况下,显示标题
    // Whether the title should be shown if the user has previews off
    @available(iOS 11.0, *)
    public static var hiddenPreviewsShowTitle: UNNotificationCategoryOptions { get }
// 在用户禁止显示预览的情况下,显示副标题
    // Whether the subtitle should be shown if the user has previews off
    @available(iOS 11.0, *)
    public static var hiddenPreviewsShowSubtitle: UNNotificationCategoryOptions { get }
}
UNAuthorizationOptions

请求权限的类型,请求权限的方法 requestAuthorization 参数

@available(iOS 10.0, *)
public struct UNAuthorizationOptions : OptionSet {

    public init(rawValue: UInt)

    // 角标提醒
    public static var badge: UNAuthorizationOptions { get }
// 声音提醒
    public static var sound: UNAuthorizationOptions { get }
// 弹框提醒
    public static var alert: UNAuthorizationOptions { get }
// 行车模式下,接收通知
    public static var carPlay: UNAuthorizationOptions { get }

    @available(iOS 12.0, *)
    public static var criticalAlert: UNAuthorizationOptions { get }

    @available(iOS 12.0, *)
    public static var providesAppNotificationSettings: UNAuthorizationOptions { get }

    @available(iOS 12.0, *)
    public static var provisional: UNAuthorizationOptions { get }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值