-
Notifications
You must be signed in to change notification settings - Fork 749
Expand file tree
/
Copy pathGraphQLResponse.swift
More file actions
96 lines (83 loc) · 3.24 KB
/
GraphQLResponse.swift
File metadata and controls
96 lines (83 loc) · 3.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#if !COCOAPODS
import ApolloMigrationAPI
#endif
/// Represents a complete GraphQL response received from a server.
public final class GraphQLResponse<Data: RootSelectionSet> {
private let base: AnyGraphQLResponse
public init<Operation: GraphQLOperation>(
operation: Operation,
body: JSONObject
) where Operation.Data == Data {
self.base = AnyGraphQLResponse(
body: body,
rootKey: CacheReference.rootCacheReference(for: Operation.operationType),
variables: operation.__variables
)
}
/// Parses the response into a `GraphQLResult` and a `RecordSet` depending on the cache policy. The result can be
/// sent to a completion block for a request and the `RecordSet` can be merged into a local cache.
///
/// - Returns: A tuple of a `GraphQLResult` and an optional `RecordSet`.
///
/// - Parameter cachePolicy: Used to determine whether a cache `RecordSet` is returned. A cache policy that does
/// not read or write to the cache will return a `nil` cache `RecordSet`.
public func parseResult(withCachePolicy cachePolicy: CachePolicy) throws -> (GraphQLResult<Data>, RecordSet?) {
switch cachePolicy {
case .fetchIgnoringCacheCompletely:
// There is no cache, so we don't need to get any info on dependencies. Use fast parsing.
return (try parseResultFast(), nil)
default:
return try parseResult()
}
}
/// Parses a response into a `GraphQLResult` and a `RecordSet`. The result can be sent to a completion block for a
/// request and the `RecordSet` can be merged into a local cache.
///
/// - Returns: A `GraphQLResult` and a `RecordSet`.
public func parseResult() throws -> (GraphQLResult<Data>, RecordSet?) {
let accumulator = zip(
GraphQLSelectionSetMapper<Data>(),
ResultNormalizerFactory.networkResponseDataNormalizer(),
GraphQLDependencyTracker()
)
let executionResult = try base.execute(
selectionSet: Data.self,
with: accumulator
)
let result = makeResult(data: executionResult?.0, dependentKeys: executionResult?.2)
return (result, executionResult?.1)
}
/// Parses a response into a `GraphQLResult` for use without the cache. This parsing does not
/// create dependent keys or a `RecordSet` for the cache.
///
/// This is faster than `parseResult()` and should be used when cache the response is not needed.
public func parseResultFast() throws -> GraphQLResult<Data> {
let accumulator = GraphQLSelectionSetMapper<Data>()
let data = try base.execute(
selectionSet: Data.self,
with: accumulator
)
return makeResult(data: data, dependentKeys: nil)
}
private func makeResult(data: Data?, dependentKeys: Set<CacheKey>?) -> GraphQLResult<Data> {
return GraphQLResult(
data: data,
extensions: base.parseExtensions(),
errors: base.parseErrors(),
source: .server,
dependentKeys: dependentKeys
)
}
}
// MARK: - Equatable Conformance
extension GraphQLResponse: Equatable where Data: Equatable {
public static func == (lhs: GraphQLResponse<Data>, rhs: GraphQLResponse<Data>) -> Bool {
lhs.base == rhs.base
}
}
// MARK: - Hashable Conformance
extension GraphQLResponse: Hashable {
public func hash(into hasher: inout Hasher) {
hasher.combine(base)
}
}