Skip to content

Commit 3f79804

Browse files
authored
chore: kickoff v1 release
2 parents 245d8d0 + 50b556e commit 3f79804

File tree

20 files changed

+356
-145
lines changed

20 files changed

+356
-145
lines changed

Amplify/Categories/API/Operation/RetryableGraphQLOperation.swift

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public protocol RetryableGraphQLOperationBehavior: Operation, DefaultLogger {
2121
/// GraphQLOperation concrete type
2222
associatedtype OperationType: AnyGraphQLOperation
2323

24-
typealias RequestFactory = () -> GraphQLRequest<Payload>
24+
typealias RequestFactory = (@escaping (GraphQLRequest<Payload>) -> Void) -> Void
2525
typealias OperationFactory = (GraphQLRequest<Payload>, @escaping OperationResultListener) -> OperationType
2626
typealias OperationResultListener = OperationType.ResultListener
2727

@@ -64,7 +64,10 @@ extension RetryableGraphQLOperationBehavior {
6464
let wrappedResultListener: OperationResultListener = { result in
6565
if case let .failure(error) = result, self.shouldRetry(error: error as? APIError) {
6666
self.log.debug("\(error)")
67-
self.start(request: self.requestFactory())
67+
self.requestFactory { [weak self] request in
68+
self?.start(request: request)
69+
}
70+
6871
return
6972
}
7073

@@ -95,7 +98,7 @@ public final class RetryableGraphQLOperation<Payload: Decodable>: Operation, Ret
9598
public var resultListener: OperationResultListener
9699
public var operationFactory: OperationFactory
97100

98-
public init(requestFactory: @escaping () -> GraphQLRequest<Payload>,
101+
public init(requestFactory: @escaping RetryableGraphQLOperation<Payload>.RequestFactory,
99102
maxRetries: Int,
100103
resultListener: @escaping OperationResultListener,
101104
_ operationFactory: @escaping OperationFactory) {
@@ -106,7 +109,9 @@ public final class RetryableGraphQLOperation<Payload: Decodable>: Operation, Ret
106109
self.resultListener = resultListener
107110
}
108111
public override func main() {
109-
start(request: requestFactory())
112+
requestFactory { [weak self] request in
113+
self?.start(request: request)
114+
}
110115
}
111116

112117
public override func cancel() {
@@ -154,7 +159,9 @@ public final class RetryableGraphQLSubscriptionOperation<Payload: Decodable>: Op
154159
self.resultListener = resultListener
155160
}
156161
public override func main() {
157-
start(request: requestFactory())
162+
requestFactory { [weak self] request in
163+
self?.start(request: request)
164+
}
158165
}
159166

160167
public override func cancel() {

Amplify/Core/Support/Optional+Extension.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
// SPDX-License-Identifier: Apache-2.0
66
//
77

8-
98
import Foundation
109

1110
extension Optional {

AmplifyPlugins/API/AWSAPICategoryPlugin/Operation/AWSRESTOperation.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,3 +125,4 @@ final public class AWSRESTOperation: AmplifyOperation<
125125
task.resume()
126126
}
127127
}
128+

AmplifyPlugins/API/Podfile.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,4 +116,4 @@ SPEC CHECKSUMS:
116116

117117
PODFILE CHECKSUM: 5170578806036f2ba018abb8868d56e448fb0ada
118118

119-
COCOAPODS: 1.11.3
119+
COCOAPODS: 1.12.0

AmplifyPlugins/DataStore/AWSDataStoreCategoryPlugin/Sync/InitialSync/InitialSyncOperation.swift

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -140,15 +140,16 @@ final class InitialSyncOperation: AsynchronousOperation {
140140
}
141141

142142
var authTypes = authModeStrategy.authTypesFor(schema: modelSchema,
143-
operation: .read)
144-
145-
RetryableGraphQLOperation(requestFactory: {
146-
GraphQLRequest<SyncQueryResult>.syncQuery(modelSchema: self.modelSchema,
147-
where: queryPredicate,
148-
limit: limit,
149-
nextToken: nextToken,
150-
lastSync: lastSyncTime,
151-
authType: authTypes.next())
143+
operation: .read)
144+
145+
RetryableGraphQLOperation(requestFactory: { completion in
146+
completion(GraphQLRequest<SyncQueryResult>.syncQuery(modelSchema: self.modelSchema,
147+
where: queryPredicate,
148+
limit: limit,
149+
nextToken: nextToken,
150+
lastSync: lastSyncTime,
151+
authType: authTypes.next()))
152+
152153
},
153154
maxRetries: authTypes.count,
154155
resultListener: completionListener, { nextRequest, wrappedCompletionListener in

AmplifyPlugins/DataStore/AWSDataStoreCategoryPlugin/Sync/MutationSync/AWSMutationDatabaseAdapter/AWSMutationDatabaseAdapter+MutationEventIngester.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ extension AWSMutationDatabaseAdapter: MutationEventIngester {
5151
}
5252

5353
MutationEvent.pendingMutationEvents(
54-
for: mutationEvent.modelId,
54+
forMutationEvent: mutationEvent,
5555
storageAdapter: storageAdapter) { result in
5656
switch result {
5757
case .failure(let dataStoreError):

AmplifyPlugins/DataStore/AWSDataStoreCategoryPlugin/Sync/SubscriptionSync/IncomingAsyncSubscriptionEventPublisher.swift

Lines changed: 98 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -196,38 +196,97 @@ final class IncomingAsyncSubscriptionEventPublisher: AmplifyCancellable {
196196
}
197197

198198
// swiftlint:disable:next function_parameter_count
199-
static func makeAPIRequest(for modelSchema: ModelSchema,
200-
subscriptionType: GraphQLSubscriptionType,
201-
api: APICategoryGraphQLBehavior,
202-
auth: AuthCategoryBehavior?,
203-
authType: AWSAuthorizationType?,
204-
awsAuthService: AWSAuthServiceBehavior) -> GraphQLRequest<Payload> {
205-
let request: GraphQLRequest<Payload>
206-
if modelSchema.hasAuthenticationRules,
207-
auth != nil,
208-
case .success(let tokenString) = awsAuthService.getToken(),
209-
case .success(let claims) = awsAuthService.getTokenClaims(tokenString: tokenString) {
210-
request = GraphQLRequest<Payload>.subscription(to: modelSchema,
211-
subscriptionType: subscriptionType,
212-
claims: claims,
213-
authType: authType)
214-
} else if modelSchema.hasAuthenticationRules,
215-
let oidcAuthProvider = hasOIDCAuthProviderAvailable(api: api),
216-
case .success(let tokenString) = oidcAuthProvider.getLatestAuthToken(),
217-
case .success(let claims) = awsAuthService.getTokenClaims(tokenString: tokenString) {
218-
request = GraphQLRequest<Payload>.subscription(to: modelSchema,
219-
subscriptionType: subscriptionType,
220-
claims: claims,
221-
authType: authType)
199+
static func makeAPIRequest(
200+
for modelSchema: ModelSchema,
201+
subscriptionType: GraphQLSubscriptionType,
202+
api: APICategoryGraphQLBehavior,
203+
auth: AuthCategoryBehavior?,
204+
authType: AWSAuthorizationType?,
205+
awsAuthService: AWSAuthServiceBehavior,
206+
completion: @escaping (GraphQLRequest<Payload>) -> Void) {
207+
208+
let requestWithOutClaims = GraphQLRequest<Payload>.subscription(
209+
to: modelSchema,
210+
subscriptionType: subscriptionType,
211+
authType: authType)
212+
213+
guard modelSchema.hasAuthenticationRules else {
214+
completion(requestWithOutClaims)
215+
return
216+
}
217+
218+
getClaims(api: api,
219+
auth: auth,
220+
awsAuthService: awsAuthService) { claims in
221+
222+
guard let claims = claims else {
223+
completion(requestWithOutClaims)
224+
return
225+
}
226+
let request = GraphQLRequest<Payload>.subscription(
227+
to: modelSchema,
228+
subscriptionType: subscriptionType,
229+
claims: claims,
230+
authType: authType)
231+
completion(request)
232+
return
233+
}
234+
235+
}
236+
237+
static func getClaims(api: APICategoryGraphQLBehavior,
238+
auth: AuthCategoryBehavior?,
239+
awsAuthService: AWSAuthServiceBehavior,
240+
completion: @escaping ([String: AnyObject]?) -> Void) {
241+
if auth != nil {
242+
getClaimsFromUserPool(awsAuthService: awsAuthService) { claims in
243+
if let claims = claims {
244+
completion(claims)
245+
} else {
246+
getClaimsFromOIDCProvider(
247+
api: api,
248+
awsAuthService: awsAuthService,
249+
completion: completion)
250+
}
251+
}
222252
} else {
223-
request = GraphQLRequest<Payload>.subscription(to: modelSchema,
224-
subscriptionType: subscriptionType,
225-
authType: authType)
253+
getClaimsFromOIDCProvider(
254+
api: api,
255+
awsAuthService: awsAuthService,
256+
completion: completion)
226257
}
227258

228-
return request
229259
}
230260

261+
static func getClaimsFromUserPool(
262+
awsAuthService: AWSAuthServiceBehavior,
263+
completion: @escaping ([String: AnyObject]?) -> Void) {
264+
265+
awsAuthService.getUserPoolAccessToken { result in
266+
if case .success(let tokenString) = result,
267+
case .success(let claims) = awsAuthService.getTokenClaims(tokenString: tokenString) {
268+
completion(claims)
269+
} else {
270+
completion(nil)
271+
}
272+
}
273+
}
274+
275+
static func getClaimsFromOIDCProvider(
276+
api: APICategoryGraphQLBehavior,
277+
awsAuthService: AWSAuthServiceBehavior,
278+
completion: @escaping ([String: AnyObject]?) -> Void) {
279+
280+
guard let oidcAuthProvider = hasOIDCAuthProviderAvailable(api: api),
281+
case .success(let tokenString) = oidcAuthProvider.getLatestAuthToken(),
282+
case .success(let claims) = awsAuthService.getTokenClaims(tokenString: tokenString)
283+
else {
284+
completion(nil)
285+
return
286+
}
287+
completion(claims)
288+
}
289+
231290
static func hasOIDCAuthProviderAvailable(api: APICategoryGraphQLBehavior) -> AmplifyOIDCAuthProvider? {
232291
if let apiPlugin = api as? APICategoryAuthProviderFactoryBehavior,
233292
let oidcAuthProvider = apiPlugin.apiAuthProviderFactory().oidcAuthProvider() {
@@ -292,16 +351,20 @@ extension IncomingAsyncSubscriptionEventPublisher {
292351
api: APICategoryGraphQLBehavior,
293352
auth: AuthCategoryBehavior?,
294353
awsAuthService: AWSAuthServiceBehavior,
295-
authTypeProvider: AWSAuthorizationTypeIterator) -> RetryableGraphQLOperation<Payload>.RequestFactory {
354+
authTypeProvider: AWSAuthorizationTypeIterator)
355+
-> RetryableGraphQLOperation<Payload>.RequestFactory {
356+
296357
// swiftlint:disable:previous line_length
297358
var authTypes = authTypeProvider
298-
return {
299-
return IncomingAsyncSubscriptionEventPublisher.makeAPIRequest(for: modelSchema,
300-
subscriptionType: subscriptionType,
301-
api: api,
302-
auth: auth,
303-
authType: authTypes.next(),
304-
awsAuthService: awsAuthService)
359+
return { completion in
360+
return IncomingAsyncSubscriptionEventPublisher.makeAPIRequest(
361+
for: modelSchema,
362+
subscriptionType: subscriptionType,
363+
api: api,
364+
auth: auth,
365+
authType: authTypes.next(),
366+
awsAuthService: awsAuthService,
367+
completion: completion)
305368
}
306369
}
307370
}

AmplifyPlugins/DataStore/AWSDataStoreCategoryPlugin/Sync/SubscriptionSync/ReconcileAndLocalSave/ReconcileAndLocalSaveOperation.swift

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -124,11 +124,9 @@ class ReconcileAndLocalSaveOperation: AsynchronousOperation {
124124
return
125125
}
126126

127-
let remoteModelIds = remoteModels.map { $0.model.identifier }
128-
129127
do {
130128
try storageAdapter.transaction {
131-
queryPendingMutations(forModelIds: remoteModelIds)
129+
queryPendingMutations(forModels: remoteModels.map(\.model))
132130
.subscribe(on: workQueue)
133131
.flatMap { mutationEvents -> Future<([RemoteModel], [LocalMetadata]), DataStoreError> in
134132
let remoteModelsToApply = self.reconcile(remoteModels, pendingMutations: mutationEvents)
@@ -159,7 +157,7 @@ class ReconcileAndLocalSaveOperation: AsynchronousOperation {
159157
}
160158
}
161159

162-
func queryPendingMutations(forModelIds modelIds: [Model.Identifier]) -> Future<[MutationEvent], DataStoreError> {
160+
func queryPendingMutations(forModels models: [Model]) -> Future<[MutationEvent], DataStoreError> {
163161
Future<[MutationEvent], DataStoreError> { promise in
164162
var result: Result<[MutationEvent], DataStoreError> = .failure(Self.unfulfilledDataStoreError())
165163
defer {
@@ -172,21 +170,23 @@ class ReconcileAndLocalSaveOperation: AsynchronousOperation {
172170
}
173171
guard let storageAdapter = self.storageAdapter else {
174172
let error = DataStoreError.nilStorageAdapter()
175-
self.notifyDropped(count: modelIds.count, error: error)
173+
self.notifyDropped(count: models.count, error: error)
176174
result = .failure(error)
177175
return
178176
}
179177

180-
guard !modelIds.isEmpty else {
178+
guard !models.isEmpty else {
181179
result = .success([])
182180
return
183181
}
184182

185-
MutationEvent.pendingMutationEvents(for: modelIds,
186-
storageAdapter: storageAdapter) { queryResult in
183+
MutationEvent.pendingMutationEvents(
184+
forModels: models,
185+
storageAdapter: storageAdapter
186+
) { queryResult in
187187
switch queryResult {
188188
case .failure(let dataStoreError):
189-
self.notifyDropped(count: modelIds.count, error: dataStoreError)
189+
self.notifyDropped(count: models.count, error: dataStoreError)
190190
result = .failure(dataStoreError)
191191
case .success(let mutationEvents):
192192
result = .success(mutationEvents)

AmplifyPlugins/DataStore/AWSDataStoreCategoryPlugin/Sync/Support/MutationEvent+Extensions.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ extension MutationEvent {
4040
storageAdapter: StorageEngineAdapter,
4141
completion: @escaping DataStoreCallback<Void>) {
4242
MutationEvent.pendingMutationEvents(
43-
for: mutationEvent.modelId,
43+
forMutationEvent: mutationEvent,
4444
storageAdapter: storageAdapter) { queryResult in
4545
switch queryResult {
4646
case .failure(let dataStoreError):

0 commit comments

Comments
 (0)