AC — Swift和IOS —用户通知
在iOS 10中新加入UserNotifications框架,称为iOS SDK发展到现在的最大规模的一次重组。新版本里通知的相关功能被提取到了单独的框架,通知也不再区分类型,而有了更统一的行为。
权限申请
通知权限
- 加入UserNotifications框架
导入用户通知
- 向用户申请通知权限
func application(_ application:UIApplication,didFinishLaunchingWithOptions launchOptions:[UIApplicationLaunchOptionsKey:Any]?)->布尔{
//应用程序启动后进行自定义的替代点。
// 1.我们利用UNUserNotificationCenter.current()获得UNUserNotificationCenter物件,然后再调用它的requestAuthorization(options:completionHandler :),征求使用者同意App发送通知。
// 2. options:设定我们希望使用者同意的通知样式。
UNUserNotificationCenter.current()。requestAuthorization(选项:[。alert,.sound,.badge],completionHandler:{(已授予:Bool,错误:Error?)->无效
如果授予== true {
print(“使用者同意了!”)
}其他{
print(“使用者不同意...”)
}
})
返回真
}
- 要注意的是,询问消息只会出现一次,一旦用户拒绝了这个请求,当我们下次启动App时,再也看不到它。想要应用有机会接收到通知的话,用户必须从设定App进入App的通知设定页面,打开Allow Notifications的开关。
远程通知
一旦用户同意后,就可以在应用中发送本地通知了。不过要通过服务器发送远程通知的话,还需要多一个获取用户token的操作。server再使用这个token将用向Apple Push Notification的server提交请求,然后APNs通过令牌识别设备和应用,将通知推给用户。
- 使用UIApplication的registerForRemoteNotification来注册远程通知; 在application(_:didRegisterForRemoteNotificationsWithDeviceToken)中获取用户令牌。
//application(_:
didFinishLaunchingWithOptions)中,註冊遠程通知
application.registerForRemoteNotifications()
func application(_ application:UIApplication,didRegisterForRemoteNotificationsWithDeviceToken deviceToken:Data){
//deviceToken
是一个Data
类型,为了方便使用和传递,一般会选择将其转换为一个字符串。
print(“ DeviceToken:\(deviceToken)”)
让apnsToken = String(格式:“%@”,deviceToken为CVarArg)作为String
print(“ ApnsToken:\(apnsToken)”)
让tokenString = apnsToken.trimmingCharacters(in:CharacterSet(charactersIn:“ ”))。replacingOccurrences(of:“”,with:“”)
print(“ TokenString:\(tokenString)”)
}
发送通知
@IBAction func createNotification(_ sender:AnyObject){
//创建通知内容
让内容= UNMutableNotificationContent()
content.title =“体验过了,才是你的。”
content.subtitle =“米花儿”
“ content.body =”不要追问为什么,就笨拙地走入未知。感受眼前的怦然与颤抖,看见左边的碎裂和跳动。不管好的坏的,只有体验过了,才是你的。
content.badge = 1
content.sound = UNNotificationSound.default()
//创建通知触发
让触发器= UNTimeIntervalNotificationTrigger(timeInterval:10,重复:false)
//创建一个通知请求
让请求= UNNotificationRequest(标识符:“ notification1”,内容:内容,触发器:触发器)
//将请求加入到通知中心
UNUserNotificationCenter.current()。add(request,withCompletionHandler:nil)
}
- 总共有的总体方法可以触发通知,可进一步研究:
- UNTimeIntervalNotificationTrigger:几秒钟后触发。
- UNCalendarlNotificationTrigger:指定某个时刻触发。
- UNLocationNotificationTrigger:用户位于某个位置时触发。
- UNPushNotificationTrigger:从遥远的后台传送到用户手机的通知。
取消通知
取消要求的方法
- Pending是使用者还没收到的未来通知,已传送则是已经收到,但仍显示在通知页面,尚未点开观看的通知。
打开函数removePendingNotificationRequests(withIdentifiers标识符:[String])
打开函数removeAllPendingNotificationRequests()
打开函数removeDeliveredNotifications(withIdentifiers标识符:[String])
打开函数removeAllDeliveredNotifications()
在通知加入图片,音乐,影片
开发者现在可以在通知中嵌入图片/视频,大大丰富了通知内容的替代和趣味性。
为本地通知添加多媒体内容十分简单,只需要通过本地磁碟上的档案路径url创建一个UNNotificationAttachment对象,然后将对象赋值给给内容的附件属性就行了。
让 imageURL = Bundle.main.url(forResource:“ pic”,withExtension:“ jpg”)
让附件=尝试! UNNotificationAttachment(标识符:“ imageAttachment”,网址:imageURL !,选项:nil)
//附件属性:可包含多个UNNotificationAttachment
物件的数组
content.attachments = [附件]
- UNNotificationAttachment物件的内容可以是图片,音乐或影片,只要传给它档案的路径url。 ,因为无法取得里头图片的url。
在前景显示通知
通知的设计是为了让使用者在操作其他App或是发呆做着白日梦时,贴心提醒使用者。因此当App在前景时,通常是不会显示通知讯息的。不过有些时候就算App在前景,还是有显示通知的需求。如果希望在App应用内也能显示通知的话,需要额外的工作处理。
遵从UNUserNotificationCenterDelegate协议
- 利用extension扩展AppDelegate,让它遵从UNUserNotificationCenterDelegate协定。
- 定义userNotificationCenter(_:willPresent:withCompletionHandler)。
func userNotificationCenter(_中心:UNUserNotificationCenter,willPresent通知:UNNotification,withCompletionHandlercompleteHandler:@转义(UNNotificationPresentationOptions)->无效)
completeHandler([。alert,.badge,.sound])
//如果不想显示某个通知,可以直接用空options调用completeHandler:
// completeHandler([])
}
将AppDelegate物件创建UNUserNotificationCenter物件的代理人
在application(_:didFinishLaunchingWithOptions)里:
UNUserNotificationCenter.current()。delegate = 自我
在通知里包含客制化资讯
可以通过其中包含定义属性的信息来实现。它的类型别是Dictionary,因此我们可在其中搭配自订的key,包含任何我们想携带的客制化资讯。
content.userInfo = [“链接”:“ https://www.facebook.com/himinihana/photos/a.104501733005072.5463.100117360110176/981809495274287”]
判断用户点击通知,解析通知内容
UNUserNotificationCenterDelegate宣告的userNotificationCenter(_:didReceive:withCompletionHndler)会在用户与通知进行交互时被触发,不管App在前景还是背景下,再点击。
因此我们在UNUserNotificationCenter物件的代理人类别AppDelegate里定义此功能,来客制化使用者点击通知后做的事情。
func userNotificationCenter(_ center:UNUserNotificationCenter,didReceive响应:UNNotificationResponse,withCompletionHandlercompleteHandler:@escaping()-> Void){
//UNNotificationResponse
是一个几乎包括了通知的所有信息的物件
让内容= response.notification.request.content
print(“标题\(content.title)”)
print(“ userInfo \(content.userInfo)”)
//警告:UNUserNotificationCenter委托收到了对-userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:的调用,但从未调用完成处理程序。
//系统要求执行的方法
completeHandler()
}
可行的通知的发送和处理
例如可以在通知里加上按钮,来跟用户互动。方式为将动作放入一个类别中,把此类别进行注册动作,最后在发送通知时,将通知的类别设置为要使用的类别来达到。
- 在application(_:didFinishLaunchingWithOptions)里:生成对应到通知按钮的UNNotificationAction对象。
- 同时指定一个标识符,我们将在实际发送通知时用此标识符进行设置,如此系统就可知该通知对应类别类别了。
- 创建通知时,设置内容的类别标识符等于先前指定的UNNotificationCategory对象的标识符一样,如此一来App收到通知时,才知道要显示哪组按钮。
- 和UN的InputNotificationAction触发的响应,直接将与中普通的通知一样,actionable通知也会进到didReceive的委托方法,在这里通过请求它转换为一个UNTextInputNotificationResponse,就可以拿到其中的使用者输入了。
//加入客制化的按钮,设置自订的通知类别
let likeAction = UNNotificationAction(标识符:“喜欢”,标题:“好感动”,选项:[。foreground])
let dislikeAction = UNNotificationAction(标识符:“不喜欢”,标题:“没感觉”,选项:[。destructive])
let inputAction = UNTextInputNotificationAction(标识符:“输入”,标题:“请写下”,选项:[。foreground],textInputButtonTitle:“发送”,textInputPlaceholder:“您想说什么...”)
让类别= UNNotificationCategory(标识符:“ luckyMessage”,动作:[likeAction,dislikeAction,inputAction],intentIdentifiers:[],选项:[。customDismissAction])
UNUserNotificationCenter.current()。setNotificationCategories([类别])
@IBAction func createNotification(_ sender:AnyObject){
// 先前略...
content.categoryIdentifier = "saySomethingCategory"
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
让categoryIdentifier = response.notification.request.content.categoryIdentifier
如果categoryIdentifier ==“ luckyMessage” {
handleSaySomthing(响应:响应)
}
completionHandler()
}
//仅点击或清除。 (除非您将.customDismissAction设置为category选项,否则当用户清除通知时,您将不会收到此回调。)
私有函数handleSaySomthing(响应:UNNotificationResponse){
让文字:字符串
让actionType = response.actionIdentifier
切换actionType {
情况“输入”:
text =(响应为!UNTextInputNotificationResponse).userText
情况“喜欢”:
文字=“谢谢”
案例“不喜欢”:
文字=“再见”
默认:
文字=“”
}
print(“ text:\(text)”)
}
参考阅读1:[结合iOS 10的用户通知:传送米花儿的幸福打气通知]
参考阅读2:[活久见的重构— iOS 10 UserNotifications框架解析]
参考阅读3:[iOS 10消息推送(UserNotifications)秘籍总结(一)]