{"id":2319,"date":"2015-12-27T20:56:04","date_gmt":"2015-12-28T02:56:04","guid":{"rendered":"http:\/\/dev.iachieved.it\/iachievedit\/?p=2319"},"modified":"2015-12-27T20:56:04","modified_gmt":"2015-12-28T02:56:04","slug":"foundation-on-linux","status":"publish","type":"post","link":"https:\/\/dev.iachieved.it\/iachievedit\/foundation-on-linux\/","title":{"rendered":"Foundation on Linux"},"content":{"rendered":"<p>It is an exciting time to be a Swift enthusiast.  The language is now <a href=\"https:\/\/swift.org\/\">open source<\/a> <i>and<\/i> has been ported to Linux.  And if that wasn&#8217;t enough, folks at Apple and elsewhere across the globe are also working to port over <a href=\"https:\/\/developer.apple.com\/library\/mac\/documentation\/Cocoa\/Reference\/Foundation\/ObjC_classic\/index.html\">Foundation<\/a> and <a href=\"https:\/\/en.wikipedia.org\/wiki\/Grand_Central_Dispatch\">Grand Central Dispatch<\/a>.<\/p>\n<p>If you&#8217;re coming to Swift from a mostly Linux background, you might not be aware of either Foundation or GCD, or why they are important.  Simply put, Foundation is a<br \/>\ncollection of utility classes designed to provide implementations for frequently used routines and tasks.<\/p>\n<p>We&#8217;re not going to look at all of the functionality Foundation provides but will instead look at two classes:  <code>NSThread<\/code> and <code>NSNotification<\/code>.  Moreover, the idea behind this post is less about an exhaustive review of the functionality provided by the classes and more about beginning to get our new Swift on Linux users familiarity with Foundation.<\/p>\n<h2>NSThread<\/h2>\n<p>NSThread is Foundation&#8217;s portable <a href=\"https:\/\/en.wikipedia.org\/wiki\/Thread_(computing)\">thread<\/a> class.  Built upon <a href=\"https:\/\/en.wikipedia.org\/wiki\/POSIX_Threads\">POSIX threads<\/a>, NSThread provides you with the ability to create a thread, start it, check its status, etc.<\/p>\n<p>An <code>NSThread<\/code> is easy to create, and notice that it takes a block as its <code>init<\/code> argument.<\/p>\n<pre class=\"lang:swift\">\r\nimport Foundation\r\nimport Glibc\r\n\r\nlet thread = NSThread(){\r\n  print(\"Entering thread\")\r\n  for i in (1...10).reverse() {\r\n    print(\"\\(i)...\", terminator:\"\")\r\n    fflush(stdout)\r\n    sleep(1)\r\n  }\r\n  print(\"Exiting thread\") \r\n}\r\n<\/pre>\n<p>As it stands you can compile the above code, but it won&#8217;t do anything because we didn&#8217;t <code>start()<\/code> our thread.  Add <code>thread.start()<\/code> at the end and run it.  Here&#8217;s what we get:<\/p>\n<pre class=\"crayon:false\">\r\nswift threadexample.swift\r\nEntering thread\r\n10...\r\n<\/pre>\n<p>That won&#8217;t do!  Our application exits before the thread is complete.  One way to solve this is to raise a &#8220;done&#8221; flag when the thread completes.  We then go to sleep on the main process until the flag is set.<\/p>\n<pre class=\"lang:swift\">\r\nimport Foundation\r\nimport Glibc\r\n\r\nvar done   = false\r\nlet thread = NSThread(){\r\n  print(\"Entering thread\")\r\n  for i in (1...10).reverse() {\r\n    print(\"\\(i)...\", terminator:\"\")\r\n    fflush(stdout)\r\n    sleep(1)\r\n  }\r\n  print(\"\\nExiting thread\") \r\n  done = true\r\n}\r\n\r\nthread.start()\r\n\r\nwhile !done {\r\n  sleep(1)\r\n}\r\n\r\nprint(\"Done\")\r\n<\/pre>\n<p>Note that the <code>sleep(1)<\/code> in our main thread is simply yielding up the CPU so we aren&#8217;t creating a busy-wait, but it does have the annoying side effect of not ending execution until after the <code>sleep<\/code> returns.<\/p>\n<pre> \r\nEntering thread\r\n10...9...8...7...6...5...4...3...2...1...\r\nExiting thread\r\nDone\r\n<\/pre>\n<p>Even better is removing the <code>done<\/code> flag and putting a &#8220;main event loop&#8221; in, like this:<\/p>\n<pre class=\"lang:swift\">\r\nimport Foundation\r\nimport Glibc\r\n\r\nlet thread = NSThread(){\r\n  print(\"Entering thread\")\r\n  for i in (1...10).reverse() {\r\n    print(\"\\(i)...\", terminator:\"\")\r\n    fflush(stdout)\r\n    sleep(1)\r\n  }\r\n  print(\"\\nExiting thread\") \r\n  print(\"Done\")\r\n  exit(0)\r\n}\r\n\r\nthread.start()\r\n\r\nselect(0, nil, nil, nil, nil)\r\n<\/pre>\n<p>In this case our thread is now responsible for ending the application.  Our <code>select<\/code> statement is a fake event loop; it never returns but the application continues to run other threads driven by incoming events. <\/p>\n<h2>NSNotification<\/h2>\n<p>Anyone that has worked with Cocoa and OS X or iOS development has worked with <code>NSNotification<\/code>s and <code>NSNotificationCenter<\/code>.  In many ways a <code>NSNotificationCenter<\/code> is like a <a href=\"http:\/\/www.freedesktop.org\/wiki\/Software\/dbus\/\">dbus<\/a> for your application:  objects may post notifications (that is, events), and objects that are interested can subscribe to receive them.<\/p>\n<p>Let&#8217;s look at an example; but first, a brief disclaimer.  <code>NSNotification<\/code>s that are posted can be created with a <code>userInfo<\/code> dictionary that contains additional information about the event.  Unfortunately there is a <a href=\"https:\/\/bugs.swift.org\/browse\/SR-396\">bug in the Swift SILgen on Linux<\/a> that is preventing the proper casts to extract the information, so we&#8217;re going to employ a global variable as a workaround.  Normally we wouldn&#8217;t do that.<\/p>\n<p>Here&#8217;s our code:<\/p>\n<pre class=\"lang:swift\">\r\nimport Foundation\r\nimport Glibc\r\n\r\nlet INPUT_NOTIFICATION = \"InputNotification\"\r\nlet nc = NSNotificationCenter.defaultCenter()\r\n\r\nvar availableData = \"\"\r\nlet readThread = NSThread(){\r\n  print(\"Entering thread\")\r\n  let delim:Character = \"\\n\"\r\n  var input:String    = \"\"\r\n  while true {\r\n    let c = Character(UnicodeScalar(UInt32(fgetc(stdin))))\r\n    if c == delim {\r\n      availableData = input\r\n      nc.postNotificationName(INPUT_NOTIFICATION, object:nil)\r\n      input = \"\"\r\n    } else {\r\n      input.append(c)\r\n    }\r\n  }\r\n  \/\/ Our read thread never exits\r\n}\r\n\r\nnc.addObserverForName(INPUT_NOTIFICATION, object:nil, queue:nil) {\r\n  (_) in\r\n  print(\"Data received:  \\(availableData)\")\r\n}\r\n\r\nreadThread.start()\r\n\r\nselect(0, nil, nil, nil, nil) \/\/ Forever sleep\r\n<\/pre>\n<p>It&#8217;s pretty simple. <\/p>\n<p><b>1.<\/b>  Our <code>nc<\/code> constant is the default <code>NSNotificationCenter<\/code> for the application.  You don&#8217;t have to create the default <code>NSNotificationCenter<\/code>.<\/p>\n<p><b>2.<\/b>  <code>readThread<\/code> is an <code>NSThread<\/code> instance that never exits but sits and reads <code>stdin<\/code>.  Whenever the newline character is encountered it saves the &#8220;buffered&#8221; characters (stored in <code>input<\/code>) to <code>availableData<\/code> and then posts an <code>INPUT_NOTIFICATION<\/code> via the default <code>NSNotificationCenter<\/code>.<\/p>\n<p><b>3.<\/b>  Before starting our <code>readThread<\/code> we added an observer for the <code>INPUT_NOTIFICATION<\/code>.  The <code>addObserverForName<\/code> function takes a block which executes when the notification is broadcasted.<\/p>\n<p><b>4.<\/b>  We start our thread with the <code>NSThread<\/code> <code>start<\/code> method.<\/p>\n<p><b>5.<\/b>  Again, we employ a blocking <code>select<\/code> to ensure the Linux process doesn&#8217;t end (which would unceremoniously kill our thread).<\/p>\n<h2>NSNotification on OS X<\/h2>\n<p>As a reference of how we <i>should<\/i> be using <code>userInfo<\/code> with <code>NSNotification<\/code>, here is some Swift code for OS X that eventually we&#8217;d like to see working on Linux:<\/p>\n<pre>\r\nimport Foundation\r\nimport Darwin\r\n\r\nlet INPUT_NOTIFICATION = \"InputNotification\"\r\nlet nc = NSNotificationCenter.defaultCenter()\r\n\r\nclass Reader : NSObject {\r\n\r\n  var readThread:NSThread?\r\n\r\n  func start() {\r\n\r\n    self.readThread = NSThread(target:self,\r\n                               selector:\"readStdin\",\r\n                               object:nil)\r\n    self.readThread!.start()\r\n  }\r\n\r\n  func readStdin() {\r\n    print(\"Entering thread\")\r\n    let delim:Character = \"\\n\"\r\n    var input:String    = \"\"\r\n    while true {\r\n      let c = Character(UnicodeScalar(UInt32(fgetc(stdin))))\r\n      if c == delim {\r\n        nc.postNotificationName(INPUT_NOTIFICATION, object:nil,\r\n                                userInfo:[\"availableData\":input])\r\n        input = \"\"\r\n      } else {\r\n        input.append(c)\r\n      }\r\n    }\r\n    \/\/ Our read thread never exits\r\n  }\r\n}\r\n\r\nnc.addObserverForName(INPUT_NOTIFICATION, object:nil, queue:nil) {\r\n  (notification) in\r\n  guard let userInfo      = notification.userInfo as? [String:String] else {\r\n    return\r\n  }\r\n  guard let availableData = userInfo[\"availableData\"] else {\r\n    return\r\n  }\r\n  print(\"Data received:  \\(availableData)\")\r\n}\r\n\r\nlet reader = Reader()\r\nreader.start()\r\n\r\nselect(0, nil, nil, nil, nil) \/\/ Forever sleep\r\n<\/pre>\n<h2>Closing Comments<\/h2>\n<p>Swift on Linux is very new; as of this writing, less than a month old.  Yet with each passing day additional functionality is being added to the Foundation classes, folks are working to port Swift to ARM platforms such as Raspberry Pi and BeagleBone, and the language is evolving towards Swift 3.  Our personal belief is that Swift has a great shot at being competitive with NodeJS, Python, Ruby, <i>and<\/i> Java and C++ for application development on Linux platforms.  Hopefully this post and those to come will help application developers explore the possibilities Swift brings.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>It is an exciting time to be a Swift enthusiast. The language is now open source and has been ported to Linux. And if that wasn&#8217;t enough, folks at Apple and elsewhere across the globe are also working to port over Foundation and Grand Central Dispatch. If you&#8217;re coming to Swift from a mostly Linux [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[19,5],"tags":[],"class_list":["post-2319","post","type-post","status-publish","format-standard","hentry","category-linux","category-swift"],"_links":{"self":[{"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts\/2319"}],"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=2319"}],"version-history":[{"count":17,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts\/2319\/revisions"}],"predecessor-version":[{"id":2343,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts\/2319\/revisions\/2343"}],"wp:attachment":[{"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/media?parent=2319"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/categories?post=2319"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/tags?post=2319"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}