iOS10 推送通知开发【译】

原文地址:Developing Push Notifications for iOS 10
译者:李剑飞的博客


虽然通知经常被过度使用,但是通知确实是一种获得用户关注和通知他们需要更新或行动的有效方式。iOS 10有了新的通知,如新消息、商业信息和时间表的变化。在本教程中,我将向你展示如何使用通知在你的iOS应用程序,并且显示iOS 10引入了新特性。开发iOS 10推送通知你需要最新版本的Xcode,Xcode 8测试版,这些目前都是可下载的,在下载页面

你可以去Github下载本教程的整个工程。

开始

在Xcode中启用推送通知是很容易的,但你需要几个步骤。

创建一个新的工程,给它起一个唯一的Bundle Identifier.

当您已经创建了project,去Project Settings页选择Capabilities栏。打开推送通知,如下所示。

注意: 如果你是苹果的付费开发者成员,你就能看到推送通知功能这一栏。


Developer Account这一栏,从左侧的菜单栏中选择证书,IDs,和描述文件,然后选择App IDsIdentifiers栏中。找到已经创建的App的名称,在服务列表中选中。注意,有两个可配置状态的推送通知。

不要关闭这个网页,你很快就会回来的。

发送通知

在本文中,我将使用Pusher发送推送通知。您还可以使用其他的解决方案如Houston。无论哪种方式,发送一个通知,你都需要一个证书。

去创建一个证书,打开Keychain Access,从证书认证菜单中选择Keychain Access -> Certificate Assistant -> Request a Certificate

填写表单并单击Continue。确保你选择保存到了磁盘。

返回到开发者账户的网页。你可以为你的App IDs生成开发(调试)证书或发布证书。

之后在选择右侧的申请,在底部,单击编辑。在推送通知部分,单击创建开发(调试)证书。

在需要时,从Keychain,继续上传生成证书请求。

现在你已经创建了证书,可以下载它。打开下载的文件安装它。

下载并运行Pusher。这个程序的顶部需要填入一个推送的证书。为它位于你的钥匙链,OS X将询问是否允许Pusher访问证书。

第二个字段需要device token,你会在下一步中得打它。

收到通知

是时候敲代码了。收到通知的设备必须注册到苹果推送通知服务(APNS)。在应用启动的时候你要发送一个唯一的token

打开AppDelegate.swift然后添加如下方法。
注意:该代码是基于Swift3.0。语法可能看起来不同于你之前使用过的。

func registerPushNotifications() {
  DispatchQueue.main.async {
    let settings = UIUserNotificationSettings(types: [.badge, .sound, .alert], categories: nil)
    UIApplication.shared().registerUserNotificationSettings(settings)
  }
}

我之后会解释,在这个设置中你会收到指定的通知类型。调用这个方法在应用程序启动的的文件里。

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
  registerPushNotifications()
  return true
}

此时,应用程序将自动弹出一个Alert,询问用户是否要收到该通知。

通知必须被注册,才能发送,而是否接受通知则需要用户批准。UIApplicationDelegate方法处理响应。

func application(_ application: UIApplication, didRegister notificationSettings: UIUserNotificationSettings) {
  if notificationSettings.types != UIUserNotificationType() {
    application.registerForRemoteNotifications()
  }
}

首先检查用户授予权限,然后调用该方法注册远程通知。当请求完成后者将调用另一个代理方法。这个方法响应包含一个device token,你可以打印进行调试。在发送推送通知来识别设备需要这个device token

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
  let chars = UnsafePointer<CChar>((deviceToken as NSData).bytes)
  var token = ""

  for i in 0..<deviceToken.count {
    token += String(format: "%02.2hhx", arguments: [chars[i]])
  }

  print("Registration succeeded!")
  print("Token: ", token)
}

如果出现错误,调用下面的方法。

func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) {
  print("Registration failed!")
}

注意:重要的是在应用程序启动时要调用registerUserNotificationSettings,因为用户可以改变权限的设置。同样registerForRemoteNotifications也是很重要的,因为有些场景device token可以改变那么通知将不再发送。

到目前为止,这足以让你收到一个简单的通知。

通知内容

通过不同的通知内容,有不同的方式来使一个App来收到不同类型的通知,这些通知内容包括应用程序通知用户的信息,或者用户自定义的信息。

给用户发送通知,使用JSON格式,这个格式本身包含一个字典,对应aps的key。在这第二个字典你指定载内容和key。

最常见的是:

  • 向用户显示的通知消息。这是一个简单的字符串,或一个字典key和标题一样,正文等等。
  • 接收到通知的声音。它可以是一个定制的声音,或一个系统的声音。
  • 应用图标右上角的角标个数。将其设置为0,消除角标。
  • 有效的内容。使用值1发送一个无声的通知给用户。它不会播放任何声音,或任何角标设置,但是当通知被唤醒,应用将与服务器进行沟通。

本教程的一个简单的通知内容:

{
  "aps": {
    "alert": {
      "title":"Hello! :)",
      "body":"App closed..."
    },
    "badge":1,
    "sound":"default"
  }
}

应用程序的生命周期

拷贝device token粘贴在Pusher的token部分,拷贝这个JSON对象在Pusherd的payload部分。

试着发送第一个通知。如果设备的屏幕被锁定,它将看起来如下,但什么都不会发生,当用户点击了这个通知视图。

接受通知,你需要添加新的方法:

private func getAlert(notification: [NSObject:AnyObject]) -> (String, String) {
  let aps = notification["aps"] as? [String:AnyObject]
  let alert = aps?["alert"] as? [String:AnyObject]
  let title = alert?["title"] as? String
  let body = alert?["body"] as? String
  return (title ?? "-", body ?? "-")
}

这将返回收到的通知标题和正文,如果结构是相同的。

func notificationReceived(notification: [NSObject:AnyObject]) {
  let viewController = window?.rootViewController
  let view = viewController as? ViewController
  view?.addNotification(
    title: getAlert(notification: notification).0,
    body: getAlert(notification: notification).1)
  }

这个方法将在应用程序主要视图UITableView内添加一行(参见ViewController的完整项目代码)。

我测试了三个案例的推送通知:

当应用关闭时

如果用户打开应用程序的通知,调用didFinishLaunchingWithOptions方法更新,如下:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
  // Override point for customization after application launch.

  application.applicationIconBadgeNumber = 0; // Clear badge when app launches

  // Check if launched from notification
  if let notification = launchOptions?[UIApplicationLaunchOptionsRemoteNotificationKey] as? [String: AnyObject] {
    window?.rootViewController?.present(ViewController(), animated: true, completion: nil)
    notificationReceived(notification: notification)
    } else {
      registerPushNotifications()
    }
    return true
  }

假设用户已经看过了这个通知,那么角标就被清除了。然后,检查应用程序是从图标打开还是通过通知打开的。在第一种情况下,调用registerPushNotifications()方法然后继续之前的流程。如果应用是通过打开通知的方式运行,则调用自定义notificationReceived方法来添加行。

当应用运行在前台时

如果用户正在使用应用程序,这意味着应用程序在前台,接受通知的方法如下。在这个通知的方法中加入对tableView的处理:

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
  notificationReceived(notification: userInfo)
}

注意:在这种情况下,通知将不会发出声音。

当应用运行在后台时

在这种情况下,我添加了一个方法来清除角标数目。通知的处理和应用程序在前台的处理是一样的。

func applicationWillEnterForeground(_ application: UIApplication) {
  application.applicationIconBadgeNumber = 0; // Clear badge when app is or resumed
}

最后,这个列表中有三行来自通知的内容。

最后

随着iOS 10的通知,开发者有了更多比之前有趣的机会和不曾有的交互权限。我希望本教程中关于如何使用通知能帮助你更好的理解通知是如何工作的。

玩的开心。

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

推荐阅读更多精彩内容

  • 概述 在多数移动应用中任何时候都只能有一个应用程序处于活跃状态,如果其他应用此刻发生了一些用户感兴趣的那么通过通知...
    莫离_焱阅读 6,490评论 1 8
  • 极光推送: 1.JPush当前版本是1.8.2,其SDK的开发除了正常的功能完善和扩展外也紧随苹果官方的步伐,SD...
    Isspace阅读 6,696评论 10 16
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,599评论 18 139
  • 以前项目都比较侧重于业务,从来没有去学习或者折腾过系统的缓存这一块,在开发物联网项目的过程中,有机会在项目中搭建...
    WhatWhoWhy阅读 819评论 0 3
  • 趁年轻 艰难 趁早 因为 越晚越苦 越老越艰难
    平心看世界阅读 231评论 0 0