Skip to content

Commit 94a4aa8

Browse files
committed
Handle response as parsed JSON objects with data request extension
1 parent 98f2964 commit 94a4aa8

File tree

3 files changed

+91
-38
lines changed

3 files changed

+91
-38
lines changed

iCookTV.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
B543C3EF1CD1FD0B008C512B /* GroundControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = B543C3EE1CD1FD0B008C512B /* GroundControl.swift */; };
3434
B543C3F11CD21530008C512B /* Tracker.swift in Sources */ = {isa = PBXBuildFile; fileRef = B543C3F01CD21530008C512B /* Tracker.swift */; };
3535
B543C3F31CD34419008C512B /* Video+PlayerItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = B543C3F21CD34419008C512B /* Video+PlayerItem.swift */; };
36+
B546053A1DDB482A00208D37 /* DataRequest+Result.swift in Sources */ = {isa = PBXBuildFile; fileRef = B54605391DDB482A00208D37 /* DataRequest+Result.swift */; };
3637
B5501BE31CD74206001C3281 /* TrackableNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5501BE21CD74206001C3281 /* TrackableNavigationController.swift */; };
3738
B5501BE91CD8ACEC001C3281 /* Trackable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5501BE81CD8ACEC001C3281 /* Trackable.swift */; };
3839
B55BF7E71DC5B7F400EE20BD /* Reusable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B55BF7E61DC5B7F400EE20BD /* Reusable.swift */; };
@@ -111,6 +112,7 @@
111112
B543C3EE1CD1FD0B008C512B /* GroundControl.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GroundControl.swift; sourceTree = "<group>"; };
112113
B543C3F01CD21530008C512B /* Tracker.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Tracker.swift; sourceTree = "<group>"; };
113114
B543C3F21CD34419008C512B /* Video+PlayerItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Video+PlayerItem.swift"; sourceTree = "<group>"; };
115+
B54605391DDB482A00208D37 /* DataRequest+Result.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "DataRequest+Result.swift"; sourceTree = "<group>"; };
114116
B5501BE21CD74206001C3281 /* TrackableNavigationController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TrackableNavigationController.swift; sourceTree = "<group>"; };
115117
B5501BE81CD8ACEC001C3281 /* Trackable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Trackable.swift; sourceTree = "<group>"; };
116118
B55BF7E61DC5B7F400EE20BD /* Reusable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Reusable.swift; sourceTree = "<group>"; };
@@ -187,6 +189,7 @@
187189
isa = PBXGroup;
188190
children = (
189191
B52EC3B01CB26F1B0072762C /* CGRect+Grid.swift */,
192+
B54605391DDB482A00208D37 /* DataRequest+Result.swift */,
190193
B53E39771CA1494000EB1EEE /* UIColor+TV.swift */,
191194
B52EC3B21CB3A02E0072762C /* UIFont+TV.swift */,
192195
B5C85D031CA97981000AE0CF /* UIImage+Grid.swift */,
@@ -622,6 +625,7 @@
622625
B58DE38B1CB8B54200C00266 /* CoverBuilder.swift in Sources */,
623626
B52BD6751D5F94320023D4E9 /* DataCollection.swift in Sources */,
624627
B5EE17501DC509B8009DA1AE /* DataFetching.swift in Sources */,
628+
B546053A1DDB482A00208D37 /* DataRequest+Result.swift in Sources */,
625629
B52BD6791D6024D30023D4E9 /* DataSource.swift in Sources */,
626630
B50BFC051CC88FA3004F853D /* Debug.swift in Sources */,
627631
B55BF7E91DC5C3C400EE20BD /* DropdownMenuPresentable.swift in Sources */,
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
//
2+
// DataRequest+Result.swift
3+
// TryTVOS
4+
//
5+
// Created by Ben on 11/15/16.
6+
// Copyright © 2016 bcylin.
7+
//
8+
// Permission is hereby granted, free of charge, to any person obtaining a copy
9+
// of this software and associated documentation files (the "Software"), to deal
10+
// in the Software without restriction, including without limitation the rights
11+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
// copies of the Software, and to permit persons to whom the Software is
13+
// furnished to do so, subject to the following conditions:
14+
//
15+
// The above copyright notice and this permission notice shall be included in all
16+
// copies or substantial portions of the Software.
17+
//
18+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24+
// SOFTWARE.
25+
//
26+
27+
import Foundation
28+
import Alamofire
29+
import Freddy
30+
31+
enum Result<T> {
32+
case success(T)
33+
case failure(Error)
34+
35+
func mapSuccess<U>(_ transform: (T) -> U) -> Result<U> {
36+
switch self {
37+
case .success(let value): return .success(transform(value))
38+
case .failure(let error): return .failure(error)
39+
}
40+
}
41+
42+
func mapError(_ transform: (Error) -> Void) -> Result<T> {
43+
switch self {
44+
case .success(_): break
45+
case .failure(let error): transform(error)
46+
}
47+
return self
48+
}
49+
50+
}
51+
52+
53+
////////////////////////////////////////////////////////////////////////////////
54+
55+
56+
extension DataRequest {
57+
58+
func responseJSONObject(
59+
queue: DispatchQueue? = nil,
60+
options: JSONSerialization.ReadingOptions = .allowFragments,
61+
completion: @escaping (Result<JSON>) -> Void
62+
) -> Self {
63+
let serializer = DataRequest.jsonResponseSerializer(options: options)
64+
65+
return response(queue: queue, responseSerializer: serializer) { response in
66+
guard let data = response.data else {
67+
let error = response.result.error ?? NSError(domain: "io.github.bcylin.try-tvos", code: NSURLErrorUnknown, userInfo: nil)
68+
completion(.failure(error))
69+
return
70+
}
71+
72+
do {
73+
let json = try JSON(data: data)
74+
completion(.success(json))
75+
} catch {
76+
completion(.failure(error))
77+
}
78+
}
79+
}
80+
81+
}

iCookTV/Protocols/DataFetching.swift

Lines changed: 6 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -27,31 +27,6 @@
2727
import Alamofire
2828
import Freddy
2929

30-
enum Result<T> {
31-
case success(T)
32-
case failure(Error)
33-
34-
func mapSuccess<U>(_ transform: (T) -> U) -> Result<U> {
35-
switch self {
36-
case .success(let value): return .success(transform(value))
37-
case .failure(let error): return .failure(error)
38-
}
39-
}
40-
41-
func mapError(_ transform: (Error) -> Void) -> Result<T> {
42-
switch self {
43-
case .success(_): break
44-
case .failure(let error): transform(error)
45-
}
46-
return self
47-
}
48-
49-
}
50-
51-
52-
////////////////////////////////////////////////////////////////////////////////
53-
54-
5530
protocol DataFetching: class {
5631
/// A reference to the pagination object that prevents duplicate requests.
5732
var pagination: Pagination { get }
@@ -73,26 +48,19 @@ extension DataFetching {
7348
return
7449
}
7550

76-
pagination.currentRequest = sessionManager.request(request).responseJSON { [weak self] response in
77-
guard let data = response.data, response.result.error == nil else {
78-
completion(.failure(response.result.error!))
79-
return
80-
}
81-
82-
guard let pagination = self?.pagination else {
83-
return
84-
}
85-
86-
pagination.queue.async {
51+
pagination.currentRequest = sessionManager.request(request).responseJSONObject(queue: pagination.queue) { [weak self] result in
52+
switch result {
53+
case let .success(json):
8754
do {
88-
let json = try JSON(data: data)
8955
let items = try json.getArray(at: "data").map(T.init)
90-
pagination.hasNextPage = json["links"]?["next"] != nil
56+
self?.pagination.hasNextPage = json["links"]?["next"] != nil
9157

9258
DispatchQueue.main.sync { completion(.success(items)) }
9359
} catch {
9460
DispatchQueue.main.sync { completion(.failure(error)) }
9561
}
62+
case let .failure(error):
63+
DispatchQueue.main.sync { completion(.failure(error)) }
9664
}
9765
}
9866
}

0 commit comments

Comments
 (0)