{"id":1730,"date":"2015-03-04T21:55:05","date_gmt":"2015-03-05T03:55:05","guid":{"rendered":"http:\/\/jamesonquave.com\/blog\/?p=1730"},"modified":"2016-09-25T18:42:21","modified_gmt":"2016-09-26T00:42:21","slug":"local-notifications-in-ios-8-with-swift-part-2","status":"publish","type":"post","link":"https:\/\/jamesonquave.com\/blog\/local-notifications-in-ios-8-with-swift-part-2\/","title":{"rendered":"Local Notifications in iOS 9+ with Swift (Part 2)"},"content":{"rendered":"<p><span style=\"color: #0000ff\"><strong>This post has been updated for compatibility with XCode 8\u00a0and iOS 10<\/strong><\/span><\/p>\n<p>In <a href=\"http:\/\/jamesonquave.com\/blog\/local-notifications-in-ios-8-with-swift-part-1\/\">part 1<\/a> of this series, we created a simple to-do list application that used local notifications to alert users when to-do items were overdue. This time, we\u2019re going to build on that the project by enabling application icon badges to display the number of overdue items and add support for notification actions, allowing our users to complete and edit to-do items without even opening the app.<\/p>\n<p>You can download the source code for part 1 <a href=\"https:\/\/github.com\/jasonbnewell\/LocalNotificationTutorials\/tree\/part1_simplified\">here<\/a>.<\/p>\n<h1><strong>Badging the App Icon<\/strong><\/h1>\n<p>It bears mentioning that we can badge the app icon without using local notifications. The applicationWillResignActive: method in AppDelegate is a good place to do so, since it will be fired just before the user returns to the home screen where they can see the app icon.<\/p>\n<pre class=\"\u201cbrush:js\u201d\">func applicationWillResignActive(_ application: UIApplication) { \/\/ fired when user quits the application\r\n    let todoItems: [TodoItem] = TodoList.sharedInstance.allItems() \/\/ retrieve list of all to-do items\r\n    let overdueItems = todoItems.filter({ (todoItem) -&gt; Bool in\r\n        return todoItem.deadline.compare(Date()) != .orderedDescending\r\n    })\r\n    UIApplication.shared.applicationIconBadgeNumber = overdueItems.count \/\/ set our badge number to number of overdue items\r\n}\r\n<\/pre>\n<p><a href=\"http:\/\/jamesonquave.com\/blog\/wp-content\/uploads\/iOS-Simulator-Screen-Shot-Feb-4-2015-10.31.14-PM.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone wp-image-1731\" src=\"http:\/\/jamesonquave.com\/blog\/wp-content\/uploads\/iOS-Simulator-Screen-Shot-Feb-4-2015-10.31.14-PM.png\" alt=\"iOS Simulator Screen Shot Feb 4, 2015, 10.31.14 PM\" width=\"250\" height=\"441\" \/><\/a> <a href=\"http:\/\/jamesonquave.com\/blog\/wp-content\/uploads\/iOS-Simulator-Screen-Shot-Feb-4-2015-11.51.25-PM.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone wp-image-1732\" src=\"http:\/\/jamesonquave.com\/blog\/wp-content\/uploads\/iOS-Simulator-Screen-Shot-Feb-4-2015-11.51.25-PM.png\" alt=\"iOS Simulator Screen Shot Feb 4, 2015, 11.51.25 PM\" width=\"250\" height=\"441\" \/><\/a><\/p>\n<p>This is a good start, but we need the badge number to automatically update when to-do items become overdue. Unfortunately, we can\u2019t instruct the app to simply increment the badge value when our notifications fire, but we can pre-compute and provide a value for the \u201capplicationIconBadgeNumber\u201d property of our local notifications. Lets provide a method in TodoList to set an associated badge number for each notification.<\/p>\n<pre class=\"\u201cbrush:js\u201d\">func setBadgeNumbers() {\r\n    let scheduledNotifications: [UILocalNotification]? = UIApplication.shared.scheduledLocalNotifications \/\/ all scheduled notifications\r\n    guard scheduledNotifications != nil else {return} \/\/ nothing to remove, so return\r\n \r\n    let todoItems: [TodoItem] = self.allItems()\r\n \r\n    \/\/ we can't modify scheduled notifications, so we'll loop through the scheduled notifications and\r\n    \/\/ unschedule\/reschedule items which need to be updated.\r\n    var notifications: [UILocalNotification] = []\r\n\r\n    for notification in scheduledNotifications! {\r\n        print(UIApplication.shared.scheduledLocalNotifications!.count)\r\n        let overdueItems = todoItems.filter({ (todoItem) -&gt; Bool in \/\/ array of to-do items in which item deadline is on or before notification fire date\r\n            return (todoItem.deadline.compare(notification.fireDate!) != .orderedDescending)\r\n        })\r\n\r\n        \/\/ set new badge number\r\n        notification.applicationIconBadgeNumber = overdueItems.count \r\n        notifications.append(notification)\r\n    }\r\n \r\n    \/\/ don't modify a collection while you're iterating through it\r\n    UIApplication.shared.cancelAllLocalNotifications() \/\/ cancel all notifications\r\n \r\n    for note in notifications {\r\n        UIApplication.shared.scheduleLocalNotification(note) \/\/ reschedule the new versions\r\n    }\r\n}\r\n<\/pre>\n<p>There\u2019s no way to update a scheduled notification, but you can achieve the same effect by simply canceling the notification, making your changes and rescheduling it.<\/p>\n<p>The applicationIconBadgeNumber property can accept values up to 2,147,483,647 (NSIntegerMax), though anything over five digits will be truncated in the icon badge. Setting it to zero or a negative number will result in no change.<\/p>\n<p><a href=\"http:\/\/jamesonquave.com\/blog\/wp-content\/uploads\/Screen-Shot-2015-02-04-at-11.38.14-PM.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-1739\" src=\"http:\/\/jamesonquave.com\/blog\/wp-content\/uploads\/Screen-Shot-2015-02-04-at-11.36.36-PM.png\" alt=\"Screen Shot 2015-02-04 at 11.36.36 PM\" width=\"120\" height=\"133\" \/><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-1740\" src=\"http:\/\/jamesonquave.com\/blog\/wp-content\/uploads\/Screen-Shot-2015-02-04-at-11.38.14-PM.png\" alt=\"Screen Shot 2015-02-04 at 11.38.14 PM\" width=\"120\" height=\"133\" \/><\/a><\/p>\n<p>Now we just need to call this method when our to-do list changes. Add the following line to the bottom of addItem: and removeItem: in TodoList<\/p>\n<pre class=\"\u201cbrush:js\u201d\">self.setBadgeNumbers()\r\n<\/pre>\n<p>Now, when a notification fires, the badge number will be automatically updated.<\/p>\n<h1><strong>Repeating Notifications<\/strong><\/h1>\n<p>UILocalNotificaiton instances have a repeatInterval property that we can use to, unsurprisingly, repeat a notification at a regular interval. This is a good way to get around the 64 notification limit in some cases; a repeating notification is only counted against it once.<\/p>\n<p>Unfortunately, we have to choose between using repeatInterval and applicationIconBadgeNumber in this app. Badge numbers are set on the application icon each time a notification is fired. Older notifications could end up \u201cout of phase\u201d with newer notifications and actually <em>lower<\/em> the badge number when repeated. We could get around this by scheduling two notifications for each to-do item, a repeating notification that displays the alert and plays the sound, and a non-repeating notification that updates the badge count, but this would cut the number of to-do items we could schedule in half.<\/p>\n<p>The biggest limitation with repeating notifications is that the repeatInterval doesn\u2019t accept a custom time interval. You have to provide an NSCalendarUnit value like \u201cHourCalendarUnit\u201d or \u201cDayCalendarUnit\u201d. If you want a notification to fire every 30 minutes, for example, you\u2019ll have to schedule two notifications (offset by 30 minutes) and set them both to repeat hourly. If you want it to fire every 31 minutes, then you\u2019re out of luck.<\/p>\n<h1><strong>Performing Actions in the Background<\/strong><\/h1>\n<p>iOS 8 introduced a really useful new feature, notification actions, which let our users trigger code execution without even having to open the app. Lets give our users the ability to complete and schedule reminders for to-do items directly from the notification banner.<\/p>\n<p><a href=\"http:\/\/jamesonquave.com\/blog\/wp-content\/uploads\/iOS-Simulator-Screen-Shot-Feb-6-2015-12.43.34-AM.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone wp-image-1737\" src=\"http:\/\/jamesonquave.com\/blog\/wp-content\/uploads\/iOS-Simulator-Screen-Shot-Feb-6-2015-12.43.34-AM.png\" alt=\"iOS Simulator Screen Shot Feb 6, 2015, 12.43.34 AM\" width=\"250\" height=\"441\" \/><\/a> <a href=\"http:\/\/jamesonquave.com\/blog\/wp-content\/uploads\/iOS-Simulator-Screen-Shot-Feb-6-2015-12.43.37-AM.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone wp-image-1738\" src=\"http:\/\/jamesonquave.com\/blog\/wp-content\/uploads\/iOS-Simulator-Screen-Shot-Feb-6-2015-12.43.37-AM.png\" alt=\"iOS Simulator Screen Shot Feb 6, 2015, 12.43.37 AM\" width=\"250\" height=\"441\" \/><\/a><\/p>\n<p>In AppDelegate:<\/p>\n<pre class=\"brush:js\">func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -&gt; Bool {\r\n \u00a0 \u00a0let completeAction = UIMutableUserNotificationAction()\r\n \u00a0 \u00a0completeAction.identifier = \"COMPLETE_TODO\" \/\/ the unique identifier for this action\r\n \u00a0 \u00a0completeAction.title = \"Complete\" \/\/ title for the action button\r\n \u00a0 \u00a0completeAction.activationMode = .background \/\/ UIUserNotificationActivationMode.Background - don't bring app to foreground\r\n \u00a0 \u00a0completeAction.isAuthenticationRequired = false \/\/ don't require unlocking before performing action\r\n \u00a0 \u00a0completeAction.isDestructive = true \/\/ display action in red\r\n \r\n \u00a0 \u00a0let remindAction = UIMutableUserNotificationAction()\r\n \u00a0 \u00a0remindAction.identifier = \"REMIND\"\r\n \u00a0 \u00a0remindAction.title = \"Remind in 30 minutes\"\r\n \u00a0 \u00a0remindAction.activationMode = .background\r\n \u00a0 \u00a0remindAction.isDestructive = false\r\n \r\n \u00a0 \u00a0let todoCategory = UIMutableUserNotificationCategory() \/\/ notification categories allow us to create groups of actions that we can associate with a notification\r\n \u00a0 \u00a0todoCategory.identifier = \"TODO_CATEGORY\"\r\n    todoCategory.setActions([remindAction, completeAction], for: .default) \/\/ UIUserNotificationActionContext.Default (4 actions max)\r\n    todoCategory.setActions([completeAction, remindAction], for: .minimal) \/\/ UIUserNotificationActionContext.Minimal - for when space is limited (2 actions max)\r\n\r\n    \/\/ we're now providing a set containing our category as an argument\r\n    application.registerUserNotificationSettings(UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: Set([todoCategory])))\r\n    return true\r\n}\r\n<\/pre>\n<p>Notice that we\u2019re calling todoCategory.setActions() twice, once for each of the two available action contexts. If your users are displaying notifications from your app as banners, then the actions in the minimal context will be displayed. If notifications are displayed as alerts (the \u201cdefault\u201d context), up to four actions will be displayed.<\/p>\n<p><a href=\"http:\/\/jamesonquave.com\/blog\/wp-content\/uploads\/iOS-Simulator-Screen-Shot-Feb-6-2015-12.41.20-AM.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone wp-image-1736\" src=\"http:\/\/jamesonquave.com\/blog\/wp-content\/uploads\/iOS-Simulator-Screen-Shot-Feb-6-2015-12.41.20-AM.png\" alt=\"iOS Simulator Screen Shot Feb 6, 2015, 12.41.20 AM\" width=\"250\" height=\"441\" \/><\/a>\u00a0<a href=\"http:\/\/jamesonquave.com\/blog\/wp-content\/uploads\/iOS-Simulator-Screen-Shot-Feb-6-2015-12.06.33-AM.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone wp-image-1735\" src=\"http:\/\/jamesonquave.com\/blog\/wp-content\/uploads\/iOS-Simulator-Screen-Shot-Feb-6-2015-12.06.33-AM.png\" alt=\"iOS Simulator Screen Shot Feb 6, 2015, 12.06.33 AM\" width=\"250\" height=\"441\" \/><\/a><\/p>\n<p>The order of the actions in the array we pass to setActions: is the order that the actions will be displayed in the UI, though, oddly, the items are ordered right-to-left in the minimal context.<\/p>\n<p>Lets make sure to set this category for the notification we\u2019re scheduling in TodoList\u2019s addItem: method.<\/p>\n<pre class=\"brush:js\">notification.category = \"TODO_CATEGORY\"\r\n<\/pre>\n<p>We already have a method for \u201ccompleting\u201d to-do items, removeItem:, but we need to implement one for scheduling a reminder in TodoList.<\/p>\n<pre class=\"brush:js\">func scheduleReminder(forItem item: TodoItem) {\r\n \u00a0 \u00a0let notification = UILocalNotification() \/\/ create a new reminder notification\r\n \u00a0 \u00a0notification.alertBody = \"Reminder: Todo Item \\\"\\(item.title)\\\" Is Overdue\" \/\/ text that will be displayed in the notification\r\n \u00a0 \u00a0notification.alertAction = \"open\" \/\/ text that is displayed after \"slide to...\" on the lock screen - defaults to \"slide to view\"\r\n \u00a0 \u00a0notification.fireDate = Date(timeIntervalSinceNow: 30 * 60) \/\/ 30 minutes from current time\r\n \u00a0 \u00a0notification.soundName = UILocalNotificationDefaultSoundName \/\/ play default sound\r\n \u00a0 \u00a0notification.userInfo = [\"title\": item.title, \"UUID\": item.UUID] \/\/ assign a unique identifier to the notification that we can use to retrieve it later\r\n \u00a0 \u00a0notification.category = \"TODO_CATEGORY\"\r\n \r\n \u00a0 \u00a0UIApplication.shared.scheduleLocalNotification(notification)\r\n}\r\n<\/pre>\n<p>Note that we aren\u2019t changing the due date on the to-do item (or trying to cancel the original notification \u2013 it\u2019s been automatically removed). Now we just have to jump back to AppDelegate and implement a handler for the actions:<\/p>\n<pre class=\"brush:js\">func application(_ application: UIApplication, handleActionWithIdentifier identifier: String?, for notification: UILocalNotification, completionHandler: @escaping () -&gt; Void) {\r\n \u00a0 \u00a0let item = TodoItem(deadline: notification.fireDate!, title: notification.userInfo![\"title\"] as! String, UUID: notification.userInfo![\"UUID\"] as! String!)\r\n \u00a0 \u00a0switch (identifier!) {\r\n \u00a0 \u00a0case \"COMPLETE_TODO\":\r\n \u00a0 \u00a0    TodoList.sharedInstance.remove(item)\r\n \u00a0 \u00a0case \"REMIND\":\r\n \u00a0 \u00a0    TodoList.sharedInstance.scheduleReminder(forItem: item)\r\n \u00a0 \u00a0default: \/\/ switch statements must be exhaustive - this condition should never be met\r\n \u00a0 \u00a0    print(\"Error: unexpected notification action identifier!\")\r\n \u00a0 \u00a0}\r\n\u00a0 \u00a0 completionHandler() \/\/ per developer documentation, app will terminate if we fail to call this\r\n}\r\n<\/pre>\n<p>Go ahead and try it out now (you may want to pass a lower value to dateByAddingTimeInterval: for testing purposes).<\/p>\n<p><a href=\"http:\/\/jamesonquave.com\/blog\/wp-content\/uploads\/iOS-Simulator-Screen-Shot-Feb-6-2015-1.25.36-AM.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone wp-image-1733\" src=\"http:\/\/jamesonquave.com\/blog\/wp-content\/uploads\/iOS-Simulator-Screen-Shot-Feb-6-2015-1.25.36-AM.png\" alt=\"iOS Simulator Screen Shot Feb 6, 2015, 1.25.36 AM\" width=\"250\" height=\"438\" \/><\/a><\/p>\n<p>We\u2019ve covered all of the non-geographic functionality of UILocalNotification and now have a pretty full-featured to-do list app, so this concludes our series. You can download the full source code for this project from <a href=\"https:\/\/github.com\/jasonbnewell\/LocalNotificationTutorials\/tree\/part2_simplified\">here<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This post has been updated for compatibility with XCode 8\u00a0and iOS 10 In part 1 of this series, we created a simple to-do list application that used local notifications to alert users when to-do items were overdue. This time, we\u2019re going to build on that the project by enabling application icon badges to display the&#8230;<\/p>\n","protected":false},"author":4,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_links_to":"","_links_to_target":""},"categories":[50,26,21,25,10,5,32],"tags":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v19.13 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Local Notifications in iOS 9+ with Swift (Part 2) - Jameson Quave<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/jamesonquave.com\/blog\/local-notifications-in-ios-8-with-swift-part-2\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Local Notifications in iOS 9+ with Swift (Part 2) - Jameson Quave\" \/>\n<meta property=\"og:description\" content=\"This post has been updated for compatibility with XCode 8\u00a0and iOS 10 In part 1 of this series, we created a simple to-do list application that used local notifications to alert users when to-do items were overdue. This time, we\u2019re going to build on that the project by enabling application icon badges to display the...\" \/>\n<meta property=\"og:url\" content=\"https:\/\/jamesonquave.com\/blog\/local-notifications-in-ios-8-with-swift-part-2\/\" \/>\n<meta property=\"og:site_name\" content=\"Jameson Quave\" \/>\n<meta property=\"article:published_time\" content=\"2015-03-05T03:55:05+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2016-09-26T00:42:21+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/jamesonquave.com\/blog\/wp-content\/uploads\/iOS-Simulator-Screen-Shot-Feb-4-2015-10.31.14-PM.png\" \/>\n<meta name=\"author\" content=\"Jason Newell\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Jason Newell\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/jamesonquave.com\/blog\/local-notifications-in-ios-8-with-swift-part-2\/\",\"url\":\"https:\/\/jamesonquave.com\/blog\/local-notifications-in-ios-8-with-swift-part-2\/\",\"name\":\"Local Notifications in iOS 9+ with Swift (Part 2) - Jameson Quave\",\"isPartOf\":{\"@id\":\"https:\/\/jamesonquave.com\/blog\/#website\"},\"datePublished\":\"2015-03-05T03:55:05+00:00\",\"dateModified\":\"2016-09-26T00:42:21+00:00\",\"author\":{\"@id\":\"https:\/\/jamesonquave.com\/blog\/#\/schema\/person\/f9280beb862ff805cb1e4545311f8c4b\"},\"breadcrumb\":{\"@id\":\"https:\/\/jamesonquave.com\/blog\/local-notifications-in-ios-8-with-swift-part-2\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/jamesonquave.com\/blog\/local-notifications-in-ios-8-with-swift-part-2\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/jamesonquave.com\/blog\/local-notifications-in-ios-8-with-swift-part-2\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/jamesonquave.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Local Notifications in iOS 9+ with Swift (Part 2)\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/jamesonquave.com\/blog\/#website\",\"url\":\"https:\/\/jamesonquave.com\/blog\/\",\"name\":\"Jameson Quave\",\"description\":\"Using computer technology to educate, and improve lives.\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/jamesonquave.com\/blog\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/jamesonquave.com\/blog\/#\/schema\/person\/f9280beb862ff805cb1e4545311f8c4b\",\"name\":\"Jason Newell\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/jamesonquave.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/575497a137605d6bb40c2a2e0f77d0b9?s=96&d=retro&r=pg\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/575497a137605d6bb40c2a2e0f77d0b9?s=96&d=retro&r=pg\",\"caption\":\"Jason Newell\"},\"description\":\"Jason Newell is a full-stack web and application developer specializing in server-side Ruby, Swift, and most recently TVML. Most recently, Jason has developed the DAD App platform for Apple TV.\",\"url\":\"https:\/\/jamesonquave.com\/blog\/author\/newell-jasonb\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Local Notifications in iOS 9+ with Swift (Part 2) - Jameson Quave","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/jamesonquave.com\/blog\/local-notifications-in-ios-8-with-swift-part-2\/","og_locale":"en_US","og_type":"article","og_title":"Local Notifications in iOS 9+ with Swift (Part 2) - Jameson Quave","og_description":"This post has been updated for compatibility with XCode 8\u00a0and iOS 10 In part 1 of this series, we created a simple to-do list application that used local notifications to alert users when to-do items were overdue. This time, we\u2019re going to build on that the project by enabling application icon badges to display the...","og_url":"https:\/\/jamesonquave.com\/blog\/local-notifications-in-ios-8-with-swift-part-2\/","og_site_name":"Jameson Quave","article_published_time":"2015-03-05T03:55:05+00:00","article_modified_time":"2016-09-26T00:42:21+00:00","og_image":[{"url":"http:\/\/jamesonquave.com\/blog\/wp-content\/uploads\/iOS-Simulator-Screen-Shot-Feb-4-2015-10.31.14-PM.png"}],"author":"Jason Newell","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Jason Newell","Est. reading time":"6 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/jamesonquave.com\/blog\/local-notifications-in-ios-8-with-swift-part-2\/","url":"https:\/\/jamesonquave.com\/blog\/local-notifications-in-ios-8-with-swift-part-2\/","name":"Local Notifications in iOS 9+ with Swift (Part 2) - Jameson Quave","isPartOf":{"@id":"https:\/\/jamesonquave.com\/blog\/#website"},"datePublished":"2015-03-05T03:55:05+00:00","dateModified":"2016-09-26T00:42:21+00:00","author":{"@id":"https:\/\/jamesonquave.com\/blog\/#\/schema\/person\/f9280beb862ff805cb1e4545311f8c4b"},"breadcrumb":{"@id":"https:\/\/jamesonquave.com\/blog\/local-notifications-in-ios-8-with-swift-part-2\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/jamesonquave.com\/blog\/local-notifications-in-ios-8-with-swift-part-2\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/jamesonquave.com\/blog\/local-notifications-in-ios-8-with-swift-part-2\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/jamesonquave.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Local Notifications in iOS 9+ with Swift (Part 2)"}]},{"@type":"WebSite","@id":"https:\/\/jamesonquave.com\/blog\/#website","url":"https:\/\/jamesonquave.com\/blog\/","name":"Jameson Quave","description":"Using computer technology to educate, and improve lives.","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/jamesonquave.com\/blog\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/jamesonquave.com\/blog\/#\/schema\/person\/f9280beb862ff805cb1e4545311f8c4b","name":"Jason Newell","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/jamesonquave.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/575497a137605d6bb40c2a2e0f77d0b9?s=96&d=retro&r=pg","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/575497a137605d6bb40c2a2e0f77d0b9?s=96&d=retro&r=pg","caption":"Jason Newell"},"description":"Jason Newell is a full-stack web and application developer specializing in server-side Ruby, Swift, and most recently TVML. Most recently, Jason has developed the DAD App platform for Apple TV.","url":"https:\/\/jamesonquave.com\/blog\/author\/newell-jasonb\/"}]}},"_links":{"self":[{"href":"https:\/\/jamesonquave.com\/blog\/wp-json\/wp\/v2\/posts\/1730"}],"collection":[{"href":"https:\/\/jamesonquave.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jamesonquave.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jamesonquave.com\/blog\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/jamesonquave.com\/blog\/wp-json\/wp\/v2\/comments?post=1730"}],"version-history":[{"count":9,"href":"https:\/\/jamesonquave.com\/blog\/wp-json\/wp\/v2\/posts\/1730\/revisions"}],"predecessor-version":[{"id":2187,"href":"https:\/\/jamesonquave.com\/blog\/wp-json\/wp\/v2\/posts\/1730\/revisions\/2187"}],"wp:attachment":[{"href":"https:\/\/jamesonquave.com\/blog\/wp-json\/wp\/v2\/media?parent=1730"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jamesonquave.com\/blog\/wp-json\/wp\/v2\/categories?post=1730"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jamesonquave.com\/blog\/wp-json\/wp\/v2\/tags?post=1730"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}