Skip to content

Commit 6ecbe8b

Browse files
committed
Part 7
1 parent deb0086 commit 6ecbe8b

File tree

9 files changed

+219
-8
lines changed

9 files changed

+219
-8
lines changed

SwiftTutorial.xcodeproj/project.pbxproj

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
objects = {
88

99
/* Begin PBXBuildFile section */
10+
021C0E56194F506F0005B787 /* Track.swift in Sources */ = {isa = PBXBuildFile; fileRef = 021C0E55194F506F0005B787 /* Track.swift */; };
11+
021C0E58194F51610005B787 /* TrackCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 021C0E57194F51610005B787 /* TrackCell.swift */; };
1012
0256BB50194F3F38003E2942 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0256BB4F194F3F38003E2942 /* AppDelegate.swift */; };
1113
0256BB52194F3F38003E2942 /* SearchResultsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0256BB51194F3F38003E2942 /* SearchResultsViewController.swift */; };
1214
0256BB55194F3F38003E2942 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0256BB53194F3F38003E2942 /* Main.storyboard */; };
@@ -29,6 +31,8 @@
2931
/* End PBXContainerItemProxy section */
3032

3133
/* Begin PBXFileReference section */
34+
021C0E55194F506F0005B787 /* Track.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Track.swift; sourceTree = "<group>"; };
35+
021C0E57194F51610005B787 /* TrackCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TrackCell.swift; sourceTree = "<group>"; };
3236
0256BB4A194F3F38003E2942 /* SwiftTutorial.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SwiftTutorial.app; sourceTree = BUILT_PRODUCTS_DIR; };
3337
0256BB4E194F3F38003E2942 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
3438
0256BB4F194F3F38003E2942 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
@@ -92,6 +96,8 @@
9296
0256BB6C194F41F5003E2942 /* APIController.swift */,
9397
0256BB70194F4A9F003E2942 /* Album.swift */,
9498
0256BB72194F4B47003E2942 /* DetailsViewController.swift */,
99+
021C0E55194F506F0005B787 /* Track.swift */,
100+
021C0E57194F51610005B787 /* TrackCell.swift */,
95101
);
96102
path = SwiftTutorial;
97103
sourceTree = "<group>";
@@ -221,11 +227,13 @@
221227
isa = PBXSourcesBuildPhase;
222228
buildActionMask = 2147483647;
223229
files = (
230+
021C0E58194F51610005B787 /* TrackCell.swift in Sources */,
224231
0256BB52194F3F38003E2942 /* SearchResultsViewController.swift in Sources */,
225232
0256BB50194F3F38003E2942 /* AppDelegate.swift in Sources */,
226233
0256BB6D194F41F5003E2942 /* APIController.swift in Sources */,
227234
0256BB71194F4A9F003E2942 /* Album.swift in Sources */,
228235
0256BB73194F4B47003E2942 /* DetailsViewController.swift in Sources */,
236+
021C0E56194F506F0005B787 /* Track.swift in Sources */,
229237
);
230238
runOnlyForDeploymentPostprocessing = 0;
231239
};
@@ -413,6 +421,7 @@
413421
0256BB68194F3F38003E2942 /* Release */,
414422
);
415423
defaultConfigurationIsVisible = 0;
424+
defaultConfigurationName = Release;
416425
};
417426
0256BB69194F3F38003E2942 /* Build configuration list for PBXNativeTarget "SwiftTutorialTests" */ = {
418427
isa = XCConfigurationList;
@@ -421,6 +430,7 @@
421430
0256BB6B194F3F38003E2942 /* Release */,
422431
);
423432
defaultConfigurationIsVisible = 0;
433+
defaultConfigurationName = Release;
424434
};
425435
/* End XCConfigurationList section */
426436
};
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<Bucket
3+
type = "1"
4+
version = "2.0">
5+
<Breakpoints>
6+
<BreakpointProxy
7+
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
8+
<BreakpointContent
9+
shouldBeEnabled = "Yes"
10+
ignoreCount = "0"
11+
continueAfterRunningActions = "No"
12+
filePath = "SwiftTutorial/DetailsViewController.swift"
13+
timestampString = "424628985.454336"
14+
startingColumnNumber = "9223372036854775807"
15+
endingColumnNumber = "9223372036854775807"
16+
startingLineNumber = "64"
17+
endingLineNumber = "64"
18+
landmarkName = "tableView(_:cellForRowAtIndexPath:)"
19+
landmarkType = "5">
20+
</BreakpointContent>
21+
</BreakpointProxy>
22+
</Breakpoints>
23+
</Bucket>

SwiftTutorial/APIController.swift

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,15 @@ class APIController: NSObject {
2727
// Now escape anything else that isn't URL-friendly
2828
let escapedSearchTerm = itunesSearchTerm.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)
2929
let urlPath = "https://itunes.apple.com/search?term=\(escapedSearchTerm)&media=music&entity=album"
30-
let url = NSURL(string: urlPath)
30+
get(urlPath)
31+
}
32+
33+
func lookupAlbum(collectionId: Int) {
34+
get("https://itunes.apple.com/lookup?id=\(collectionId)&entity=song")
35+
}
36+
37+
func get(path: String) {
38+
let url = NSURL(string: path)
3139
let session = NSURLSession.sharedSession()
3240
let task = session.dataTaskWithURL(url, completionHandler: {data, response, error -> Void in
3341
println("Task completed")

SwiftTutorial/Album.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,15 @@ class Album {
1313
var largeImageURL: String?
1414
var itemURL: String?
1515
var artistURL: String?
16+
var collectionId: Int?
1617

17-
init(name: String!, price: String!, thumbnailImageURL: String!, largeImageURL: String!, itemURL: String!, artistURL: String!) {
18+
init(name: String!, price: String!, thumbnailImageURL: String!, largeImageURL: String!, itemURL: String!, artistURL: String!, collectionId: Int?) {
1819
self.title = name
1920
self.price = price
2021
self.thumbnailImageURL = thumbnailImageURL
2122
self.largeImageURL = largeImageURL
2223
self.itemURL = itemURL
2324
self.artistURL = artistURL
25+
self.collectionId = collectionId
2426
}
2527
}

SwiftTutorial/Base.lproj/Main.storyboard

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
2121
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
2222
<prototypes>
23-
<tableViewCell contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="SearchResultCell" textLabel="GZD-IL-v2Z" detailTextLabel="5Re-0H-SJG" style="IBUITableViewCellStyleSubtitle" id="IOy-Jh-366">
23+
<tableViewCell contentMode="scaleToFill" ambiguous="YES" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="SearchResultCell" textLabel="GZD-IL-v2Z" detailTextLabel="5Re-0H-SJG" style="IBUITableViewCellStyleSubtitle" id="IOy-Jh-366">
2424
<autoresizingMask key="autoresizingMask"/>
2525
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="IOy-Jh-366" id="Lwd-Ae-TbU">
2626
<autoresizingMask key="autoresizingMask"/>
@@ -90,6 +90,7 @@
9090
<viewControllerLayoutGuide type="bottom" id="4A1-t1-Q0W"/>
9191
</layoutGuides>
9292
<view key="view" contentMode="scaleToFill" id="SgI-CA-d2r">
93+
<rect key="frame" x="0.0" y="0.0" width="480" height="480"/>
9394
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
9495
<subviews>
9596
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="WgH-O9-qIk">
@@ -107,30 +108,88 @@
107108
<rect key="frame" x="110" y="76" width="100" height="100"/>
108109
</variation>
109110
</imageView>
111+
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" translatesAutoresizingMaskIntoConstraints="NO" id="tBO-zb-0h3">
112+
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
113+
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
114+
<prototypes>
115+
<tableViewCell contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="TrackCell" id="2nj-6t-oSQ" customClass="TrackCell" customModule="SwiftTutorial" customModuleProvider="target">
116+
<autoresizingMask key="autoresizingMask"/>
117+
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="2nj-6t-oSQ" id="ehN-cY-kCs">
118+
<autoresizingMask key="autoresizingMask"/>
119+
<subviews>
120+
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="0bg-Bt-Asa">
121+
<rect key="frame" x="0.0" y="-21" width="42" height="21"/>
122+
<fontDescription key="fontDescription" type="system" pointSize="17"/>
123+
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
124+
<nil key="highlightedColor"/>
125+
<variation key="heightClass=regular-widthClass=compact" fixedFrame="YES">
126+
<rect key="frame" x="57" y="12" width="243" height="21"/>
127+
</variation>
128+
</label>
129+
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="▶️" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Mcd-wa-lCc">
130+
<rect key="frame" x="0.0" y="-21" width="42" height="21"/>
131+
<fontDescription key="fontDescription" type="system" pointSize="17"/>
132+
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
133+
<nil key="highlightedColor"/>
134+
<variation key="heightClass=regular-widthClass=compact" fixedFrame="YES">
135+
<rect key="frame" x="20" y="10" width="29" height="24"/>
136+
</variation>
137+
</label>
138+
</subviews>
139+
<variation key="default">
140+
<mask key="subviews">
141+
<exclude reference="0bg-Bt-Asa"/>
142+
<exclude reference="Mcd-wa-lCc"/>
143+
</mask>
144+
</variation>
145+
<variation key="heightClass=regular-widthClass=compact">
146+
<mask key="subviews">
147+
<include reference="0bg-Bt-Asa"/>
148+
<include reference="Mcd-wa-lCc"/>
149+
</mask>
150+
</variation>
151+
</tableViewCellContentView>
152+
<connections>
153+
<outlet property="playIcon" destination="Mcd-wa-lCc" id="5IL-av-kEM"/>
154+
<outlet property="titleLabel" destination="0bg-Bt-Asa" id="AYE-rY-9Gp"/>
155+
</connections>
156+
</tableViewCell>
157+
</prototypes>
158+
<variation key="heightClass=regular-widthClass=compact" fixedFrame="YES">
159+
<rect key="frame" x="0.0" y="243" width="320" height="397"/>
160+
</variation>
161+
<connections>
162+
<outlet property="dataSource" destination="xtR-ZP-i6I" id="XEF-zY-V4W"/>
163+
<outlet property="delegate" destination="xtR-ZP-i6I" id="SwE-VK-0Ya"/>
164+
</connections>
165+
</tableView>
110166
</subviews>
111167
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
112168
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
113169
<variation key="default">
114170
<mask key="subviews">
115171
<exclude reference="WgH-O9-qIk"/>
116172
<exclude reference="AIH-2u-9AI"/>
173+
<exclude reference="tBO-zb-0h3"/>
117174
</mask>
118175
</variation>
119176
<variation key="heightClass=regular-widthClass=compact">
120177
<mask key="subviews">
121178
<include reference="WgH-O9-qIk"/>
122179
<include reference="AIH-2u-9AI"/>
180+
<include reference="tBO-zb-0h3"/>
123181
</mask>
124182
</variation>
125183
</view>
126184
<connections>
127185
<outlet property="albumCover" destination="AIH-2u-9AI" id="8jE-Og-JYE"/>
128186
<outlet property="titleLabel" destination="WgH-O9-qIk" id="dRW-M7-mY6"/>
187+
<outlet property="tracksTableView" destination="tBO-zb-0h3" id="Bs2-hh-ids"/>
129188
</connections>
130189
</viewController>
131190
<placeholder placeholderIdentifier="IBFirstResponder" id="rhu-ce-V5h" userLabel="First Responder" sceneMemberID="firstResponder"/>
132191
</objects>
133-
<point key="canvasLocation" x="1593" y="159.75"/>
192+
<point key="canvasLocation" x="1593" y="158.25"/>
134193
</scene>
135194
<!--Navigation Controller-->
136195
<scene sceneID="3Xq-0n-iKS">

SwiftTutorial/DetailsViewController.swift

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,19 @@
77
//
88

99
import UIKit
10+
import MediaPlayer
11+
import QuartzCore
1012

11-
class DetailsViewController: UIViewController {
13+
class DetailsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, APIControllerProtocol {
14+
15+
var mediaPlayer: MPMoviePlayerController = MPMoviePlayerController()
16+
var tracks: Track[] = []
1217

1318
@IBOutlet var albumCover : UIImageView
1419
@IBOutlet var titleLabel : UILabel
20+
@IBOutlet var tracksTableView : UITableView
21+
22+
@lazy var api: APIController = APIController(delegate: self)
1523

1624
var album: Album?
1725

@@ -23,5 +31,60 @@ class DetailsViewController: UIViewController {
2331
super.viewDidLoad()
2432
titleLabel.text = self.album?.title
2533
albumCover.image = UIImage(data: NSData(contentsOfURL: NSURL(string: self.album?.largeImageURL)))
34+
35+
// Load in tracks
36+
if self.album?.collectionId? {
37+
api.lookupAlbum(self.album!.collectionId!)
38+
}
39+
}
40+
41+
func didReceiveAPIResults(results: NSDictionary) {
42+
if let allResults = results["results"] as? NSDictionary[] {
43+
for trackInfo in allResults {
44+
// Create the track
45+
if let kind = trackInfo["kind"] as? String {
46+
if kind=="song" {
47+
var track = Track(dict: trackInfo)
48+
tracks.append(track)
49+
}
50+
}
51+
}
52+
}
53+
dispatch_async(dispatch_get_main_queue(), {
54+
self.tracksTableView.reloadData()
55+
})
56+
}
57+
58+
func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int {
59+
return tracks.count
60+
}
61+
62+
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
63+
var cell = tableView.dequeueReusableCellWithIdentifier("TrackCell") as TrackCell
64+
65+
var track = tracks[indexPath.row]
66+
cell.titleLabel.text = track.title
67+
cell.playIcon.text = "▶️"
68+
69+
return cell
70+
}
71+
72+
func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!) {
73+
var track = tracks[indexPath.row]
74+
mediaPlayer.stop()
75+
mediaPlayer.contentURL = NSURL(string: track.previewUrl)
76+
mediaPlayer.play()
77+
if let cell = tableView.cellForRowAtIndexPath(indexPath) as? TrackCell {
78+
cell.playIcon.text = "YOUR_STOP_ICON"
79+
}
2680
}
81+
82+
func tableView(tableView: UITableView!, willDisplayCell cell: UITableViewCell!, forRowAtIndexPath indexPath: NSIndexPath!) {
83+
cell.layer.transform = CATransform3DMakeScale(0.1,0.1,1)
84+
UIView.animateWithDuration(0.25, animations: {
85+
cell.layer.transform = CATransform3DMakeScale(1,1,1)
86+
})
87+
}
88+
89+
2790
}

SwiftTutorial/SearchResultsViewController.swift

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//
88

99
import UIKit
10+
import QuartzCore
1011

1112
class SearchResultsViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, APIControllerProtocol {
1213

@@ -147,16 +148,25 @@ class SearchResultsViewController: UIViewController, UITableViewDataSource, UITa
147148
itemURL = result["trackViewUrl"] as? String
148149
}
149150

150-
var newAlbum = Album(name: name!, price: price!, thumbnailImageURL: thumbnailURL!, largeImageURL: imageURL!, itemURL: itemURL!, artistURL: artistURL!)
151+
var collectionId = result["collectionId"] as? Int
152+
var newAlbum = Album(name: name!, price: price!, thumbnailImageURL: thumbnailURL!, largeImageURL: imageURL!, itemURL: itemURL!, artistURL: artistURL!, collectionId: collectionId!)
151153
albums.append(newAlbum)
152154
}
153155

156+
dispatch_async(dispatch_get_main_queue(), {
157+
self.appsTableView.reloadData()
158+
})
154159

155-
self.appsTableView.reloadData()
156160
UIApplication.sharedApplication().networkActivityIndicatorVisible = false
157161
}
158162
}
159-
163+
164+
func tableView(tableView: UITableView!, willDisplayCell cell: UITableViewCell!, forRowAtIndexPath indexPath: NSIndexPath!) {
165+
cell.layer.transform = CATransform3DMakeScale(0.1,0.1,1)
166+
UIView.animateWithDuration(0.25, animations: {
167+
cell.layer.transform = CATransform3DMakeScale(1,1,1)
168+
})
169+
}
160170

161171
}
162172

0 commit comments

Comments
 (0)