{"id":688,"date":"2014-11-01T20:41:44","date_gmt":"2014-11-02T02:41:44","guid":{"rendered":"http:\/\/dev.iachieved.it\/iachievedit\/?p=688"},"modified":"2015-02-28T14:29:39","modified_gmt":"2015-02-28T20:29:39","slug":"http-json-requests-with-swift-and-alamofire","status":"publish","type":"post","link":"https:\/\/dev.iachieved.it\/iachievedit\/http-json-requests-with-swift-and-alamofire\/","title":{"rendered":"HTTP JSON Requests with Swift and Alamofire"},"content":{"rendered":"<p><b>Editor&#8217;s note:<\/b>  See our <a href=\"http:\/\/dev.iachieved.it\/iachievedit\/using-carthage-with-alamofire\/\">latest post<\/a> on using Carthage for adding Alamofire to your project.  You don&#8217;t need to suffer through git submodules (the method described below) any longer.<\/p>\n<p>It didn&#8217;t take long after the introduction of Swift to begin seeing <a href=\"http:\/\/stackoverflow.com\/questions\/24120402\/swift-and-afnetworking-integration\">Stackoverflow questions<\/a> asking about using <a href=\"\">AFNetworking<\/a>, the popular Objective-C framework for making HTTP requests on iOS.  Of course it can be done, as Swift and Objective-C can coexist together in the same project, but there&#8217;s the Objective-C way of doing things, and then there is the Swift way. Enter <a href=\"https:\/\/github.com\/Alamofire\/Alamofire\">Alamofire<\/a>, brought to you by the same <a href=\"http:\/\/nshipster.com\">author<\/a> as AFNetworking.<\/p>\n<p>As you can guess, we&#8217;re interested in using this new framework with our Swift projects.  Let&#8217;s get to it shall we.  This tutorial will walk you through creating a new Xcode project using Swift to make use of the <a href=\"http:\/\/mymemory.translated.net\">MyMemory<\/a> language translator to translate simple phrases from English to Spanish.  Of course we could have built an application that allowed the user to choose the source and destination languages, but we wanted to leave it as an exercise to the reader.<\/p>\n<p>Before you get started, I should point out that I&#8217;m using Xcode 6.1 (6A1052d).  If you are using a different version, well, as they say, YMMV.  While I suggest you go through this tutorial step-by-step, you can fast forward and download the working project on <a href=\"https:\/\/bitbucket.org\/joeiachievedit\/alamofire-translator\">Bitbucket<\/a> (see the end of this post for instructions to ensure Alamofire is updated in your checkout).<\/p>\n<p>Start Xcode and select <b>File &#8211; New Project<\/b> and create a <i>Single View<\/i> iOS application.  For the <b>Product Name<\/b> we chose <code>translator<\/code>, and of course make sure your language is <b>Swift<\/b>.<\/p>\n<p>Before getting to Alamofire, let&#8217;s create a UI.  Click on <code>Main.storyboard<\/code> to bring it up.<\/p>\n<p>Drag four labels and a text input field to the storyboard, arranged as follows:<\/p>\n<p><a href=\"http:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2014\/11\/alamofire_constraints.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2014\/11\/alamofire_constraints.png\" alt=\"alamofire_constraints\" width=\"1174\" height=\"751\" class=\"alignnone size-full wp-image-736\" \/><\/a><\/p>\n<p>In this example we have also added constraints to the layout.  I&#8217;m by no means an expert on using Xcode constraints, but if I did it correctly the UI should look appropriate on the iPhone 5, 6, or 6 Plus.  The layout should also rotate correctly.<\/p>\n<p>Wire up the Text Field to the view controller as an IBOutlet.  In this example I&#8217;ve named it <code>textFieldToTranslate<\/code>.  Also wire up the label where we&#8217;ll display our translated text.  I&#8217;ve named it <code>translatedTextLabel<\/code>.<\/p>\n<p><a href=\"http:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2014\/11\/alamofire_addtextfieldtotranslate.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2014\/11\/alamofire_addtextfieldtotranslate.png\" alt=\"alamofire_addtextfieldtotranslate\" width=\"786\" height=\"267\" class=\"alignnone size-full wp-image-697\" \/><\/a><\/p>\n<p>Your <code>IBOutlet<\/code>s in <code>ViewController.swift<\/code> should look like:<\/p>\n<p>[objc]<br \/>\n  @IBOutlet weak var textFieldToTranslate: UITextField!<br \/>\n  @IBOutlet weak var translatedTextLabel: UILabel!<br \/>\n[\/objc]<\/p>\n<p>Now, let&#8217;s add the appropriate delegate methods to the view controller so we can interact with the text field.  This includes:<\/p>\n<ul>\n<li>Adding <code>UITextFieldDelegate<\/code> to the <code>ViewController<\/code> class declaration\n<li>Setting the <code>delegate<\/code> property of the <code>UITextField<\/code> to the view controller\n<li>Adding the <code>textFieldShouldReturn<\/code> function to the <code>ViewController<\/code> class\n<\/ul>\n<p>I typically set the <code>UITextField delegate<\/code> property in the view controller <code>viewDidAppear<\/code> method, so let&#8217;s add that:<\/p>\n<p>[objc]<br \/>\n  override func viewDidAppear(animated: Bool) {<br \/>\n    super.viewDidAppear(animated)<\/p>\n<p>    self.textFieldToTranslate.delegate = self<br \/>\n  }<\/p>\n<p>  func textFieldShouldReturn(textField: UITextField) -&gt; Bool {<\/p>\n<p>    textField.resignFirstResponder()<\/p>\n<p>    return true<br \/>\n  }<br \/>\n[\/objc]<\/p>\n<p>We can compile and run our code as is, but of course it does next to nothing.  Now, let&#8217;s wire up Alamofire to translate the text that is in the text field.<\/p>\n<h2>Using Alamofire<\/h2>\n<p>Alamorefire&#8217;s set up is a bit different than with Objective-C frameworks.  The Alamofire Github repository currently states, <a href=\"https:\/\/github.com\/Alamofire\/Alamofire\">Due to the current lack of proper infrastructure for Swift dependency management, using Alamofire in your project requires the following steps<\/a>, followed by 7 steps to follow.  We&#8217;re going to follow those here, with some additional detail provided.<\/p>\n<p>Open a terminal (again, I like <a href=\"http:\/\/iterm2.com\">iTerm 2<\/a>), and <code>cd<\/code> over to your Xcode project directory.  In our case we <code>cd ~\/projects\/blogging\/translator<\/code>, and <b>use the git submodule feature<\/b> to check the Alamofire code as a git submodule:<\/p>\n<p><a href=\"http:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2014\/11\/alamofire_addsubmodule.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2014\/11\/alamofire_addsubmodule.png\" alt=\"alamofire_addsubmodule\" width=\"574\" height=\"446\" class=\"alignnone size-full wp-image-698\" \/><\/a><\/p>\n<p>Now, with the Mac Finder, locate your project directory, navigate into the Alamofire folder, and <b>drag-and-drop<\/b> the <code>Alamofire.xcodeproj<\/code> icon from the Finder window into the Xcode project.<\/p>\n<p><a href=\"http:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2014\/11\/alamofire_addingxcodeproj.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2014\/11\/alamofire_addingxcodeproj.png\" alt=\"alamofire_addingxcodeproj\" width=\"1032\" height=\"228\" class=\"alignnone size-full wp-image-722\" \/><\/a><\/p>\n<p>You should now see something like this in your Xcode project:<\/p>\n<p><a href=\"http:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2014\/11\/alamofire_addxcodeproj.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2014\/11\/alamofire_addxcodeproj.png\" alt=\"alamofire_addxcodeproj\" width=\"260\" height=\"284\" class=\"alignnone size-full wp-image-703\" \/><\/a><\/p>\n<p>Now, in Xcode, navigate to the target configuration window of Alamofire by clicking on the blue Alamofire project icon, and selecting the application target under the <b>Targets<\/b> heading in the sidebar.  Ensure here that the <b>Deployment Target<\/b> of Alamofire <i>is the same<\/i> as the <b>Deployment Target<\/b> of the <b>translator<\/b> application.  In our case, we are using a deployment target of 8.0.<\/p>\n<p><a href=\"http:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2014\/11\/alamoFireTarget.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2014\/11\/alamoFireTarget.png\" alt=\"alamoFireTarget\" width=\"594\" height=\"351\" class=\"alignnone size-full wp-image-699\" \/><\/a><\/p>\n<p>Now, click on the <b>translator<\/b> project icon (the blueprint icon), select the <b>translator<\/b> target and in the tab bar at the top of that window open the <b>Build Phases<\/b> panel.  Expand the <b>Target Dependencies<\/b> group, and add <code>Alamofire<\/code>:<\/p>\n<p><a href=\"http:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2014\/11\/alamofire_targetdependency_alamofire.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2014\/11\/alamofire_targetdependency_alamofire.png\" alt=\"alamofire_targetdependency_alamofire\" width=\"702\" height=\"381\" class=\"alignnone size-full wp-image-700\" \/><\/a><\/p>\n<p>Finally, click on the <code>+<\/code> button at the top left of the panel (right under the label that says <b>General<\/b> and select <b>New Copy Files Phase<\/b>. <\/p>\n<p><a href=\"http:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2014\/11\/alamofire_copyfilesphase.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2014\/11\/alamofire_copyfilesphase.png\" alt=\"alamofire_copyfilesphase\" width=\"702\" height=\"352\" class=\"alignnone size-full wp-image-738\" \/><\/a><\/p>\n<p>Rename this new phase to <b>Copy Frameworks<\/b>, set the <b>Destination<\/b> to <b>Frameworks<\/b>, and add <code>Alamofire.framework<\/code>.<\/p>\n<p><a href=\"http:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2014\/11\/alamofire_addalamofireframework.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2014\/11\/alamofire_addalamofireframework.png\" alt=\"alamofire_addalamofireframework\" width=\"401\" height=\"199\" class=\"alignnone size-full wp-image-705\" \/><\/a><\/p>\n<p>And that&#8217;s all there is to it!  Okay, so it&#8217;s a pain in the ass doing all that, but I find it worth the trouble.  For a minute or two of drag-and-drop-and-configure we have an excellent API to begin making HTTP requests with.<\/p>\n<p>Now that we have Alamofire added, let&#8217;s use it in our <code>textFieldShouldReturn<\/code> function.  Remember, <code>textFieldShouldReturn<\/code> is going to get called when the user presses the action key on the iOS keyboard associated with our text field.  First, add the statement <code>import Alamofire<\/code> at the top of your <code>ViewController.swift<\/code> file, like such:<\/p>\n<p>[objc]<br \/>\nimport Alamofire<br \/>\n[\/objc]<\/p>\n<p>Then, in <code>textFieldShouldReturn<\/code> we&#8217;ll do the following:<\/p>\n<p>[objc]<br \/>\n    let textToTranslate = self.textFieldToTranslate.text<\/p>\n<p>    let parameters = [&quot;q&quot;:textToTranslate,<br \/>\n                      &quot;langpair&quot;:&quot;en|es&quot;]<\/p>\n<p>    Alamofire.request(.GET, &quot;http:\/\/api.mymemory.translated.net\/get&quot;, parameters:parameters)<br \/>\n    .responseJSON { (_, _, JSON, _) -&gt; Void in<\/p>\n<p>      let translatedText: String? = JSON?.valueForKeyPath(&quot;responseData.translatedText&quot;) as String?<\/p>\n<p>[\/objc]<\/p>\n<p>We&#8217;re following the API at <a href=\"http:\/\/mymemory.translated.net\/doc\/spec.php\">MyMemory<\/a> for translating text from English to Spanish. Notice the simplicity of both the HTTP request with Alamofire as well as handling the response.  <code>.GET<\/code> is an enumeration for the HTTP method to use for the request, followed by our URL, and then a basic dictionary of URL parameters.<\/p>\n<p>The MyMemory API call returns a JSON string, so we can utilize the Alamofire <code>responseJSON<\/code> function to give us a JSON dictionary (it handles taking the JSON string returned in the body and converting it for us).  Although it looks careless the method in which we are getting the <code>translatedText<\/code> is good form.  Since we declare <code>translatedText<\/code> as <code>String?<\/code> we are saying &#8220;This could be a <code>String<\/code> or <code>nil<\/code>.&#8221;  Moreover, by using <code>JSON?.valueForKeyPath()<\/code> we are saying, &#8220;<code>JSON<\/code> could respond to <code>valueForKeyPath<\/code> or it could be <code>nil<\/code>&#8220;.  If <code>JSON<\/code> is <code>nil<\/code> then it follows <code>translatedText<\/code> will be <code>nil<\/code> as well.  If <code>JSON<\/code> is not <code>nil<\/code> and we find a value at the given key path <code>responseData.translatedText<\/code>, then we have our translation available (which we&#8217;ll display in the label).<\/p>\n<p>All of this code makes heavy use of <i>chained optionals<\/i> in Swift.  For a refresher in Swift optionals in general, visit <a href=\"http:\/\/dev.iachieved.it\/iachievedit\/?p=314\">our post on the topic<\/a>.<\/p>\n<p>Once we have the translated text we update our view controller label:<\/p>\n<p>[objc]<br \/>\n      if let translated = translatedText {<br \/>\n        self.translatedTextLabel.text = translated<br \/>\n      } else {<br \/>\n        self.translatedTextLabel.text = &quot;No translation available.&quot;<br \/>\n      }<br \/>\n[\/objc]<\/p>\n<p>Alamofire has a <i>lot<\/i> of features, and of course we&#8217;ve only scratched the surface.  Take a look through the extensive documentation on <a href=\"https:\/\/github.com\/Alamofire\/Alamofire\">Github<\/a>; it&#8217;s all there, support for <code>POST<\/code> and the remaining cast of characters, various authentication methods (eg., basic auth), uploading data, etc.  <\/p>\n<p>Let&#8217;s run our new application and translate <i>Good night, friends!<\/i> into Spanish.<\/p>\n<p><a href=\"http:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2014\/11\/translator_run.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/dev.iachieved.it\/iachievedit\/wp-content\/uploads\/2014\/11\/translator_run.png\" alt=\"translator_run\" width=\"320\" height=\"568\" class=\"alignnone size-full wp-image-742\" \/><\/a><\/p>\n<p>Nice, it worked!  Of course, my Spanish-speaking amigos will point out that the opening <i>signo de exclamaci\u00f3n<\/i> is missing, but that can be corrected. <\/p>\n<p>That&#8217;s it for today, I hope you enjoyed the tutorial.  Again, if you&#8217;d like a working example visit the <a href=\"https:\/\/bitbucket.org\/joeiachievedit\/alamofire-translator\">Bitbucket<\/a> repository.  After checking out the repository, make sure and run the following <i>in your alamofire-translator<\/i> directory:<\/p>\n<pre>\r\ngit submodule init\r\ngit submodule update\r\n<\/pre>\n<h2>Exercises for the Reader<\/h2>\n<p>You will no doubt notice that the application is only capable of translating from English to Spanish.  MyMemory allows for any-to-any translation, why not add a popup menu to allow for choosing which language to translate from and to?  And while the HTTP request is pretty quick there&#8217;s room perhaps for a progress indicator somewhere on the screen, as either a HUD or basic activity spinner.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Editor&#8217;s note: See our latest post on using Carthage for adding Alamofire to your project. You don&#8217;t need to suffer through git submodules (the method described below) any longer. It didn&#8217;t take long after the introduction of Swift to begin seeing Stackoverflow questions asking about using AFNetworking, the popular Objective-C framework for making HTTP requests [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11,5,3],"tags":[],"class_list":["post-688","post","type-post","status-publish","format-standard","hentry","category-apple","category-swift","category-web-services"],"_links":{"self":[{"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts\/688"}],"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=688"}],"version-history":[{"count":48,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts\/688\/revisions"}],"predecessor-version":[{"id":1276,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts\/688\/revisions\/1276"}],"wp:attachment":[{"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/media?parent=688"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/categories?post=688"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/tags?post=688"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}