Skip to content

Commit

Permalink
Add docs and improve merging of records from WebSockets into cache. (#…
Browse files Browse the repository at this point in the history
…1892)

* Add docs and improve merging of records from WebSockets into cache.

* Fix compiler bug issue
  • Loading branch information
AnthonyMDev authored Aug 5, 2021
1 parent 3358410 commit a186027
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 14 deletions.
7 changes: 7 additions & 0 deletions Sources/Apollo/ApolloStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,13 @@ public final class ApolloStore {
}
}

/// Merges a `RecordSet` into the normalized cache.
/// - Parameters:
/// - records: The records to be merged into the cache.
/// - identifier: [optional] A unique identifier for the request that kicked off this change,
/// to assist in de-duping cache hits for watchers.
/// - callbackQueue: The queue to call the completion block on. Defaults to `DispatchQueue.main`.
/// - completion: [optional] A completion block to be called after records are merged into the cache.
public func publish(records: RecordSet, identifier: UUID? = nil, callbackQueue: DispatchQueue = .main, completion: ((Result<Void, Error>) -> Void)? = nil) {
queue.async(flags: .barrier) {
do {
Expand Down
5 changes: 5 additions & 0 deletions Sources/Apollo/GraphQLResponse.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ public final class GraphQLResponse<Data: GraphQLSelectionSet> {
self.variables = operation.variables
}

/// Parses a response into a `GraphQLResult` and a `RecordSet`.
/// The result can be sent to a completion block for a request.
/// The `RecordSet` can be merged into a local cache.
/// - Parameter cacheKeyForObject: See `CacheKeyForObject`
/// - Returns: A `GraphQLResult` and a `RecordSet`.
public func parseResult(cacheKeyForObject: CacheKeyForObject? = nil) throws -> (GraphQLResult<Data>, RecordSet?) {
let errors: [GraphQLError]?

Expand Down
41 changes: 27 additions & 14 deletions Sources/ApolloWebSocket/WebSocketTransport.swift
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ public class WebSocketTransport {
///
/// - Parameters:
/// - websocket: The websocket client to use for creating a websocket connection.
/// - store: [optional] The `ApolloStore` used as a local cache. Defaults to `nil`.
/// - clientName: The client name to use for this client. Defaults to `Self.defaultClientName`
/// - clientVersion: The client version to use for this client. Defaults to `Self.defaultClientVersion`.
/// - sendOperationIdentifiers: Whether or not to send operation identifiers with operations. Defaults to false.
Expand Down Expand Up @@ -362,24 +363,36 @@ extension WebSocketTransport: NetworkTransport {
return EmptyCancellable()
}

return WebSocketTask(self, operation) { [store] result in
return WebSocketTask(self, operation) { [weak store, contextIdentifier, callbackQueue] result in
switch result {
case .success(let jsonBody):
let response = GraphQLResponse(operation: operation, body: jsonBody)
if let store = store {
do {
let (_, records) = try response.parseResult(cacheKeyForObject: store.cacheKeyForObject)
if let records = records {
store.publish(records: records, identifier: nil)
do {
let response = GraphQLResponse(operation: operation, body: jsonBody)

if let store = store {
let (graphQLResult, parsedRecords) = try response.parseResult(cacheKeyForObject: store.cacheKeyForObject)
guard let records = parsedRecords else {
callCompletion(with: .success(graphQLResult))
return
}

store.publish(records: records,
identifier: contextIdentifier,
callbackQueue: callbackQueue) { result in
switch result {
case .success:
completionHandler(.success(graphQLResult))

case let .failure(error):
callCompletion(with: .failure(error))
}
}
} catch {
callCompletion(with: .failure(error))

} else {
let graphQLResult = try response.parseResultFast()
callCompletion(with: .success(graphQLResult))
}
}

do {
let graphQLResult = try response.parseResultFast()
callCompletion(with: .success(graphQLResult))

} catch {
callCompletion(with: .failure(error))
}
Expand Down

0 comments on commit a186027

Please sign in to comment.