{"id":3206,"date":"2016-09-17T19:53:52","date_gmt":"2016-09-18T01:53:52","guid":{"rendered":"http:\/\/dev.iachieved.it\/iachievedit\/?p=3206"},"modified":"2018-05-23T17:57:27","modified_gmt":"2018-05-23T22:57:27","slug":"notifications-and-userinfo-with-swift-3-0","status":"publish","type":"post","link":"https:\/\/dev.iachieved.it\/iachievedit\/notifications-and-userinfo-with-swift-3-0\/","title":{"rendered":"Notifications and userInfo with Swift 3.0"},"content":{"rendered":"<p><img decoding=\"async\" src=\"https:\/\/img.shields.io\/badge\/Xcode-8.0-blue.svg?style=flat\" alt=\"Xcode 8.0\" \/> <img decoding=\"async\" src=\"https:\/\/img.shields.io\/badge\/Swift-3.0-orange.svg?style=flat\" alt=\"Swift 3.0\" \/><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/img.shields.io\/badge\/Xcode-9.3-blue.svg?style=flat\" alt=\"Xcode 9.3\" \/> <img decoding=\"async\" src=\"https:\/\/img.shields.io\/badge\/Swift-4.1-orange.svg?style=flat\" alt=\"Swift 4.1\" \/><\/p>\n<p><b>Editor&#8217;s Note:<\/b>  This is one of our most popular posts, so I wanted to take a moment and verify that the Swift 3.0 code presented below is still accurate with Swift 4.1.  I&#8217;m happy to say it still is, so enjoy posting <code>Notification<\/code>s with <code>userInfo<\/code> in Swift 4!<\/p>\n<p>Swift 3.0 has brought a number of changes to the Swift language, including the <a href=\"https:\/\/developer.apple.com\/videos\/play\/wwdc2016\/403\/\">Great Renaming<\/a> which brought about the end of the <code>NS<\/code> prefix on Foundation classes.  <code>NSThread<\/code> is now simply <code>Thread<\/code>.  <code>NSData<\/code> becomes <code>Data<\/code>.  You get the idea.<\/p>\n<p>That means we need to provide an update on using <code>NSNotificationCenter<\/code>, sorry, <code>NotificationCenter<\/code> with <code>userInfo<\/code>.  Things have definitely changed between Swift 2 and Swift 3.<\/p>\n<p>The technique for obtaining the default <code>NotificationCenter<\/code> has changed, and can now be done with <code>let nc = NotificationCenter.default<\/code>.  In addition the model of using selectors <i>has changed<\/i> to specifying a block or funtion to execute when the notificaiton is received.<\/p>\n<p>For example, in Swift 2 we would write:<\/p>\n<pre class=\"lang:swift\">\nlet nc = NSNotificationCenter.defaultCenter()\nnc.addObserver(self, \n               selector: #selector(ViewController.catchNotification),\n               name: \"MyNotification\", \n               object: nil)\n<\/pre>\n<p>whereas Swift 3 code would look like this:<\/p>\n<pre class=\"lang:swift\">\nlet nc = NotificationCenter.default \/\/ Note that default is now a property, not a method call\nnc.addObserver(forName:Notification.Name(rawValue:\"MyNotification\"),\n               object:nil, queue:nil,\n               using:catchNotification)\n<\/pre>\n<p>In this example we&#8217;re instructing the notification center to deliver <code>MyNotification<\/code> notifications to the <code>catchNotification<\/code> function which has a signature of <code>(Notification) -&gt; Void<\/code>.  Alternatively we could use a trailing closure:<\/p>\n<pre class=\"lang:swift\">\nlet nc = NotificationCenter.default \/\/ Note that default is now a property, not a method call\nnc.addObserver(forName:Notification.Name(rawValue:\"MyNotification\"),\n               object:nil, queue:nil) {\n  notification in\n  \/\/ Handle notification\n}\n<\/pre>\n<h3>Post It!<\/h3>\n<p>Now, let&#8217;s look at <i>posting<\/i> (sending) a notification.  The <code>postNotificationName<\/code> method in Swift 2.0 has been replaced with <code>post<\/code> in Swift 3.0.<\/p>\n<pre class=\"lang:swift\">\nlet nc = NotificationCenter.default\nnc.post(name:Notification.Name(rawValue:\"MyNotification\"),\n        object: nil,\n        userInfo: [\"message\":\"Hello there!\", \"date\":Date()])\n<\/pre>\n<p>The <code>userInfo<\/code> now takes <code>[AnyHashable:Any]?<\/code> as an argument, which we provide as a dictionary literal in Swift.  Note that the <code>userInfo<\/code> values don&#8217;t need to be homogeneous (that&#8217;s where the <code>Any<\/code> comes in); we are sending along a <code>String<\/code> and a <code>Date<\/code>.<\/p>\n<h3>Handling Notifications<\/h3>\n<p>The <code>guard<\/code> construct serves as a good method to unwrap and verify that the expected data is in the <code>userInfo<\/code>.<\/p>\n<pre class=\"lang:swift\">\n  func catchNotification(notification:Notification) -> Void {\n    print(\"Catch notification\")\n    \n    guard let userInfo = notification.userInfo,\n          let message  = userInfo[\"message\"] as? String,\n          let date     = userInfo[\"date\"]    as? Date else {\n      print(\"No userInfo found in notification\")\n      return\n    }\n    \n    let alert = UIAlertController(title: \"Notification!\",\n                                  message:\"\\(message) received at \\(date)\",\n                                  preferredStyle: UIAlertControllerStyle.alert)\n    alert.addAction(UIAlertAction(title: \"OK\", style: UIAlertActionStyle.default, handler: nil))\n    self.present(alert, animated: true, completion: nil)\n    \n  }\n<\/pre>\n<p>To verify that the <code>guard<\/code> works properly switch out the <code>Date()<\/code> in the call to <code>post<\/code> with a <code>String<\/code> or some other object.  You should see <code>No userInfo found in notification<\/code> printed to the console.<\/p>\n<h3>Example Source<\/h3>\n<p>You can try out the code above with a simple iOS project.  Create a new <b>Single View Application<\/b> and replace the contents of <code>ViewController.swift<\/code> with the following:<\/p>\n<pre class=\"lang:swift\">\nimport UIKit\n\nclass ViewController: UIViewController {\n  \n  let myNotification = Notification.Name(rawValue:\"MyNotification\")\n\n  override func viewDidLoad() {\n    super.viewDidLoad()\n    \n    let nc = NotificationCenter.default\n    nc.addObserver(forName:myNotification, object:nil, queue:nil, using:catchNotification)\n  }\n  \n  override func viewDidAppear(_ animated: Bool) {\n    super.viewDidAppear(animated)\n    let nc = NotificationCenter.default\n    nc.post(name:myNotification,\n            object: nil,\n            userInfo:[\"message\":\"Hello there!\", \"date\":Date()])\n  }\n  \n  func catchNotification(notification:Notification) -> Void {\n    print(\"Catch notification\")\n    \n    guard let userInfo = notification.userInfo,\n          let message  = userInfo[\"message\"] as? String,\n          let date     = userInfo[\"date\"]    as? Date else {\n        print(\"No userInfo found in notification\")\n        return\n    }\n    \n    let alert = UIAlertController(title: \"Notification!\",\n                                  message:\"\\(message) received at \\(date)\",\n                                  preferredStyle: UIAlertControllerStyle.alert)\n    alert.addAction(UIAlertAction(title: \"OK\", style: UIAlertActionStyle.default, handler: nil))\n    self.present(alert, animated: true, completion: nil)\n  }\n}\n<\/pre>\n<p>A few notes here:<\/p>\n<ul>\n<li>`Notification` &#8220;names&#8221; are no longer strings, but are of type `Notification.Name`, hence why we declare `let myNotification = Notification.Name(rawValue:&#8221;MyNotification&#8221;)`.  This allows us to use `myNotification` anywhere a `Notification.Name` is expected, i.e., the `NotificationCenter.addObserver` and `NotificationCenter.post` functions.\n<li>We chose to have a separate `func` for `catchNotification` here rather than utilizing a trailing closure.\n<\/ul>\n<p>And that&#8217;s it!  Simple and effective.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Editor&#8217;s Note: This is one of our most popular posts, so I wanted to take a moment and verify that the Swift 3.0 code presented below is still accurate with Swift 4.1. I&#8217;m happy to say it still is, so enjoy posting Notifications with userInfo in Swift 4! Swift 3.0 has brought a number of [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":3108,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[63],"class_list":["post-3206","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-swift","tag-swift-notification-tutorial"],"_links":{"self":[{"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts\/3206"}],"collection":[{"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/comments?post=3206"}],"version-history":[{"count":10,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts\/3206\/revisions"}],"predecessor-version":[{"id":3416,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts\/3206\/revisions\/3416"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/media\/3108"}],"wp:attachment":[{"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/media?parent=3206"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/categories?post=3206"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/tags?post=3206"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}