Skip to content

feat: PR #369 with reverting back to AmplifyModelRegistration #394

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Apr 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion Amplify.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@
B98E9D142372236300934B51 /* QueryPredicate+Equatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B98E9D0C2372236200934B51 /* QueryPredicate+Equatable.swift */; };
B996FC4423FF2FA8006D0F68 /* Encodable+AnyEncodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B996FC4323FF2FA8006D0F68 /* Encodable+AnyEncodable.swift */; };
B996FC4D24059918006D0F68 /* Model+Enum.swift in Sources */ = {isa = PBXBuildFile; fileRef = B996FC4C24059918006D0F68 /* Model+Enum.swift */; };
B9A329CC243559BF00C5B80C /* TimeInterval+Helper.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9A329CB243559BF00C5B80C /* TimeInterval+Helper.swift */; };
B9B64A9F23FCBF7E00730B68 /* ModelValueConverter.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9B64A9E23FCBF7E00730B68 /* ModelValueConverter.swift */; };
B9DCA263240F217C00075E22 /* AnyEncodableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9DCA262240F217C00075E22 /* AnyEncodableTests.swift */; };
B9FAA10B23878122009414B4 /* ModelField+Association.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9FAA10A23878122009414B4 /* ModelField+Association.swift */; };
Expand Down Expand Up @@ -846,6 +847,7 @@
B99209E22411E49D00F80010 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
B996FC4323FF2FA8006D0F68 /* Encodable+AnyEncodable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Encodable+AnyEncodable.swift"; sourceTree = "<group>"; };
B996FC4C24059918006D0F68 /* Model+Enum.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Model+Enum.swift"; sourceTree = "<group>"; };
B9A329CB243559BF00C5B80C /* TimeInterval+Helper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TimeInterval+Helper.swift"; sourceTree = "<group>"; };
B9B64A9E23FCBF7E00730B68 /* ModelValueConverter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModelValueConverter.swift; sourceTree = "<group>"; };
B9DCA262240F217C00075E22 /* AnyEncodableTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnyEncodableTests.swift; sourceTree = "<group>"; };
B9FAA10A23878122009414B4 /* ModelField+Association.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ModelField+Association.swift"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1740,7 +1742,6 @@
B92E03A62367CE7A006CEB8D /* Model */ = {
isa = PBXGroup;
children = (
2129BE502395A66F006363A1 /* AmplifyModelRegistration.swift */,
B92E03A72367CE7A006CEB8D /* Model.swift */,
B9FAA17F238FBB5D009414B4 /* Model+Array.swift */,
B92E03AC2367CE7A006CEB8D /* Model+Codable.swift */,
Expand All @@ -1750,6 +1751,7 @@
FA8EE77C238627350097E4F1 /* Model+Subscript.swift */,
B92E03A92367CE7A006CEB8D /* ModelRegistry.swift */,
FA5D4CF2238AFD7B00D2F54A /* ModelRegistry+Syncable.swift */,
2129BE502395A66F006363A1 /* AmplifyModelRegistration.swift */,
FA8EE780238628490097E4F1 /* Persistable.swift */,
FA8EE775238626C70097E4F1 /* AnyModel */,
B9FAA1232388BE2B009414B4 /* Collection */,
Expand Down Expand Up @@ -2090,6 +2092,7 @@
FAE4145E23999BC900CE94C2 /* Result+Void.swift */,
FA56F72422B14B6A0039754A /* Resumable.swift */,
B9FAA174238EFC59009414B4 /* String+Extensions.swift */,
B9A329CB243559BF00C5B80C /* TimeInterval+Helper.swift */,
219A88EC23F3309800BBC5F2 /* Tree.swift */,
);
path = Support;
Expand Down Expand Up @@ -3777,6 +3780,7 @@
FAC2351C227A053D00424678 /* APICategoryPlugin.swift in Sources */,
FA176ED52385012000C5C5F9 /* DataStoreCategory+HubPayloadEventName.swift in Sources */,
210DBC162332B3CB009B9E51 /* StorageDownloadDataOperation.swift in Sources */,
B9A329CC243559BF00C5B80C /* TimeInterval+Helper.swift in Sources */,
950A26DC23D15D7E00D92B19 /* PredictionsTextToSpeechOperation.swift in Sources */,
FAC235A3227A5ED000424678 /* HubChannel.swift in Sources */,
FAA2E8CE23A02A8100E420EA /* PredictionsCategory+Resettable.swift in Sources */,
Expand Down
28 changes: 28 additions & 0 deletions Amplify/Core/Support/TimeInterval+Helper.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//
// Copyright 2018-2020 Amazon.com,
// Inc. or its affiliates. All Rights Reserved.
//
// SPDX-License-Identifier: Apache-2.0
//

import Foundation

extension TimeInterval {

public static func seconds(_ value: Double) -> TimeInterval {
return value
}

public static func minutes(_ value: Double) -> TimeInterval {
return value * 60
}

public static func hours(_ value: Double) -> TimeInterval {
return value * 60 * 60
}

public static func days(_ value: Double) -> TimeInterval {
return value * 60 * 60 * 24
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ final public class AWSDataStorePlugin: DataStoreCategoryPlugin {

let modelRegistration: AmplifyModelRegistration

/// The DataStore configuration
let configuration: DataStoreConfiguration

/// The local storage provider. Resolved during configuration phase
var storageEngine: StorageEngineBehavior!

Expand All @@ -38,8 +41,9 @@ final public class AWSDataStorePlugin: DataStoreCategoryPlugin {
}

/// No-argument init that uses defaults for all providers
public init(modelRegistration: AmplifyModelRegistration) {
public init(modelRegistration: AmplifyModelRegistration, configuration: DataStoreConfiguration = .default) {
self.modelRegistration = modelRegistration
self.configuration = configuration
self.isSyncEnabled = false
if #available(iOS 13.0, *) {
self.dataStorePublisher = DataStorePublisher()
Expand All @@ -50,9 +54,11 @@ final public class AWSDataStorePlugin: DataStoreCategoryPlugin {

/// Internal initializer for testing
init(modelRegistration: AmplifyModelRegistration,
configuration: DataStoreConfiguration = .default,
storageEngine: StorageEngineBehavior,
dataStorePublisher: DataStoreSubscribeBehavior) {
self.modelRegistration = modelRegistration
self.configuration = configuration
self.isSyncEnabled = false
self.storageEngine = storageEngine
self.dataStorePublisher = dataStorePublisher
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
//
// Copyright 2018-2020 Amazon.com,
// Inc. or its affiliates. All Rights Reserved.
//
// SPDX-License-Identifier: Apache-2.0
//

import Amplify
import Foundation

/// Error Handler function typealias
public typealias DataStoreErrorHandler = (AmplifyError) -> Void

/// Holds a reference to both the local `Model` and the remote one during a conflict
/// resolution. Implementations of the `DataStoreConflictHandler` use this to decide
/// what the outcome of a conflict should be.
public struct DataStoreConclictData {
public let local: Model
public let remote: Model
}

/// Conflict Handler function typealias. The function is used during a conflict that
/// could not be resolved and requires a decision from the consumer.
public typealias DataStoreConflictHandler = (DataStoreConclictData, DataStoreConflictHandlerResolver) -> Void

/// Callback for the `DataStoreConflictHandler`.
public typealias DataStoreConflictHandlerResolver = (DataStoreConflictHandlerResult) -> Void

/// The conflict resolution result enum.
public enum DataStoreConflictHandlerResult {

/// Discard the local changes in favor of the remote ones.
case discard

/// Keep the local changes (semantic shortcut to `retry(local)`).
case keep

/// Return a new `Model` instance that should used instead of the local and remote changes.
case retry(Model)
}

/// The `DataStore` plugin configuration object.
public struct DataStoreConfiguration {

/// A callback function called on unhandled errors
public let errorHandler: DataStoreErrorHandler

/// A callback called when a conflict could not be resolved by the service
public let conflictHandler: DataStoreConflictHandler

/// How often the sync engine will run (in seconds)
public let syncInterval: TimeInterval

/// The number of records to sync per execution
public let syncMaxRecords: UInt

/// The page size of each sync execution
public let syncPageSize: UInt

init(errorHandler: @escaping DataStoreErrorHandler,
conflictHandler: @escaping DataStoreConflictHandler,
syncInterval: TimeInterval,
syncMaxRecords: UInt,
syncPageSize: UInt) {
self.errorHandler = errorHandler
self.conflictHandler = conflictHandler
self.syncInterval = syncInterval
self.syncMaxRecords = syncMaxRecords
self.syncPageSize = syncPageSize
}

}

extension DataStoreConfiguration {

public static let defaultSyncInterval: TimeInterval = .hours(24)
public static let defaultSyncMaxRecords: UInt = 10_000
public static let defaultSyncPageSize: UInt = 1_000

/// Creates a custom configuration. The only required property is `conflictHandler`.
///
/// - Parameters:
/// - errorHandler: a callback function called on unhandled errors
/// - conflictHandler: a callback called when a conflict could not be resolved by the service
/// - syncInterval: how often the sync engine will run (in seconds)
/// - syncMaxRecords: the number of records to sync per execution
/// - syncPageSize: the page size of each sync execution
/// - Returns: an instance of `DataStoreConfiguration` with the passed parameters.
public static func custom(
errorHandler: @escaping DataStoreErrorHandler = { error in
Amplify.Logging.error(error: error)
},
conflictHandler: @escaping DataStoreConflictHandler = { _, resolve in
resolve(.discard)
},
syncInterval: TimeInterval = DataStoreConfiguration.defaultSyncInterval,
syncMaxRecords: UInt = DataStoreConfiguration.defaultSyncMaxRecords,
syncPageSize: UInt = DataStoreConfiguration.defaultSyncPageSize
) -> DataStoreConfiguration {
return DataStoreConfiguration(errorHandler: errorHandler,
conflictHandler: conflictHandler,
syncInterval: syncInterval,
syncMaxRecords: syncMaxRecords,
syncPageSize: syncPageSize)
}

/// The default configuration.
public static var `default`: DataStoreConfiguration {
.custom()
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ extension APICategoryDependencyTests {

let dataStorePublisher = DataStorePublisher()
let dataStorePlugin = AWSDataStorePlugin(modelRegistration: TestModelRegistration(),
storageEngine: storageEngine,
dataStorePublisher: dataStorePublisher)
storageEngine: storageEngine,
dataStorePublisher: dataStorePublisher)
try Amplify.add(plugin: dataStorePlugin)

let dataStoreConfig = DataStoreCategoryConfiguration(plugins: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ class LocalSubscriptionTests: XCTestCase {

let dataStorePublisher = DataStorePublisher()
let dataStorePlugin = AWSDataStorePlugin(modelRegistration: TestModelRegistration(),
storageEngine: storageEngine,
dataStorePublisher: dataStorePublisher)
storageEngine: storageEngine,
dataStorePublisher: dataStorePublisher)

let dataStoreConfig = DataStoreCategoryConfiguration(plugins: [
"awsDataStorePlugin": true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ class AWSMutationEventIngesterTests: XCTestCase {

let publisher = DataStorePublisher()
let dataStorePlugin = AWSDataStorePlugin(modelRegistration: TestModelRegistration(),
storageEngine: storageEngine,
dataStorePublisher: publisher)
storageEngine: storageEngine,
dataStorePublisher: publisher)

try Amplify.add(plugin: apiPlugin)
try Amplify.add(plugin: dataStorePlugin)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ class RemoteSyncAPIInvocationTests: XCTestCase {

let dataStorePublisher = DataStorePublisher()
let dataStorePlugin = AWSDataStorePlugin(modelRegistration: TestModelRegistration(),
storageEngine: storageEngine,
dataStorePublisher: dataStorePublisher)
storageEngine: storageEngine,
dataStorePublisher: dataStorePublisher)

let apiConfig = APICategoryConfiguration(plugins: [apiPlugin.key: true])
let dataStoreConfig = DataStoreCategoryConfiguration(plugins: [dataStorePlugin.key: true])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ class ModelReconciliationDeleteTests: SyncEngineTestBase {
let syncReceivedNotification = expectation(description: "Received 'syncReceived' update from Hub")
let syncReceivedToken = Amplify.Hub.listen(to: .dataStore,
eventName: HubPayload.EventName.DataStore.syncReceived) { _ in
syncReceivedNotification.fulfill()
syncReceivedNotification.fulfill()
}
guard try HubListenerTestUtilities.waitForListener(with: syncReceivedToken, timeout: 5.0) else {
XCTFail("Sync listener never registered")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
9BDB42C47E6D7F9A113AE558 /* Pods_HostApp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9C6448DF009E54C11ACE4515 /* Pods_HostApp.framework */; };
B912D1B824296F1E0028F05C /* QueryPaginationInput+SQLite.swift in Sources */ = {isa = PBXBuildFile; fileRef = B912D1B724296F1E0028F05C /* QueryPaginationInput+SQLite.swift */; };
B912D1BA242984D10028F05C /* QueryPaginationInputTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B912D1B9242984D10028F05C /* QueryPaginationInputTests.swift */; };
B9334BA22433AF3E00C9F407 /* DataStoreConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9334BA12433AF3E00C9F407 /* DataStoreConfiguration.swift */; };
B996FC4723FF3C7C006D0F68 /* ExampleWithEveryType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B996FC4623FF3C7C006D0F68 /* ExampleWithEveryType.swift */; };
B996FC4923FF3E92006D0F68 /* ExampleWithEveryType+Schema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B996FC4823FF3E92006D0F68 /* ExampleWithEveryType+Schema.swift */; };
B996FC4B23FF418C006D0F68 /* SQLModelValueConverterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B996FC4A23FF418C006D0F68 /* SQLModelValueConverterTests.swift */; };
Expand Down Expand Up @@ -256,6 +257,7 @@
AA98AF8502498A6DD04B5B9D /* Pods-HostApp.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HostApp.release.xcconfig"; path = "Target Support Files/Pods-HostApp/Pods-HostApp.release.xcconfig"; sourceTree = "<group>"; };
B912D1B724296F1E0028F05C /* QueryPaginationInput+SQLite.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "QueryPaginationInput+SQLite.swift"; sourceTree = "<group>"; };
B912D1B9242984D10028F05C /* QueryPaginationInputTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QueryPaginationInputTests.swift; sourceTree = "<group>"; };
B9334BA12433AF3E00C9F407 /* DataStoreConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataStoreConfiguration.swift; sourceTree = "<group>"; };
B996FC4623FF3C7C006D0F68 /* ExampleWithEveryType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExampleWithEveryType.swift; sourceTree = "<group>"; };
B996FC4823FF3E92006D0F68 /* ExampleWithEveryType+Schema.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ExampleWithEveryType+Schema.swift"; sourceTree = "<group>"; };
B996FC4A23FF418C006D0F68 /* SQLModelValueConverterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SQLModelValueConverterTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -402,11 +404,12 @@
2149E5A62388684F00873955 /* AWSDataStoreCategoryPlugin */ = {
isa = PBXGroup;
children = (
2149E5C32388684F00873955 /* Info.plist */,
2149E5C42388684F00873955 /* AWSDataStorePlugin.swift */,
FACBB2AD238AFAE800C29602 /* AWSDataStorePlugin+DataStoreBaseBehavior.swift */,
FA5D4CEE238AFCBC00D2F54A /* AWSDataStorePlugin+DataStoreSubscribeBehavior.swift */,
FA5D4CEC238AFC4D00D2F54A /* AWSDataStorePlugin+DefaultLogger.swift */,
B9334BA12433AF3E00C9F407 /* DataStoreConfiguration.swift */,
2149E5C32388684F00873955 /* Info.plist */,
2149E5A72388684F00873955 /* Storage */,
2149E5B82388684F00873955 /* Subscribe */,
2149E5BA2388684F00873955 /* Sync */,
Expand Down Expand Up @@ -779,14 +782,14 @@
isa = PBXGroup;
children = (
B9E010E3239167E000DCE8C8 /* TestModelRegistration.swift */,
6B64027823E3584300001FD7 /* MockAWSIncomingEventReconciliationQueue.swift */,
6BDC224123E27324007C8410 /* MockAWSInitialSyncOrchestrator.swift */,
6B64027A23E38B9900001FD7 /* MockOutgoingMutationQueue.swift */,
FAF5287A2399814F0053A717 /* MockReconciliationQueue.swift */,
6BC4FDA923A899680027D20C /* MockRequestRetryablePolicy.swift */,
6B4E3DF52397327E00AD962B /* MockStateMachine.swift */,
FA8D932E239EA5C4001ED336 /* NoOpInitialSyncOrchestrator.swift */,
FA23345B23955CEF009BEFE9 /* NoOpMutationQueue.swift */,
6BC4FDA923A899680027D20C /* MockRequestRetryablePolicy.swift */,
6BDC224123E27324007C8410 /* MockAWSInitialSyncOrchestrator.swift */,
6B64027823E3584300001FD7 /* MockAWSIncomingEventReconciliationQueue.swift */,
6B64027A23E38B9900001FD7 /* MockOutgoingMutationQueue.swift */,
);
path = Mocks;
sourceTree = "<group>";
Expand Down Expand Up @@ -1271,6 +1274,7 @@
2149E5C72388684F00873955 /* StorageEngine.swift in Sources */,
FA3B3F05238F22F5002EFDB3 /* OutgoingMutationQueue+Action.swift in Sources */,
FAED573E238B4C2F008EBED8 /* StorageEngineAdapter+UntypedModel.swift in Sources */,
B9334BA22433AF3E00C9F407 /* DataStoreConfiguration.swift in Sources */,
FA4A9559239ACC1B008E876E /* IncomingSubscriptionEventPublisher.swift in Sources */,
FA8F4D222395B11700861D91 /* MutationEvent+Query.swift in Sources */,
FAF7CECB238C72830095547B /* OutgoingMutationQueue.swift in Sources */,
Expand Down
Loading