在上集中,我们已经构建了一个简单的待办列表应用(to-do list app),这个应用可以在待办项过期时通过本地通知提醒用户。现在,我们要在之前的基础上添加以下功能:应用图标角标上显示过期待办项的数量、通知动作的支持和在不开启应用的情况下编辑和完成待办项。

你可以在这里下载上一集的源代码。

为应用图标添加角标(Badge)

值得注意的是,我们不通过本地通知也可以为应用图标添加角标。AppDelegate 中的 applicationWillResignActive: 方法是可以实现这个功能的。在用户返回主屏幕的时候,看到应用图标时候,会触发这个方法。

func applicationWillResignActive(application: UIApplication) {
var todoItems: [TodoItem] = TodoList.sharedInstance.allItems()
var overdueItems = todoItems.filter({ (todoItem) -> Bool in
return todoItem.deadline.compare(NSDate()) != .OrderedDescending
})
UIApplication.sharedApplication().applicationIconBadgeNumber = overdueItems.count
}

虽然可行,但是并不能在待办项过期时自动更新角标的值。因为我们不能简单的在通知触发的时候增加角标的值,因此,我们可以为本地通知预设一个“applicationIconBadgeNumber”的属性值。接下来,我们在 TodoList 中写一个为每个通知设置相关角标值的方法。

func setBadgeNumbers() {
var notifications = UIApplication.sharedApplication().scheduledLocalNotifications as! [UILocalNotification]
var todoItems: [TodoItem] = self.allItems()
for notification in notifications {
var overdueItems = todoItems.filter({ (todoItem) -> Bool in
return (todoItem.deadline.compare(notification.fireDate!) != .OrderedDescending)
})
UIApplication.sharedApplication().cancelLocalNotification(notification)
notification.applicationIconBadgeNumber = overdueItems.count
UIApplication.sharedApplication().scheduleLocalNotification(notification)
}
}

虽然没有办法去更新已经计划好时间的通知,但是可以通过删除当前通知然后重新设置的方式来达到同样的效果。

applicationIconBadgeNumber这个属性可以接受的最大值是 2,147,483,647(NSIntegerMax),超过 5 位数的数字就会在图标上被截断,如图所示。而且,设置为零或负数是不会产生效果的。

我们只是需要在待办列表发生变化的时候调用这个方法。将下面这段代码添加到 TodoList 中的addItem:removeItem:两个方法之后。

self.setBadgeNumbers()

这样,当一个通知被触发的时候,角标的值会被自动更新。

如何让通知反复触发

UILocalNotificaiton实例有个属性,叫repeatInterval,可以让通知以一个固定的时长反复触发。这种方法可以很好的避免通知数量 64 的这个上限,而且一个重复的通知只会被计算一次。

不幸的是,在我们的应用中,只能在repeatIntervalapplicationIconBadgeNumber中选择一个。角标值会在每次通知被触发的时候更新。较旧的通知可能会被新的通知终结,而且恰好新的通知是重复的通知(一个重复的通知只会被计算一次),即导致角标的值会比预计的小。我们可以设置两个通知,一个是重复的通知会显示提醒和播放提示音,另一个是非重复的通知会更新角标值,会发现测试的结果角标值只有预想的一半。

重复通知的最大局限是重复的间隔(repeatInterval)不接受自定义值。你必须提供一个NSCalendarUnit值,例如HourCalendarUnitDayCalendarUnit。假如,如果你希望设置的通知每 30 分钟触发一次,那么可以通过设置两个通知(两者之间间隔 30 分钟,并都以一小时重复触发)来解决。当然了,如果你希望是每 31 分钟触发一次,那就没办法了。

后台执行通知动作

iOS 8 引进了一个很有用的新特性:通知动作(notification actions),它可以让通知由用户来触发,甚至用户没有打开应用都可以触发。让我们来实现这个功能吧:从通知横幅上直接完成或等会提醒待办项。

AppDelegate文件里可以这样写:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let completeAction = UIMutableUserNotificationAction()
completeAction.identifier = "COMPLETE_TODO"
completeAction.title = "Complete"
completeAction.activationMode = .Background
completeAction.authenticationRequired = false
completeAction.destructive = true
let remindAction = UIMutableUserNotificationAction()
remindAction.identifier = "REMIND"
remindAction.title = "Remind in 30 minutes"
remindAction.activationMode = .Background
remindAction.destructive = fal
let todoCategory = UIMutableUserNotificationCategory()
todoCategory.identifier = "TODO_CATEGORY"
todoCategory.setActions([remindAction, completeAction], forContext: .Default)
todoCategory.setActions([completeAction, remindAction], forContext: .Minimal)
application.registerUserNotificationSettings(UIUserNotificationSettings(forTypes: .Alert | .Badge | .Sou categories: NSSet(array: [todoCategory])))
return true
}

值得注意的是,上面的代码中我们调用了todoCategory.setActions()两次,分别设置了动作上下文(action contexts)。如果通知是以横幅(banner)的形式显示,那么通知动作会以迷你形式(minimal context)显示出来。如果通知是以(默认的)提示(alert) 形式显示,通知动作会显示至少 4 个操作。如下图。

我们传递到setActions:方法里的通知动作的顺序会一一对应的呈现在 UI 里,但是很奇怪的是,迷你形式里通知动作的顺序是以从右向左排列的方式显示的。

下面的代码是为了确保通知的category是为 TodoList 的addItem:方法设置的。

notification.category = "TODO_CATEGORY"

到此,我们已经可以用removeItem:方法来实现完成待办项,现在我们需要在 TodoList 里实现过会提醒的功能。

func scheduleReminderforItem(item: TodoItem) {
var notification = UILocalNotification()
notification.alertBody = "Reminder: Todo Item \"\(item.title)\" Is Overdue"
notification.alertAction = "open"
notification.fireDate = NSDate().dateByAddingTimeInterval(30 * 60)
notification.soundName = UILocalNotificationDefaultSoundName
notification.userInfo = ["title": item.title, "UUID": item.UUID]
notification.category = "TODO_CATEGOR
UIApplication.sharedApplication().scheduleLocalNotification(notification)
}

值得注意的是,我们并没有修改待办项的到期日期(或者试着取消原来的通知,虽然已经被自动删除)。现在,回到AppDelegate里,实现actions:里的处理。

func application(application: UIApplication, handleActionWithIdentifier identifier: String?, forLocalNotification notification: UILocalNotification, completionHandler: () -> Void) {
var item = TodoItem(deadline: notification.fireDate!, title: notification.userInfo!["title"] as String, UU notification.userInfo!["UUID"] as String!)
switch (identifier!) {
case "COMPLETE_TODO":
TodoList.sharedInstance.removeItem(item)
case "REMIND":
TodoList.sharedInstance.scheduleReminderforItem(item)
default:
println("Error: unexpected notification action identifier!")
}
completionHandler()
}

终于可以试着运行这个应用了(为了测试方便,建议将dateByAddingTimeInterval:设置一个较小的值)。

我们讨论了所有的非地理上(注:上一集讲到的用户进入和离开某个地理区域时,可以触发本地通知的功能)的 UILocalNotification 功能,现在已经有一个功能较全的待办项应用了,所以本系列教程到此结束。你可以在这里下载工程的源代码。

如何在 iOS 8 中使用 Swift 实现本地通知(下)的更多相关文章

  1. 如何在 iOS 8 中使用 Swift 实现本地通知(上)

    当你的应用在后台运行时,可以简单地使用本地通知把信息呈现给用户.它可以允许你显示 提醒.播放提示音和数字角标(badge).本地通知可以被以下的事件触发:计划好的时间点或者用户进入和离开某个地理区域. ...

  2. 如何在C语言中调用Swift函数

    在Apple官方的<Using Swift with Cocoa and Objectgive-C>一书中详细地介绍了如何在Objective-C中使用Swift的类以及如何在Swift中 ...

  3. 如何在IOS开发中在自己的framework中添加.bunble文件

    今天就跟大家介绍一下有关,如何在IOS开发中在自己的framework中添加.bunble文件,该文章我已经在IOS教程网(http://ios.662p.com)发布过来,个人觉得还是对大家有帮助的 ...

  4. 转 如何在IOS设备中去掉屏幕上的status bar

    引入如何在IOS设备中去掉屏幕上的status bar,即:不显示设备上方的[网络.时间.电池??]条?操作方法一:在-info.list项目文件中,加上“Status bar is initiall ...

  5. 如何在iOS设备中配置S/MIME邮件签名证书

    本篇将介绍如何在iOS设备(如iPhone或iPad)上导入.配置并使用S/MIME邮件证书. 前置条件: iOS设备上已完成邮箱账号配置: 您的S/MIME邮件证书PFX/P12文件已导出备用. 步 ...

  6. <转>如何在iOS 7中设置barTintColor实现类似网易和 Facebook 的 navigationBar 效果

    转自:i‘m Allen的博客 先给代码:https://github.com/allenhsu/CRNavigationController 1. 问题的表现 相信很多人在 iOS 7 的适配过程中 ...

  7. iOS OC中桥接swift第三方库

    swift中有一些比较好的框架,比如绘图框架charts,最近项目中刚好用到,通过Pod的方式直接导入,xcode会自动生成charts-swift.h的文件,然后在需要导入的地方import < ...

  8. ios开发——实用技术OC-Swift篇&本地通知与远程通知详解

    本地通知与远程通知详解 一:本地通知   Local Notification的作用 Local Notification(本地通知) :是根据本机状态做出的通知行为,因此,凡是仅需依赖本机状态即可判 ...

  9. iOS监听模式系列之本地通知Notification

    本地通知 本地通知是由本地应用触发的,它是基于时间行为的一种通知形式,例如闹钟定时.待办事项提醒,又或者一个应用在一段时候后不使用通常会提示用户使用此应用等都是本地通知.创建一个本地通知通常分为以下几 ...

随机推荐

  1. Scrum角色

    产品负责人(Product Owner)的职责如下: 确定产品的功能. 决定发布的日期和发布内容. 为产品的profitability       of the product (ROI)负责. 根据 ...

  2. WebSocket with Flask

    转自:https://blog.shonenada.com/post/websocket-with-flask/ WebSocket with Flask HTML5 以前,HTML 还不支持 Web ...

  3. Numpy矩阵取列向量

    >>> A=matrix("1 2;3 4") >>> A matrix([[1, 2], [3, 4]]) >>> A[:, ...

  4. html5页面中拨打电话的方式

    <a href="tel:18688888888">拨号</a> <a href="sms:18688888888">发短信 ...

  5. 如何调试最新的asp.net mvc源码

    vs2013调试 一.源码当前为5.2.0.0,按下面改为5.0.0.1 二./web.config 版本为5.0.0.0 改为5.0.0.1 三.vs2013 x86 本机工具命令提示 sn.exe ...

  6. hdu5072-Coprime(容斥原理)

    题意:给N个互不相同的数,选择出两两互质或者两两不互质的三个数,有多少种选法. 题解:一共有C(N,3)中选择方式,减去不符合要求的,剩下的就是答案. 详见 http://blog.csdn.net/ ...

  7. 第三百二十二天 how can I 坚持

    昨晚好像一直在做梦,模模糊糊的,其实很难受. 真不知道该怎么办了,是没有勇气,还是怕什么,总之, 不知道该咋办了. 搞不懂. 回来第二天了,节奏又一点的开始了,一年又会很快过去. 刘松说要来北京,整天 ...

  8. 异步编程之Promise(2):探究原理

    异步编程系列教程: (翻译)异步编程之Promise(1)--初见魅力 异步编程之Promise(2):探究原理 异步编程之Promise(3):拓展进阶 异步编程之Generator(1)--领略魅 ...

  9. Configure the Struts Tag Libraries

    In Struts framework, you always need to configure the Struts tag libraries in order to access it in ...

  10. 【全面完美方案】iPhone 4S WiFi变灰 DIY修复方式

    这是我在一位台湾网友usaretama发表的一篇帖子中看到的,原帖我发表在维维网 如果你有WiFi开关变灰不能切换.WiFi遇到搜不到AP或搜到了连不上,那您就要注意这篇了. 家人的 iPhone 4 ...