Skip to content

Commit b0e6c62

Browse files
committed
Part 3
1 parent 7c39481 commit b0e6c62

File tree

5 files changed

+125
-43
lines changed

5 files changed

+125
-43
lines changed

SwiftTutorial.xcodeproj/project.pbxproj

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,11 @@
88

99
/* Begin PBXBuildFile section */
1010
0256BB50194F3F38003E2942 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0256BB4F194F3F38003E2942 /* AppDelegate.swift */; };
11-
0256BB52194F3F38003E2942 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0256BB51194F3F38003E2942 /* ViewController.swift */; };
11+
0256BB52194F3F38003E2942 /* SearchResultsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0256BB51194F3F38003E2942 /* SearchResultsViewController.swift */; };
1212
0256BB55194F3F38003E2942 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0256BB53194F3F38003E2942 /* Main.storyboard */; };
1313
0256BB57194F3F38003E2942 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0256BB56194F3F38003E2942 /* Images.xcassets */; };
1414
0256BB63194F3F38003E2942 /* SwiftTutorialTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0256BB62194F3F38003E2942 /* SwiftTutorialTests.swift */; };
15+
0256BB6D194F41F5003E2942 /* APIController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0256BB6C194F41F5003E2942 /* APIController.swift */; };
1516
/* End PBXBuildFile section */
1617

1718
/* Begin PBXContainerItemProxy section */
@@ -28,12 +29,13 @@
2829
0256BB4A194F3F38003E2942 /* SwiftTutorial.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SwiftTutorial.app; sourceTree = BUILT_PRODUCTS_DIR; };
2930
0256BB4E194F3F38003E2942 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
3031
0256BB4F194F3F38003E2942 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
31-
0256BB51194F3F38003E2942 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
32+
0256BB51194F3F38003E2942 /* SearchResultsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchResultsViewController.swift; sourceTree = "<group>"; };
3233
0256BB54194F3F38003E2942 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
3334
0256BB56194F3F38003E2942 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
3435
0256BB5C194F3F38003E2942 /* SwiftTutorialTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SwiftTutorialTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
3536
0256BB61194F3F38003E2942 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
3637
0256BB62194F3F38003E2942 /* SwiftTutorialTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftTutorialTests.swift; sourceTree = "<group>"; };
38+
0256BB6C194F41F5003E2942 /* APIController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = APIController.swift; sourceTree = "<group>"; };
3739
/* End PBXFileReference section */
3840

3941
/* Begin PBXFrameworksBuildPhase section */
@@ -76,10 +78,11 @@
7678
isa = PBXGroup;
7779
children = (
7880
0256BB4F194F3F38003E2942 /* AppDelegate.swift */,
79-
0256BB51194F3F38003E2942 /* ViewController.swift */,
81+
0256BB51194F3F38003E2942 /* SearchResultsViewController.swift */,
8082
0256BB53194F3F38003E2942 /* Main.storyboard */,
8183
0256BB56194F3F38003E2942 /* Images.xcassets */,
8284
0256BB4D194F3F38003E2942 /* Supporting Files */,
85+
0256BB6C194F41F5003E2942 /* APIController.swift */,
8386
);
8487
path = SwiftTutorial;
8588
sourceTree = "<group>";
@@ -208,8 +211,9 @@
208211
isa = PBXSourcesBuildPhase;
209212
buildActionMask = 2147483647;
210213
files = (
211-
0256BB52194F3F38003E2942 /* ViewController.swift in Sources */,
214+
0256BB52194F3F38003E2942 /* SearchResultsViewController.swift in Sources */,
212215
0256BB50194F3F38003E2942 /* AppDelegate.swift in Sources */,
216+
0256BB6D194F41F5003E2942 /* APIController.swift in Sources */,
213217
);
214218
runOnlyForDeploymentPostprocessing = 0;
215219
};

SwiftTutorial/APIController.swift

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
//
2+
// APIController.swift
3+
// SwiftTutorial
4+
//
5+
// Created by Jameson Quave on 6/16/14.
6+
// Copyright (c) 2014 JQ Software LLC. All rights reserved.
7+
//
8+
9+
import UIKit
10+
11+
protocol APIControllerProtocol {
12+
func didReceiveAPIResults(results: NSDictionary)
13+
}
14+
15+
class APIController: NSObject {
16+
var delegate: APIControllerProtocol?
17+
18+
func searchItunesFor(searchTerm: String) {
19+
20+
// The iTunes API wants multiple terms separated by + symbols, so replace spaces with + signs
21+
var itunesSearchTerm = searchTerm.stringByReplacingOccurrencesOfString(" ", withString: "+", options: NSStringCompareOptions.CaseInsensitiveSearch, range: nil)
22+
23+
// Now escape anything else that isn't URL-friendly
24+
var escapedSearchTerm = itunesSearchTerm.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)
25+
var urlPath = "https://itunes.apple.com/search?term=\(escapedSearchTerm)&media=software"
26+
var url: NSURL = NSURL(string: urlPath)
27+
var session = NSURLSession.sharedSession()
28+
var task = session.dataTaskWithURL(url, completionHandler: {data, response, error -> Void in
29+
println("Task completed")
30+
if(error) {
31+
// If there is an error in the web request, print it to the console
32+
println(error.localizedDescription)
33+
}
34+
var err: NSError?
35+
var jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as NSDictionary
36+
if(err?) {
37+
// If there is an error parsing JSON, print it to the console
38+
println("JSON Error \(err!.localizedDescription)")
39+
}
40+
var results: NSArray = jsonResult["results"] as NSArray
41+
// Now send the JSON result to our delegate object
42+
self.delegate?.didReceiveAPIResults(jsonResult)
43+
})
44+
task.resume()
45+
}
46+
47+
}

SwiftTutorial/Base.lproj/Main.storyboard

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6153.11"/>
55
</dependencies>
66
<scenes>
7-
<!--View Controller-->
7+
<!--Search Results View Controller-->
88
<scene sceneID="ufC-wZ-h7g">
99
<objects>
10-
<viewController id="vXZ-lx-hvc" customClass="ViewController" customModule="SwiftTutorial" customModuleProvider="target" sceneMemberID="viewController">
10+
<viewController id="vXZ-lx-hvc" customClass="SearchResultsViewController" customModule="SwiftTutorial" customModuleProvider="target" sceneMemberID="viewController">
1111
<layoutGuides>
1212
<viewControllerLayoutGuide type="top" id="jyV-Pf-zRb"/>
1313
<viewControllerLayoutGuide type="bottom" id="2fi-mo-0CV"/>
@@ -41,6 +41,9 @@
4141
</mask>
4242
</variation>
4343
</view>
44+
<connections>
45+
<outlet property="appsTableView" destination="0Ds-au-UhU" id="4Ou-lD-tIm"/>
46+
</connections>
4447
</viewController>
4548
<placeholder placeholderIdentifier="IBFirstResponder" id="x5A-6p-PRh" sceneMemberID="firstResponder"/>
4649
</objects>
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
//
2+
// ViewController.swift
3+
// SwiftTutorial
4+
//
5+
// Created by Jameson Quave on 6/16/14.
6+
// Copyright (c) 2014 JQ Software LLC. All rights reserved.
7+
//
8+
9+
import UIKit
10+
11+
class SearchResultsViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, APIControllerProtocol {
12+
13+
@IBOutlet var appsTableView : UITableView
14+
var tableData: NSArray = []
15+
var api: APIController = APIController()
16+
17+
override func viewDidLoad() {
18+
super.viewDidLoad()
19+
self.api.delegate = self
20+
api.searchItunesFor("Angry Birds")
21+
}
22+
23+
override func didReceiveMemoryWarning() {
24+
super.didReceiveMemoryWarning()
25+
// Dispose of any resources that can be recreated.
26+
}
27+
28+
func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int {
29+
return tableData.count
30+
}
31+
32+
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
33+
let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "MyTestCell")
34+
35+
var rowData: NSDictionary = self.tableData[indexPath.row] as NSDictionary
36+
37+
cell.text = rowData["trackName"] as String
38+
39+
// Grab the artworkUrl60 key to get an image URL for the app's thumbnail
40+
var urlString: NSString = rowData["artworkUrl60"] as NSString
41+
var imgURL: NSURL = NSURL(string: urlString)
42+
43+
// Download an NSData representation of the image at the URL
44+
var imgData: NSData = NSData(contentsOfURL: imgURL)
45+
cell.image = UIImage(data: imgData)
46+
47+
// Get the formatted price string for display in the subtitle
48+
var formattedPrice: NSString = rowData["formattedPrice"] as NSString
49+
50+
cell.detailTextLabel.text = formattedPrice
51+
52+
return cell
53+
}
54+
55+
func didReceiveAPIResults(results: NSDictionary) {
56+
var resultsArr: NSArray = results["results"] as NSArray
57+
dispatch_async(dispatch_get_main_queue(), {
58+
self.tableData = resultsArr
59+
self.appsTableView.reloadData()
60+
})
61+
}
62+
63+
64+
}
65+

SwiftTutorial/ViewController.swift

Lines changed: 0 additions & 37 deletions
This file was deleted.

0 commit comments

Comments
 (0)