iOS10推送通知(本地&远程)

一.发送一个简单的本地通知

1.注册通知

  • 需要导入头文件或者框架UserNotifications

  • 在iOS8.0之后,如果想要用户接收通知需要主动请求授权,为了能让该代码一定被执行,一般写在Appdelegate中


func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

// 1.获取通知中心

let center = UNUserNotificationCenter.current()

// 2.注册通知(会弹框请求用户授权)

// 如果有错误则直接返回

if error != nil {

return

}

// 授权成功则为true

if granted {

print("用户同意通知")

} else {

print("用户拒绝通知")

}

}

2.发送通知(点击控制器View的时候发送通知)


override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

// 创建通知标识(用于标识哪一个通知)

let identifier = "SimpleNotificationIdentifier"

// 创建通知中的内容

let content = UNMutableNotificationContent()

// 设置内容

content.body = "我是内容"

// 设置通知发送的时间

// 注意:重复时间必须大于60秒

let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 3, repeats: false)

// 创建请求对象

let request = UNNotificationRequest(identifier: identifier, content: content, trigger: trigger)

// 获取通知中心

let center = UNUserNotificationCenter.current()

// 添加本地通知

center.add(request, withCompletionHandler: {(error: Error?) in

if error == nil {

print("本地通知添加成功")

}

})

}

3.展示效果

  • 前台没有弹框

  • 后台/退出应用/通知中心/锁屏均可以接收到弹框

Paste_Image.png
二.发送一个带附件的通知
  • 在iOS10之后发送通知的时候可以附带一些内容

  • 内容包含图片、GIF图片、视频以及音频(格式最好是caf,否则没有效果)


/* 设置其他内容 */

// 应用文字

content.badge = 10

// 设置通知的声音

content.sound = UNNotificationSound(named: "win.aac")

// 设置标题

content.title = "我是标题"

// 设置子标题

content.subtitle = "我是子标题"

// 设置附件内容

// 附件标识

let attachmentIdentifier = "ImageAttachmentIdentifier"

// 附件URL

if let url = Bundle.main.url(forResource: "70s Electric Piano 52.caf", withExtension: nil) {

do {

let attachment = try UNNotificationAttachment(identifier: attachmentIdentifier, url: url, options: nil)

content.attachments = [attachment]

print("---")

} catch {

print(error)

}

}

  • 展示的效果

图片

Paste_Image.png

Gif

Paste_Image.png

音频

Paste_Image.png

视频

Paste_Image.png
三.对通知的操作
  • 当一个通知添加成功之后,可以对添加成功的通知做一些操作,分别为:

  • 查看即将发送的通知

  • 取消即将发送的通知

  • 查看已经发送的通知

  • 取消已经发送的通知


/// 查看即将发送的通知

@IBAction func showUnsendNotification() {

UNUserNotificationCenter.current().getPendingNotificationRequests { (request: [UNNotificationRequest]) in

print("即将发送的通知:\(request)")

}

}

/// 删除即将发送的通知

@IBAction func removeUnsendNotification() {

// 通过标识删除某一个通知

// UNUserNotificationCenter.current().removePendingNotificationRequests(withIdentifiers: <#T##[String]#>)

// 删除所有

UNUserNotificationCenter.current().removeAllPendingNotificationRequests()

}

/// 查看发送成功的通知

@IBAction func showSendedNotification() {

UNUserNotificationCenter.current().getDeliveredNotifications { (notification: [UNNotification]) in

print("查看发送成功的通知:\(notification)")

}

}

/// 删除发送成功的通知

@IBAction func removeSendedNotification() {

// 通过标识删除某一个发送成功的通知

// UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: <#T##[String]#>)

// 删除所有发送成功的通知

UNUserNotificationCenter.current().removeAllDeliveredNotifications()

}

四.监听通知的点击
  • 当用户点击通知进入App后,监听用户通知行为

  • 需要设置通知的代理,当用户点击了通知后,会通过代理告诉我们

设置代理


UNUserNotificationCenter.current().delegate = self

遵守协议并实现代理方法


extension ViewController: UNUserNotificationCenterDelegate {

/// 当接收到通知的时候会来到该方法

///

/// - Parameters:

/// - center: 通知中心

/// - response: 响应

/// - completionHandler: 成功回调

func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {

print("接收到通知\(response)")

completionHandler()

}

/// 当一个通知发送成功后会来到该方法

///

/// - Parameters:

/// - center: 通知中心

/// - notification: 发送的通知

/// - completionHandler: 回调闭包,可以设置在前台收到通知横幅

func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {

print("发送通知成功\(notification)")

// 在前台也能接收到通知

completionHandler([.alert,.badge,.sound])

}

}

五.通知的触发条件
  • iOS10与之前的通知的触发条件一共有三种

  • 多少时间之后发送通知

  • 指定日期发送通知

  • 触发区域发送通知

  • 在iOS10之后,触发条件的类为UNNotificationTrigger

  • 而具体设置需要使用到它的子类

  • UNTimeIntervalNotificationTrigger : 多少时间之后

  • UNCalendarNotificationTrigger : 指定日期

  • UNLocationNotificationTrigger : 指定区域

1.多少时间之后发送通知

注意: 如果需要重复,那么时间必须大于60秒

let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 3, repeats: false)

2.指定日期发送通知

可以通过添加年月日时,来固定一个时间发送通知

// 创建时间组件

var components = DateComponents()

// 设置为日历时间

components.calendar = Calendar(identifier: .gregorian)

// 每天的早上10点10分发送通知

components.hour = 10

components.minute = 10

print(components.date)

let trigger = UNCalendarNotificationTrigger(dateMatching: components, repeats: true)

3.指定区域发送通知

注意:在使用模拟器调试的过程中,可能会无法显示,重置模拟器,或者换个模拟器则会解决该问题

// 1.请求授权(iOS8.0之后获取用户的位置要主动请求授权,注意在info.plist中配置对应的key)

lazy var locationM: CLLocationManager = {

let locationM = CLLocationManager()

locationM.requestAlwaysAuthorization()

return locationM

}()

// 2.创建区域触发器

let region = CLCircularRegion(center: CLLocationCoordinate2D(latitude: 12.123, longitude: 123.456), radius: 1000, identifier: "RegionNotification")

locationM.startMonitoring(for: region)

let trigger = UNLocationNotificationTrigger(region: region, repeats: true)

六.额外操作项
1.设置通知的额外信息

// 1.设置额外信息

content.userInfo = ["name": "张三", "age": 18]

// 2.在接收到通知后,可以获取到额外信息

/// 当接收到通知的时候会来到该方法

///

/// - Parameters:

/// - center: 通知中心

/// - response: 响应

/// - completionHandler: 成功回调

func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {

print("接收到通知获取额外信息\(response.notification.request.content.userInfo)")

completionHandler()

}

// 打印为:接收到通知获取额外信息[AnyHashable("name"): 张三, AnyHashable("age"): 18]

2.设置额外操作项
  • 步骤

  • 注册操作集合

  • 注册操作组,添加到操作集合中

  • 注册操作行为,添加到操作组中

  • 设置通知所用到的操作组


// 1.注册操作项

// 1.创建操作项

let action1: UNNotificationAction = UNNotificationAction(identifier: "huifu", title: "回复", options: .foreground)

let action2: UNNotificationAction = UNNotificationAction(identifier: "jujue", title: "拒绝", options: .destructive)

let actions: [UNNotificationAction] = [action1, action2]

// 创建操作组

// identifier: 操作组标识

// actions: 操作组行为

// intentIdentifiers:暂时未发现该用途

// options: 支持的场景

let categoryIdentifier = "category1"

let category: UNNotificationCategory = UNNotificationCategory(identifier: categoryIdentifier, actions: actions, intentIdentifiers: [], options: .customDismissAction)

// 注册操作集合(其中设置操作组)

let categories: Set<UNNotificationCategory> = [category]

center.setNotificationCategories(categories)

// 设置该通知用到的额外操作组

content.categoryIdentifier = "category1"

  • 展示效果

  • 点击回复打开app

  • 点击拒绝则不会打开app

  • 两者都会调用接收通知的代理方法

Paste_Image.png
七.设置快捷回复
  • 操作行为有2个类来实现'UNNotificationAction'以及UNTextInputNotificationAction

  • 其中UNTextInputNotificationAction是'UNNotificationAction'的子类,用于实现快捷回复

  • 下列代码中的action3 为便捷回复行为


// 1.创建操作项

let action1: UNNotificationAction = UNNotificationAction(identifier: "huifu", title: "回复", options: .foreground)

let action2: UNNotificationAction = UNNotificationAction(identifier: "jujue", title: "拒绝", options: .destructive)

let action3 = UNTextInputNotificationAction(identifier: "kuaijie", title: "快捷回复", options: .foreground, textInputButtonTitle: "回复按钮", textInputPlaceholder: "占位字符")

let actions: [UNNotificationAction] = [action1, action2,action3]

// 创建操作组

// identifier: 操作组标识

// actions: 操作组行为

// intentIdentifiers:暂时未发现该用途

// options: 支持的场景

let categoryIdentifier = "category1"

let category: UNNotificationCategory = UNNotificationCategory(identifier: categoryIdentifier, actions: actions, intentIdentifiers: [], options: .customDismissAction)

// 注册操作集合(其中设置操作组)

let categories: Set<UNNotificationCategory> = [category]

center.setNotificationCategories(categories)

  • 展示效果
Paste_Image.png
八.通知触发的场景
  • 在实际开发中,前台获取通知与后台获取通知所要执行的逻辑不一致,那么就有必要去判断一下,当前的通知触发的场景

  • 步骤

  • 在获取到通知的代理方法中获取该应用的状态

  • 判断当前状态


/// 当接收到通知的时候会来到该方法

///

/// - Parameters:

/// - center: 通知中心

/// - response: 响应

/// - completionHandler: 成功回调

func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {

if let response = response as? UNTextInputNotificationResponse {

print(response.userText)

} else {

print("接收到通知获取额外信息\(response.notification.request.content.userInfo)")

}

let status = UIApplication.shared.applicationState

switch status {

case .active:

print("在前台")

case .inactive:

print("进入前台")

default:

print("在后台")

}

completionHandler()

}

iOS10远程推送通知

一.获取DeviceToken

  • 此处省略配置真机调试证书通知调试证书以及通知生产证书步骤

  • 必须保证BundleId与在开发者中心的AppId一致

  • 必须使用真机

1.注册通知

  • 需要导入头文件或者框架UserNotifications

  • 在iOS8.0之后,如果想要用户接收通知需要主动请求授权,为了能让该代码一定被执行,一般写在Appdelegate中


// 1.获取通知中心

let center = UNUserNotificationCenter.current()

// 2.注册通知

center.requestAuthorization(options: [.alert,.carPlay,.badge,.sound], completionHandler: {(granted: Bool, error: Error?) in

if error != nil {

return

}

if granted {

print("用户允许通知")

} else {

print("用户拒绝通知")

}

})

2.向苹果服务器申请DeviceToken

  • 获取方式与iOS8.0一致

// 3.获取deviceToken

application.registerForRemoteNotifications()

  • 从代理中获取deviceToken

  • 此处Data打印的是32types,转为NSData即可


/// 当获取到deviceToken会来到该方法

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {

print(NSData(data: deviceToken))

}

/// 注册失败会来到该方法

func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {

print(error)

}

3.开启远程推送功能

  • 工程->target->Capabilities->Push

  • 开启的条件

  • 1.Apple Id 必须配置了远程推送通知

  • 2.权利文件(打开会自动生成该文件)

4.运行真机,获取DeviceToken

二.发送通知

  • 借助PushMeBaby作为服务器向苹果服务器发送消息,苹果服务器推送通知

极光推送

  • 注册应用

  • 上传通知证书.p12

  • 集成Jpush SDK

1.注册Jpush并获取DeviceToken


func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

// 注册通知

let entity = JPUSHRegisterEntity()

entity.types = Int(JPAuthorizationOptions.alert.rawValue | JPAuthorizationOptions.badge.rawValue | JPAuthorizationOptions.sound.rawValue)

JPUSHService.register(forRemoteNotificationConfig: entity, delegate: self)

// 初始化JUSH

JPUSHService.setup(withOption: launchOptions, appKey: "b29ccf03d1e6aca9baa3c34a", channel: "App Store", apsForProduction: false)

return true

}

/// 获取DeviceToken

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {

JPUSHService.registerDeviceToken(deviceToken)

}

/// 注册失败

func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {

print(error)

}

2.设置代理,处理通知


extension AppDelegate : JPUSHRegisterDelegate {

/// 获取通知

func jpushNotificationCenter(_ center: UNUserNotificationCenter!, didReceive response: UNNotificationResponse!, withCompletionHandler completionHandler: (() -> Void)!) {

}

/// 可设置在前台获取通知

func jpushNotificationCenter(_ center: UNUserNotificationCenter!, willPresent notification: UNNotification!, withCompletionHandler completionHandler: ((Int) -> Void)!) {

let userInfo = notification.request.content.userInfo

let isPushTrigger = notification.request.trigger?.isKind(of: UNPushNotificationTrigger.self) ?? false

if isPushTrigger {

JPUSHService.handleRemoteNotification(userInfo)

}

let value = Int(UNNotificationPresentationOptions.alert.rawValue | UNNotificationPresentationOptions.sound.rawValue | UNNotificationPresentationOptions.badge.rawValue)

completionHandler(value)

// 需要执行这个方法,选择是否提醒用户,有Badge、Sound、Alert三种类型可以选择设置

}

}

来源:http://bbs.520it.com/forum.php?mod=viewthread&tid=3020

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,001评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,210评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,874评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,001评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,022评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,005评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,929评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,742评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,193评论 1 309
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,427评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,583评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,305评论 5 342
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,911评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,564评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,731评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,581评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,478评论 2 352

推荐阅读更多精彩内容