{"id":678,"date":"2014-06-06T12:22:49","date_gmt":"2014-06-06T18:22:49","guid":{"rendered":"http:\/\/jamesonquave.com\/blog\/?p=678"},"modified":"2015-04-16T18:10:47","modified_gmt":"2015-04-17T00:10:47","slug":"developing-ios-8-apps-using-swift-interaction-with-multiple-views","status":"publish","type":"post","link":"https:\/\/jamesonquave.com\/blog\/developing-ios-8-apps-using-swift-interaction-with-multiple-views\/","title":{"rendered":"Developing iOS 8 Apps Using Swift &#8211; Interaction with multiple views (Part 6)"},"content":{"rendered":"<p><strong><i>This section completely updated to reflect changes in Xcode 6.3, as of April 16, 2015<\/i><\/strong><\/b><\/p>\n<p>In parts 1 through 5 we went over some basics of Swift, and set up a simple example project that creates a Table View and a puts some API results from iTunes inside of them. If you haven&#8217;t read that yet, check out <a title=\"Developing iOS Apps Using Swift Tutorial Part 1\" href=\"http:\/\/jamesonquave.com\/blog\/developing-ios-apps-using-swift-tutorial\/\">Part 1<\/a><\/p>\n<p>If not, and you just want to start from here, download the code for <a href=\"https:\/\/github.com\/jquave\/Swift-Tutorial\/tree\/Part5\">Part 5<\/a> to get started. We&#8217;ll use it as a template to begin.<\/p>\n<p>In this tutorial we&#8217;re going to do quite a few things, so let&#8217;s get started!<\/p>\n<p><strong>Modifying The API Controller code<\/strong><\/p>\n<p>First off, our actual plan for this app is to show iTunes music information. So let&#8217;s modify the API controller to better handle this information.<\/p>\n<p>One thing&#8217;s been bothering me though. When we create our APIController, we set a delegate after it&#8217;s created. But, an API Controller without a delegate isn&#8217;t all that useful, so why even offer the option to make one?<\/p>\n<p>Let&#8217;s add a constructor that accepts the delegate as it&#8217;s only argument.<\/p>\n<pre class=\"brush: js;\">\r\ninit(delegate: APIControllerProtocol) {\r\n    self.delegate = delegate\r\n}\r\n<\/pre>\n<p>Now, our delegate variable in the APIController isn&#8217;t actually going to be an optional any more. There is no APIController without a delegate!<br \/>\nSo also change the delegate property to be an every day, non-optional APIControllerProtocol object.<\/p>\n<pre class=\"brush: js;\">\r\nvar delegate: APIControllerProtocol\r\n<\/pre>\n<p>There&#8217;s also going to be an error at the end of the searchItunesFor method, because we&#8217;re treating the delegate object as an optional, but it&#8217;s not optional any more. So change the erroneous line to say this:<\/p>\n<pre class=\"brush: js;\">\r\nself.delegate.didReceiveAPIResults(results)\r\n<\/pre>\n<p>The only difference is we removed the ? from after the delegate property, to indicate it&#8217;s not an optional.<\/p>\n<p>Now in our SearchResultsController, we need to change a few things. First, since the APIController constructor now needs the delegate object to be instantiated before *it* can be instantiated itself, we need to make it an implicitly unwrapped optional, and wait until viewDidLoad to assign it.<\/p>\n<p>So in the api variable declaration change to this:<\/p>\n<pre class=\"brush: js;\">\r\nvar api : APIController!\r\n<\/pre>\n<p>In the viewDidLoad method we need to unwrap the api object in order to call searchItunesFor(). You should end up with this<\/p>\n<pre class=\"brush: js;\">\r\noverride func viewDidLoad() {\r\n    super.viewDidLoad()\r\n    api = APIController(delegate: self)\r\n    api.searchItunesFor(\"JQ Software\")\r\n}\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p><strong>Searching for Albums<\/strong><br \/>\nLet&#8217;s also modify our call to the searchItunesFor() in the APIController to use a search term for music. We&#8217;ll also show a networkActivityIndicator, to tell the user a network operation is happening. This will show up on the top status bar of the phone.<\/p>\n<pre class=\"brush: js;\">\r\noverride func viewDidLoad() {\r\n    super.viewDidLoad()\r\n    api = APIController(delegate: self)\r\n    UIApplication.sharedApplication().networkActivityIndicatorVisible = true\r\n    api.searchItunesFor(\"Beatles\")\r\n}\r\n<\/pre>\n<p>Now in our urlPath in the APIController, let&#8217;s modify the API parameters to look specifically for albums.<\/p>\n<pre class=\"brush: js;\">\r\nlet urlPath = \"https:\/\/itunes.apple.com\/search?term=\\(escapedSearchTerm)&amp;media=music&amp;entity=album\"\r\n<\/pre>\n<p>We&#8217;ll now get results in the form of Album data, but this schema is a little different from apps. In fact running the app right now will we&#8217;ll just get default cells because the expected JSON data isn&#8217;t there. This is really fragile code, but we can make it slightly less fragile by doing some modeling of the data we expect.<\/p>\n<p><strong>Creating a Swift model for iTunes Albums<\/strong><\/p>\n<p>In order to facilitate passing around information about albums, we should create a model of what an album is exactly. Create a new swift file and call it Album.swift with the following contents:<\/p>\n<pre class=\"brush: js;\">\r\nimport Foundation\r\n\r\nstruct Album {\r\n    let title: String\r\n    let price: String\r\n    let thumbnailImageURL: String\r\n    let largeImageURL: String\r\n    let itemURL: String\r\n    let artistURL: String\r\n    \r\n    init(name: String, price: String, thumbnailImageURL: String, largeImageURL: String, itemURL: String, artistURL: String) {\r\n        self.title = name\r\n        self.price = price\r\n        self.thumbnailImageURL = thumbnailImageURL\r\n        self.largeImageURL = largeImageURL\r\n        self.itemURL = itemURL\r\n        self.artistURL = artistURL\r\n    }\r\n}\r\n<\/pre>\n<p>It&#8217;s a pretty simple struct, it just holds a few properties about albums for us. We create the 6 different properties as strings, and add an initializer that sets all the properties based on our parameters.<\/p>\n<p>So now we have a struct for albums, let&#8217;s use it!<\/p>\n<p><strong>Using our new Swift Album model<\/strong><\/p>\n<p>Back in our SearchResultsController, let&#8217;s modify the tableData array variable, and instead opt for a Swift native array for Albums. In swift, this is as easy as:<\/p>\n<pre class=\"brush: js;\">\r\nvar albums = [Album]()\r\n<\/pre>\n<p>We can do away with do line <strong>var tableData = []<\/strong>, we won&#8217;t be using that any more.<\/p>\n<p>This creates an empty array containing strictly Albums. We&#8217;ll now need to change our tableView dataSource and delegate methods to understand albums.<br \/>\nIn the numberOfRowsInSection method, let&#8217;s change the number of items to the count of albums in our albums array:<\/p>\n<pre class=\"brush: js;\">\r\nfunc tableView(tableView: UITableView, numberOfRowsInSection section: Int) -&gt; Int {\r\n    return albums.count\r\n}\r\n<\/pre>\n<p>Now in cellForRowAtIndexPath, let&#8217;s swap out those dictionary lookups for a single album lookup:<\/p>\n<pre class=\"brush: js;\">\r\nfunc tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {\r\n    let cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier(kCellIdentifier) as! UITableViewCell\r\n    let album = self.albums[indexPath.row]\r\n\r\n    \/\/ Get the formatted price string for display in the subtitle\r\n    cell.detailTextLabel?.text = album.price\r\n    \/\/ Update the textLabel text to use the title from the Album model\r\n    cell.textLabel?.text = album.title\r\n    \r\n    \/\/ Start by setting the cell's image to a static file\r\n    \/\/ Without this, we will end up without an image view!\r\n    cell.imageView?.image = UIImage(named: \"Blank52\")\r\n    \r\n    let thumbnailURLString = album.thumbnailImageURL\r\n    let thumbnailURL = NSURL(string: thumbnailURLString)!\r\n    \r\n    \/\/ If this image is already cached, don't re-download\r\n    if let img = imageCache[thumbnailURLString] {\r\n        cell.imageView?.image = img\r\n    }\r\n    else {\r\n        \/\/ The image isn't cached, download the img data\r\n        \/\/ We should perform this in a background thread\r\n        let request: NSURLRequest = NSURLRequest(URL: thumbnailURL)\r\n        let mainQueue = NSOperationQueue.mainQueue()\r\n        NSURLConnection.sendAsynchronousRequest(request, queue: mainQueue, completionHandler: { (response, data, error) -> Void in\r\n            if error == nil {\r\n                \/\/ Convert the downloaded data in to a UIImage object\r\n                let image = UIImage(data: data)\r\n                \/\/ Store the image in to our cache\r\n                self.imageCache[thumbnailURLString] = image\r\n                \/\/ Update the cell\r\n                dispatch_async(dispatch_get_main_queue(), {\r\n                    if let cellToUpdate = tableView.cellForRowAtIndexPath(indexPath) {\r\n                        cellToUpdate.imageView?.image = image\r\n                    }\r\n                })\r\n            }\r\n            else {\r\n                println(\"Error: \\(error.localizedDescription)\")\r\n            }\r\n        })\r\n    }\r\n    return cell\r\n}\r\n<\/pre>\n<p>Then there is the didSelectRowAtIndexPath method that needs to be modified to use the albums array. But, actually we&#8217;re not going to need this any more, so let&#8217;s just delete the whole method.<\/p>\n<p><strong>Creating Album objects from JSON<\/strong><\/p>\n<p>Now, all of this is not much use if we aren&#8217;t creating our album information in the first place. We need to modify our didReceiveAPIResults method of SearchResultsViewController to take album JSON results, create Album objects, and save them in to the albums array. Since we have a model for Albums now, it makes sense to move this functionality in to the Album model itself. So let&#8217;s make a minor adjustment to didReceiveAPIResults and delegate the responsibility of construction the albums array to the Album class.<\/p>\n<pre class=\"brush: js;\">\r\nfunc didReceiveAPIResults(results: NSArray) {\r\n    dispatch_async(dispatch_get_main_queue(), {\r\n        self.albums = Album.albumsWithJSON(results)\r\n        self.appsTableView!.reloadData()\r\n        UIApplication.sharedApplication().networkActivityIndicatorVisible = false\r\n    })\r\n}\r\n<\/pre>\n<p>Note that since this is where the api request comes to it&#8217;s conclusion, we also turn off the networkActivityIndicator.<\/p>\n<p>Now in the Album.swift file we need to add a static method that creates a list of albums from a JSON list.<\/p>\n<pre class=\"brush: js;\">\r\nstatic func albumsWithJSON(results: NSArray) -> [Album] {\r\n    \/\/ Create an empty array of Albums to append to from this list\r\n    var albums = [Album]()\r\n    \r\n    \/\/ Store the results in our table data array\r\n    if results.count>0 {\r\n        \r\n        \/\/ Sometimes iTunes returns a collection, not a track, so we check both for the 'name'\r\n        for result in results {\r\n            \r\n            var name = result[\"trackName\"] as? String\r\n            if name == nil {\r\n                name = result[\"collectionName\"] as? String\r\n            }\r\n            \r\n            \/\/ Sometimes price comes in as formattedPrice, sometimes as collectionPrice.. and sometimes it's a float instead of a string. Hooray!\r\n            var price = result[\"formattedPrice\"] as? String\r\n            if price == nil {\r\n                price = result[\"collectionPrice\"] as? String\r\n                if price == nil {\r\n                    var priceFloat: Float? = result[\"collectionPrice\"] as? Float\r\n                    var nf: NSNumberFormatter = NSNumberFormatter()\r\n                    nf.maximumFractionDigits = 2\r\n                    if priceFloat != nil {\r\n                        price = \"$\\(nf.stringFromNumber(priceFloat!)!)\"\r\n                    }\r\n                }\r\n            }\r\n            \r\n            let thumbnailURL = result[\"artworkUrl60\"] as? String ?? \"\"\r\n            let imageURL = result[\"artworkUrl100\"] as? String ?? \"\"\r\n            let artistURL = result[\"artistViewUrl\"] as? String ?? \"\"\r\n            \r\n            var itemURL = result[\"collectionViewUrl\"] as? String\r\n            if itemURL == nil {\r\n                itemURL = result[\"trackViewUrl\"] as? String\r\n            }\r\n            \r\n            var newAlbum = Album(name: name!, price: price!, thumbnailImageURL: thumbnailURL, largeImageURL: imageURL, itemURL: itemURL!, artistURL: artistURL)\r\n            albums.append(newAlbum)\r\n        }\r\n    }\r\n    return albums\r\n}\r\n<\/pre>\n<p>I know this looks like a lot of new code, but actually there&#8217;s not much going on here. It&#8217;s really just looping through the list coming from allResults, and its grabbing values for some keys, and setting defaults if they&#8217;re missing.<\/p>\n<p>The ?? operator used here is pretty neat. It works like this:<\/p>\n<pre>\r\nlet finalVariable = possiblyNilVariable ?? \"Definitely Not Nil Variable\"\r\n<\/pre>\n<p>The finalVariable value is set to possiblyNilVariable if it is not nil. But if it is nil? It uses the value of the thing on the right-hand side of the ?? operator. In this case, the string &#8220;Definitely Not Nil Variable&#8221;.<\/p>\n<p>We use this here in order to prevent getting nil values passed in to our Album.<\/p>\n<p>On line 39, we create an Album object. On line 40 the album is added to the list.<br \/>\nFinally on line 43 the list of albums is returned.<\/p>\n<p>If you run the app now you should see a new list of Album&#8217;s pop up. Cool, right?<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Creating a second view<\/strong><\/p>\n<p>Now to actually show the details of an album, we&#8217;ll need a new view. First let&#8217;s create the class.<br \/>\nAdd a new file called DetailsViewController.swift that inherits from UIViewController.<\/p>\n<p>Our view controller will be pretty simple to start. We&#8217;re just going to add an album, and implement UIViewController&#8217;s init method as well as viewDidLoad().<\/p>\n<pre class=\"brush: js;\">\r\nimport UIKit\r\n\r\nclass DetailsViewController: UIViewController {\r\n    \r\n    var album: Album?\r\n    \r\n    required init(coder aDecoder: NSCoder) {\r\n        super.init(coder: aDecoder)\r\n    }\r\n    \r\n    override func viewDidLoad() {\r\n        super.viewDidLoad()\r\n    }\r\n}\r\n<\/pre>\n<p>This code doesn&#8217;t do much yet, but that&#8217;s okay. We just need the class to exist in order to set up our storyboard.<\/p>\n<p>Since we&#8217;ll be pushing views back and forth on the stack we&#8217;ll want a navigation bar as well. It&#8217;s hard to explain in text, and there is an NDA preventing me from showing parts of Xcode 6 in screenshots, so instead I created a short video demonstrating how to do this in Xcode 5. The process is nearly identical for Xcode 6 Beta, and is not under any sort of NDA.<\/p>\n<p><iframe loading=\"lazy\" src=\"\/\/www.youtube.com\/embed\/Vms2hZwg0Zk\" height=\"360\" width=\"640\" allowfullscreen=\"\" frameborder=\"0\"><\/iframe><\/p>\n<p>In the video we did the following:<\/p>\n<ol>\n<li>Embedded our view controller in a navigation controller using the Xcode shortcut in the Editor menu, by clicking the view controller, then selecting Editor-&gt;Embed In-&gt;Navigation Controller<\/li>\n<li>Added a new view controller<\/li>\n<li>Set it&#8217;s class and storyboard ID to &#8216;DetailsViewController&#8217;<\/li>\n<li>Control+Clicked+Dragged from the table view cell in our first view controller to the new view controller we just created, and selected &#8216;show&#8217; for the type of segue.<\/li>\n<\/ol>\n<p>What this last step does is creates a segue on our navigation controller that pushes the new view on top of the stack. If you run the app now and click a cell, you should see this new view animate in.<\/p>\n<p>Let&#8217;s build out a simple UI for this new view. It&#8217;ll contain a UIImageView that is 100&#215;100 pixels, and a title Label. Drag these objects out of the object library and arrange them any way you like on the new view.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Providing the new view with Album information<\/strong><\/p>\n<p>When the storyboard segue fires off, it first calls a function on whatever view controller is currently on the screen called prepareForSegue. We&#8217;re going to intercept this call in order to tell our new view controller which album we&#8217;re looking at. Add the following in SearchResultsViewController:<\/p>\n<pre class=\"brush: js;\">\r\noverride func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {\r\n    if let detailsViewController: DetailsViewController = segue.destinationViewController as? DetailsViewController {\r\n        var albumIndex = appsTableView!.indexPathForSelectedRow()!.row\r\n        var selectedAlbum = self.albums[albumIndex]\r\n        detailsViewController.album = selectedAlbum\r\n    }\r\n}\r\n<\/pre>\n<p>What&#8217;s happening here is the segue parameter being passed in has a member called destinationViewController, which is our fancy new DetailsViewController we just created. In order to set the album member on it, we first need to cast it to DetailsViewController using the &#8216;as&#8217; keyword as shown above.<br \/>\nThen, by using the indexPathForSelectedRow() method of our table view we can determine which album is selected at the moment this segue happens.<br \/>\nUsing this information, well tell our detailsViewController which album was clicked before it is displayed.<\/p>\n<p>Now I&#8217;m going to show you a pretty nifty feature of Xcode. We&#8217;re going to let it write some code for us.<\/p>\n<p>Open up your storyboard again let&#8217;s start creating IBOutlets for our image view, label, button, and text view. On the top-right hand corner of Xcode there is the &#8216;assistant&#8217; button. The icon looks like a bowtie and suit jacket. Clicking on this will open up a code window right next to your storyboard window. Make sure that one of the panels is showing DetailsViewController.swift, and the other is showing Main.storyboard.<\/p>\n<p>Now, hold control, and click+drag from your image view to your code file. Just a line under your class definition for DetailsViewController. It&#8217;ll prompt you for a name, so let&#8217;s call it &#8216;albumCover&#8217;. The default options should be fine here. After doing this you should see this line of code newly added:<\/p>\n<pre class=\"brush: js;\">\r\n@IBOutlet weak var albumCover: UIImageView!\r\n<\/pre>\n<p>We just created a new IBOutlet, and now it&#8217;s connected to our storyboard&#8217;s DetailsViewController. How cool is that?<\/p>\n<p>Do the same thing for the label you added to your view, and call it &#8216;titleLabel&#8217;.<\/p>\n<p>Next, let&#8217;s modify viewDidLoad so that it will load in the info we&#8217;re being passed to our view objects, here&#8217;s the final DetailsViewController code:<\/p>\n<pre class=\"brush: js;\">\r\nimport UIKit\r\n\r\nclass DetailsViewController: UIViewController {\r\n    var album: Album?\r\n    @IBOutlet weak var albumCover: UIImageView!\r\n    @IBOutlet weak var titleLabel: UILabel!\r\n    \r\n    required init(coder aDecoder: NSCoder) {\r\n        super.init(coder: aDecoder)\r\n    }\r\n    \r\n    override func viewDidLoad() {\r\n        super.viewDidLoad()\r\n        titleLabel.text = self.album?.title\r\n        albumCover.image = UIImage(data: NSData(contentsOfURL: NSURL(string: self.album!.largeImageURL)!)!)\r\n    }\r\n}\r\n<\/pre>\n<p>The @IBOutlets are the UI connections made by our storyboards, and our viewDidLoad method sets the title and album cover variables to load in from our Album object.<\/p>\n<p>Now try running the app and taking a look. We can now drill in to details for albums and get a nice big detail view with the album cover and title. Because we pushed in a navigation controller, we also get a functional Back button for free!<\/p>\n<p>If you made it this far, I want to personally congratulate you so <a href=\"https:\/\/twitter.com\/intent\/tweet?text=@jquave\">let me know on twitter<\/a> that you pulled it off! You are well on your way to creating real iOS apps with Swift.<\/p>\n<p>I&#8217;ve decided this tutorial series is going to be expanded upon and refined, along with several other tutorials and essays on working with swift, Xcode, and Apple in a new book, which I have available for <a href='http:\/\/jamesonquave.com\/swiftebook\/'>pre-order here<\/a>. Also, I&#8217;ve decided to open up a <a href='http:\/\/jamesonquave.com\/forum\/'>new forum<\/a> for all the followers of this tutorial.<\/p>\n<p>Make sure to <a href=\"http:\/\/jamesonquave.us6.list-manage.com\/subscribe\/post?u=1d2576bf288fe2fd7fa71bd20&amp;id=6c787ed58a\">sign up to be notified<\/a> of the new sessions.<\/p>\n<p>The full source code for this section is <a href='https:\/\/github.com\/jquave\/Swift-Tutorial\/tree\/Part6'>available here<\/a>.<\/p>\n<p>In <a href='http:\/\/jamesonquave.com\/blog\/developing-ios-8-apps-using-swift-animations-audio-and-custom-table-view-cells\/'>part 7<\/a>, we set up a full Detail view with a working music player, and implement some great animations.<\/p>\n<p><a href='http:\/\/jamesonquave.com\/blog\/developing-ios-8-apps-using-swift-animations-audio-and-custom-table-view-cells\/'>Go To Part 7 -><\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>This section completely updated to reflect changes in Xcode 6.3, as of April 16, 2015 In parts 1 through 5 we went over some basics of Swift, and set up a simple example project that creates a Table View and a puts some API results from iTunes inside of them. If you haven&#8217;t read that&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_links_to":"","_links_to_target":""},"categories":[26,21,10,32],"tags":[39,40,34,41,33,36,16],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v19.13 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Developing iOS 8 Apps Using Swift - Interaction with multiple views (Part 6) - 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\/developing-ios-8-apps-using-swift-interaction-with-multiple-views\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Developing iOS 8 Apps Using Swift - Interaction with multiple views (Part 6) - Jameson Quave\" \/>\n<meta property=\"og:description\" content=\"This section completely updated to reflect changes in Xcode 6.3, as of April 16, 2015 In parts 1 through 5 we went over some basics of Swift, and set up a simple example project that creates a Table View and a puts some API results from iTunes inside of them. If you haven&#8217;t read that...\" \/>\n<meta property=\"og:url\" content=\"https:\/\/jamesonquave.com\/blog\/developing-ios-8-apps-using-swift-interaction-with-multiple-views\/\" \/>\n<meta property=\"og:site_name\" content=\"Jameson Quave\" \/>\n<meta property=\"article:published_time\" content=\"2014-06-06T18:22:49+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2015-04-17T00:10:47+00:00\" \/>\n<meta name=\"author\" content=\"Jameson Quave\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Jameson Quave\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"12 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/jamesonquave.com\/blog\/developing-ios-8-apps-using-swift-interaction-with-multiple-views\/\",\"url\":\"https:\/\/jamesonquave.com\/blog\/developing-ios-8-apps-using-swift-interaction-with-multiple-views\/\",\"name\":\"Developing iOS 8 Apps Using Swift - Interaction with multiple views (Part 6) - Jameson Quave\",\"isPartOf\":{\"@id\":\"https:\/\/jamesonquave.com\/blog\/#website\"},\"datePublished\":\"2014-06-06T18:22:49+00:00\",\"dateModified\":\"2015-04-17T00:10:47+00:00\",\"author\":{\"@id\":\"https:\/\/jamesonquave.com\/blog\/#\/schema\/person\/db6184f355c7f4e3b876d0f228c2fcfc\"},\"breadcrumb\":{\"@id\":\"https:\/\/jamesonquave.com\/blog\/developing-ios-8-apps-using-swift-interaction-with-multiple-views\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/jamesonquave.com\/blog\/developing-ios-8-apps-using-swift-interaction-with-multiple-views\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/jamesonquave.com\/blog\/developing-ios-8-apps-using-swift-interaction-with-multiple-views\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/jamesonquave.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Developing iOS 8 Apps Using Swift &#8211; Interaction with multiple views (Part 6)\"}]},{\"@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\/db6184f355c7f4e3b876d0f228c2fcfc\",\"name\":\"Jameson Quave\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/jamesonquave.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/d9786c83345117d560bbeab0e1f26814?s=96&d=retro&r=pg\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/d9786c83345117d560bbeab0e1f26814?s=96&d=retro&r=pg\",\"caption\":\"Jameson Quave\"},\"sameAs\":[\"http:\/\/jamesonquave.com\"],\"url\":\"https:\/\/jamesonquave.com\/blog\/author\/jquave\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Developing iOS 8 Apps Using Swift - Interaction with multiple views (Part 6) - 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\/developing-ios-8-apps-using-swift-interaction-with-multiple-views\/","og_locale":"en_US","og_type":"article","og_title":"Developing iOS 8 Apps Using Swift - Interaction with multiple views (Part 6) - Jameson Quave","og_description":"This section completely updated to reflect changes in Xcode 6.3, as of April 16, 2015 In parts 1 through 5 we went over some basics of Swift, and set up a simple example project that creates a Table View and a puts some API results from iTunes inside of them. If you haven&#8217;t read that...","og_url":"https:\/\/jamesonquave.com\/blog\/developing-ios-8-apps-using-swift-interaction-with-multiple-views\/","og_site_name":"Jameson Quave","article_published_time":"2014-06-06T18:22:49+00:00","article_modified_time":"2015-04-17T00:10:47+00:00","author":"Jameson Quave","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Jameson Quave","Est. reading time":"12 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/jamesonquave.com\/blog\/developing-ios-8-apps-using-swift-interaction-with-multiple-views\/","url":"https:\/\/jamesonquave.com\/blog\/developing-ios-8-apps-using-swift-interaction-with-multiple-views\/","name":"Developing iOS 8 Apps Using Swift - Interaction with multiple views (Part 6) - Jameson Quave","isPartOf":{"@id":"https:\/\/jamesonquave.com\/blog\/#website"},"datePublished":"2014-06-06T18:22:49+00:00","dateModified":"2015-04-17T00:10:47+00:00","author":{"@id":"https:\/\/jamesonquave.com\/blog\/#\/schema\/person\/db6184f355c7f4e3b876d0f228c2fcfc"},"breadcrumb":{"@id":"https:\/\/jamesonquave.com\/blog\/developing-ios-8-apps-using-swift-interaction-with-multiple-views\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/jamesonquave.com\/blog\/developing-ios-8-apps-using-swift-interaction-with-multiple-views\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/jamesonquave.com\/blog\/developing-ios-8-apps-using-swift-interaction-with-multiple-views\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/jamesonquave.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Developing iOS 8 Apps Using Swift &#8211; Interaction with multiple views (Part 6)"}]},{"@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\/db6184f355c7f4e3b876d0f228c2fcfc","name":"Jameson Quave","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/jamesonquave.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/d9786c83345117d560bbeab0e1f26814?s=96&d=retro&r=pg","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/d9786c83345117d560bbeab0e1f26814?s=96&d=retro&r=pg","caption":"Jameson Quave"},"sameAs":["http:\/\/jamesonquave.com"],"url":"https:\/\/jamesonquave.com\/blog\/author\/jquave\/"}]}},"_links":{"self":[{"href":"https:\/\/jamesonquave.com\/blog\/wp-json\/wp\/v2\/posts\/678"}],"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\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/jamesonquave.com\/blog\/wp-json\/wp\/v2\/comments?post=678"}],"version-history":[{"count":61,"href":"https:\/\/jamesonquave.com\/blog\/wp-json\/wp\/v2\/posts\/678\/revisions"}],"predecessor-version":[{"id":1773,"href":"https:\/\/jamesonquave.com\/blog\/wp-json\/wp\/v2\/posts\/678\/revisions\/1773"}],"wp:attachment":[{"href":"https:\/\/jamesonquave.com\/blog\/wp-json\/wp\/v2\/media?parent=678"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jamesonquave.com\/blog\/wp-json\/wp\/v2\/categories?post=678"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jamesonquave.com\/blog\/wp-json\/wp\/v2\/tags?post=678"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}