tnblog
首页
登录

Swift->通知相关整理大全

68人阅读 2019/8/29 10:00 评论:3 手机 收藏 关注
分类: iOS

通知中?心(UNUserNotifications)

请求通知权限

App启动时请求授权。

Make your authorization request during your app's launch cycle.

苹果官?方?文档要求我们把请求权限的代码写在App启动后的相关?方法内。 使?用UNUserNotificationCenter来请求通知权限。 .current() ?方法?用以获取此类的单例例对象。

let center = UNUserNotificationCenter.current()
// 请求 显示通知,播放通知声?音 的权限
center.requestAuthorization(options: [.alert, .sound]) {(granted, error) in
}

检查已请求权限的可?用性

?用户在第?一次请求通知权限之后,后期是可以在系统设置?里里修改的。?用户可以分别控制是否允许你的App开启通知声?音,通知横幅,App?角标等权限。

检查权限所以使?用的相关依赖依然是 UNUserNotificationCenter

let center = UNUserNotificationCenter.current()
center.getNotificationSettings { (settings) in
    guard settings.authorizationStatus == .authorized else {return} /// 是否被允许在锁屏显示通知,取值enabled/disabled
    settings.lockScreenSetting
    /// 是否允许显示弹窗 settings.alertSetting ...
}

发送本地通知

1. 创建UNMutableNotificationContent对象,此对象?用于描述通知的内容信息,?比如标题和消息 体。

2. 创建UNNotificationTrigger对象(可选)。此对象?用于指定通知的触发?方式,?比如具体时间,具

体地点,甚?至时间周期。
3. 创建UNNotificationRequest对象,此对象?用于描述?一个通知请求,请求会带上以上创建的两个对

象。
4. 提交通知请求

let notificationContent = UNMutableNotificationContent()notificationContent.title = "通知标题"notificationContent.body = "通知内容"						
var date = DateComponents()
date.hour = 8
date.minute = 30
/// 在每天的8:30分,触发此通知
let trigger = UNCalendarNotificationTrigger(dateMatching: date, repeats: true)						
/// identitier?用于保证request的唯?一性,以后可?用于取消通知时使?用。
/// 如果trigger参数为nil,则此通知?立即发出。
let request = UNNotificationRequest(identifier: UUID().uuidString,				
            content: notificationContent, trigger: trigger)
            					
UNUserNotificationCenter.current().add(request) { (error) in
  if error != nil {					
    // pass					
    }
}					
	

定制通知?行行为(Actionable notifications)

/// identifier是此action的唯?一标识符,title就是按钮的标题,options?用于指定此按钮的?一些
?行行为,?比如.authenticationRequired表示必须?手机在解锁状态才能显示此按钮
let acceptAction = UNNotificationAction(identifier: "ACCEPT_ACTION", title:"Accept", options: .authenticationRequired)

						
/// .destructive表示按钮具有破坏性?行行为,按钮会显示红?色
let declineAction = UNNotificationAction(identifier: "DECLINE_ACTION", title:"Decline", options: .destructive)

						
/// identifier是此通知类型的标识符,当通知(aps)的categoryIdentifier等于此值时,此通知
类型会被应?用,此通知类型包含两个按钮
let actionCategory = UNNotificationCategory(identifier: "ACTION_CATEGORY",actions: [acceptAction, , declineAction], intentIdentifiers: [],hiddenPreviewsBodyPlaceholder: "", options: .allowInCarPlay)

						
UNUserNotificationCenter.current().setNotificationCategories([actionCategory])

以上代码的作?用,注册?一个notificationCategory,该category的标识符为 ACTION_CATEGORY ,本地通 知或者远程通知都可以指定标识符,?用于指定该通知响应的notificationCategory

let content = UNMutableNotificationContent()
content.title = "测试通知标题"
content.body = "测试通知内容"
/// 发送此通知,即可触发上?面添加的两个按钮,这?里里要保证categoryIdentifier和之前注册的时候
填写的?一致

content.categoryIdentifier = "ACTION_CATEGORY"						

处理理通知按钮点击事件

要处理理通知按钮的点击?行行为,?用户必须在程序启动完成之前注册代理理,代理理
UNUserNotificationCenterDelegate 类型的对象,否则可能会错过程序启动时传?入的通知。

实现 optional func userNotificationCenter(_ center: UNUserNotificationCenter, didReceiveresponse: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) ?方法,并根据带来的通知处理理结果,来规划按钮的点击逻辑。

func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive
response: UNNotificationResponse, withCompletionHandler completionHandler:@escaping () -> Void) {
				
    let userInfo = response.notification.request.content.userInfo/// 这个就是点击的按钮的identifier
    let actionIdentifier = response.actionIdentifier

						
    //...
					
    completionHandler()
}	

接收远程通知

使远程通知也可以显示?自定义按钮,后端开发?人员需要保证发送来的通知内容与这个类似:

					{
"aps": {

						
/*这?里里的category等于上?面写的categoryIdentifier*/"category": "ACTION_CATEGORY",
"alert": {

						
"title": "通知标题",

						
"body": "通知内容"}

						
    }    "field1":"message",    "field2":"message"

						
}		

只要 payload 内的 category 字段与App内置对应的的 categoryIdentifier 匹配,收到此通知时下拉或 者重按,即可出现按钮。


处理理通知(前台)

在前台的时候收到通知会回调这个?法:userNotificationCenter(_:willPresent:withCompletionHandler:),请注意,是收到通知?而?非点击 通知。

func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent
notification: UNNotification, withCompletionHandler completionHandler: @escaping(UNNotificationPresentationOptions) -> Void) {
					
  if notification.request.content.categoryIdentifier == "ACTION_CATEGORY" {    
      let field1 = notification.request.content.userInfo["field1"] as? String    
      let field2 = notification.request.content.userInfo["field2"] as? String    
      // ...
						
    }
    // completionHandler?一定要调?用,这个回调的参数决定了了收到通知后的系统?行行为// completionHandler([])表示收到通知后没有系统动作
    // completionHandler([.sound])表示播放通知声?音completionHandler([.sound, .badge])					
}		


App收到通知之前,修改通知的内容(payload)

要实现这个类似于"拦截通知"的功能,你需要新建?一个Notification Service Extension

Xcode项?目?里里,点选菜单栏File -> New -> Target, 然后选择Notification Service Extension,填写 信息并完成创建。

Xcode为你新建的?文件模板?里里,已经实现了了基本的推送?文案修改。

/// 使?用此?方法来修改通知信息,将最终的结果通过contentHandler回传给系统/// 你可以在此?方法内下载图?片,或者电影等信息
/// 此?方法有(不不超过30s的)时间限制,需要在时限内调?用contentHandler
func didReceive(_ request: UNNotificationRequest, withContentHandler
contentHandler: @escaping (UNNotificationContent) -> Void) {
			
    /// 保存contentHandler,以便便于下?面那个?方法内调?用
    self.contentHandler = contentHandler
    let newContent = request.content.mutableCopy()
    /// 下载完成后配置此条通知的附件可?用于显示图?片,视频,或者?音频等内容
    /// 参数?里里的URL必须是fileURL					
    /// options字典?用于定义?一些额外的配置,?比如图?片缩略略图的裁剪区域等,具体配置定义在https://developer.apple.com/documentation/usernotifications/unnotificationattachm
ent				
    let attachment = try? UNNotificationAttachment(identifier: UDID().udidString,url URL: URL(fileURLWithPath: "", options: nil)					
    newContent.attachments = [attachment]

						
    /// 最后?一定要调?用contentHandler
}

						
///  如果contentHandler在时限内没有调?用,系统将会通过此?方法通知app						
///  此?方法内应当尽可能快的调?用contentHandler,func serviceExtensionTimeWillExpire() {
				
    if let contentHandler = self.contentHandler {    contentHandler()

						
    }
}	

请注意,系统只会在你的APNs Payload内包含下列列信息时,才会执?行行此拓拓展:必须包含 mutable-content ,value1;

必须包含 alert 字典,且其中的 body 或者 title 必须有值;

{
"aps": {

						
    "alert": {
        "title": "通知标题",
        "body": "通知内容"

						
     },
     "mutable-content": 1,    
     "category": "..."

						
    }
}			

?自定义通知UI

要实现这个功能,你需要新建?一个Notification Content Extension.

Xcode项?目?里里,点选菜单栏File -> New -> Target, 然后选择Notification Content Extension,填 写信息并完成创建。

						
# The file list we got after creation.

						
├── Base.lproj
│   └── MainInterface.storyboard
├── Info.plist
└── NotificationViewController.swift

以下是注意事项:

你不不能在Extension?里里?面?自?己新建ViewController?文件,你也不不能再storyboard?里里?面新建scene,?一个Notification Content Extension只能对应?一种Notification Category.

你可以?用新建多个Notification Content Extension的?方式来实现多种通知UI的定制,需要注意的是,多个不不同的extension,你需要保证所?支持的Notification Category的唯?一性.

修改UI样式

你可以在 MainInterface.storyboard 或者 NotificationViewController.swift 中?自定义UI,内容的?高 度可以根据autolayout?自适应.

UI的编写就跟?一般的UIViewController是?一样的,需要注意的应该就是这?里里的ViewController?高度应该是 刚刚好跟内容?大?小?一致的,所以说对AutoLayout有?一定的要求.

					
/// 此?方法将会在第?一次下拉通知以及后续有其他相关通知到达之后,被调?
func didReceive(_ notification: UNNotification) {
    let notificationTitle = notification.request.content.title
    let notificationBody = notification.request.content.body
    let attachments = notification.request.content.attachments
    /// 根据通知标题,通知内容,以及附件等信息来配置通知的详情UI						
}	

为你的?自定义UI指定所?支持的通知类型

前?面说了了,我们可以?用UNNotificationCategory.identifier来确定每?一种通知的唯?一性.当系统收到通知时,系统会匹配NotificationCategoryidentifier,来确认其是否存在?一个?自定义通知UI.

Info.plist ?文件中,使?用 UNNotificationExtensionCategory 字段指定此extension所?支持的Notification Categroy.

					
<key>NSExtension</key>
<dict>					
    <key>NSExtensionAttributes</key>
    <dict>					
        <!-- 模板?里里?面默认的此字段的类型是String,可以根据实际场景改为String Array --><key>UNNotificationExtensionCategory</key>
        <string>myNotificationCategory</string>					
        <!--?自?己?手动改成String Array,可以填写多个Notification Content Identifier-->
        <!--当任意?一个identifier被匹配到时,当前extension都会被启动--><key>UNNotificationExtensionCategory</key>
        <array>			
            <string>myNotificationCategory</string>
            <string>myNotificationCategory1</string>
            <string>myNotificationCategory2</string>				
        </array>				
    </dict>
</dict>


评价
没有个性,不需要签名
文章
6
粉丝
16
评论
8
分类
16
{{item.ArticleTitle}}
{{item.BlogName}} : {{item.Content}}