Skip to content
Closed
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
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,14 @@ extension DataStoreCategory: DataStoreBaseBehavior {
plugin.delete(modelType, withId: id, completion: completion)
}

public func start(completion: @escaping DataStoreCallback<Void>) {
plugin.start(completion: completion)
}

public func stop(completion: @escaping DataStoreCallback<Void>) {
plugin.stop(completion: completion)
}

public func clear(completion: @escaping DataStoreCallback<Void>) {
plugin.clear(completion: completion)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ public protocol DataStoreBaseBehavior {
withId id: String,
completion: @escaping DataStoreCallback<Void>)

func start(completion: @escaping DataStoreCallback<Void>)

func stop(completion: @escaping DataStoreCallback<Void>)

func clear(completion: @escaping DataStoreCallback<Void>)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,24 @@ extension AWSDataStorePlugin: DataStoreBaseBehavior {
predicate: predicate,
completion: onCompletion)
}
public func start(completion: @escaping DataStoreCallback<Void>) {
reinitStorageEngineIfNeeded(completion: completion)
}

public func stop(completion: @escaping DataStoreCallback<Void>) {
if storageEngine == nil {
completion(.successfulVoid)
return
}
storageEngine.stopSync { result in
self.storageEngine = nil
if #available(iOS 13.0, *) {
self.dataStorePublisher?.sendFinished()
}
self.dataStorePublisher = nil
completion(result)
}
}

public func clear(completion: @escaping DataStoreCallback<Void>) {
if storageEngine == nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ final public class AWSDataStorePlugin: DataStoreCategoryPlugin {

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

var iStorageEngineSink: Any?
@available(iOS 13.0, *)
Expand All @@ -52,7 +53,8 @@ final public class AWSDataStorePlugin: DataStoreCategoryPlugin {
self.isSyncEnabled = false
self.validAPIPluginKey = "awsAPIPlugin"
self.validAuthPluginKey = "awsCognitoAuthPlugin"

self.storageEngineBehaviorFactory =
StorageEngine.init(isSyncEnabled:dataStoreConfiguration:validAPIPluginKey:validAuthPluginKey:modelRegistryVersion:userDefault:)
if #available(iOS 13.0, *) {
self.dataStorePublisher = DataStorePublisher()
} else {
Expand All @@ -64,13 +66,16 @@ final public class AWSDataStorePlugin: DataStoreCategoryPlugin {
init(modelRegistration: AmplifyModelRegistration,
configuration dataStoreConfiguration: DataStoreConfiguration = .default,
storageEngine: StorageEngineBehavior,
storageEngineBehaviorFactory: StorageEngineBehaviorFactory? = nil,
dataStorePublisher: ModelSubcriptionBehavior,
validAPIPluginKey: String,
validAuthPluginKey: String) {
self.modelRegistration = modelRegistration
self.dataStoreConfiguration = dataStoreConfiguration
self.isSyncEnabled = false
self.storageEngine = storageEngine
self.storageEngineBehaviorFactory = storageEngineBehaviorFactory ??
StorageEngine.init(isSyncEnabled:dataStoreConfiguration:validAPIPluginKey:validAuthPluginKey:modelRegistryVersion:userDefault:)
self.dataStorePublisher = dataStorePublisher
self.validAPIPluginKey = validAPIPluginKey
self.validAuthPluginKey = validAuthPluginKey
Expand All @@ -84,45 +89,46 @@ final public class AWSDataStorePlugin: DataStoreCategoryPlugin {
resolveSyncEnabled()

try resolveStorageEngine(dataStoreConfiguration: dataStoreConfiguration)

try storageEngine.setUp(modelSchemas: ModelRegistry.modelSchemas)
}

let filter = HubFilters.forEventName(HubPayload.EventName.Amplify.configured)
var token: UnsubscribeToken?
token = Amplify.Hub.listen(to: .dataStore, isIncluded: filter) { _ in
self.storageEngine.startSync()
if let token = token {
Amplify.Hub.removeListener(token)
}
func reinitStorageEngineIfNeeded(completion: @escaping DataStoreCallback<Void> = {_ in}) {
if storageEngine == nil {
reinitStorageEngine(completion: completion)
} else {
startSyncEngine(completion: completion)
}
}

func reinitStorageEngineIfNeeded() {
if storageEngine != nil {
return
}
func reinitStorageEngine(completion: @escaping DataStoreCallback<Void>) {
do {
if #available(iOS 13.0, *) {
self.dataStorePublisher = DataStorePublisher()
}
try resolveStorageEngine(dataStoreConfiguration: dataStoreConfiguration)
try storageEngine.setUp(modelSchemas: ModelRegistry.modelSchemas)
storageEngine.startSync()
startSyncEngine(completion: completion)
} catch {
log.error(error: error)
}
}

func startSyncEngine(completion: @escaping DataStoreCallback<Void>) {
storageEngine.startSync(completion: completion)
}

func resolveStorageEngine(dataStoreConfiguration: DataStoreConfiguration) throws {
guard storageEngine == nil else {
return
}

storageEngine = try StorageEngine(isSyncEnabled: isSyncEnabled,
dataStoreConfiguration: dataStoreConfiguration,
validAPIPluginKey: validAPIPluginKey,
validAuthPluginKey: validAuthPluginKey,
modelRegistryVersion: modelRegistration.version)
storageEngine = try storageEngineBehaviorFactory(isSyncEnabled,
dataStoreConfiguration,
validAPIPluginKey,
validAuthPluginKey,
modelRegistration.version,
UserDefaults.standard)

if #available(iOS 13.0, *) {
setupStorageSink()
}
Expand Down Expand Up @@ -184,4 +190,3 @@ final public class AWSDataStorePlugin: DataStoreCategoryPlugin {
}

}

Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,38 @@ import AWSPluginsCore

extension StorageEngine {

func startSync() {
guard let api = tryGetAPIPlugin() else {
log.info("Unable to find suitable API plugin for syncEngine. syncEngine will not be started")
return
}
func startSync(completion: @escaping DataStoreCallback<Void>) {
syncEngineStartSerialQueue.async {
guard let api = self.tryGetAPIPlugin() else {
self.log.info("Unable to find suitable API plugin for syncEngine. syncEngine will not be started")
completion(.failure(.configuration("Unable to find suitable API plugin for syncEngine. syncEngine will not be started",
"Ensure the API category has been setup and configured for your project", nil)))
return
}

let authPluginRequired = requiresAuthPlugin(api: api)
let authPluginRequired = self.requiresAuthPlugin(api: api)

guard authPluginRequired else {
syncEngine?.start(api: api, auth: nil)
return
}
guard authPluginRequired else {
if !self.syncEngineCalledStart {
self.syncEngineCalledStart = true
self.syncEngine?.start(api: api, auth: nil)
}
completion(.successfulVoid)
return
}

guard let auth = tryGetAuthPlugin() else {
log.warn("Unable to find suitable Auth plugin for syncEngine. Models require auth")
return
guard let auth = self.tryGetAuthPlugin() else {
self.log.warn("Unable to find suitable Auth plugin for syncEngine. Models require auth")
completion(.failure(.configuration("Unable to find suitable Auth plugin for syncEngine. Models require auth",
"Ensure the Auth category has been setup and configured for your project", nil)))
return
}
if !self.syncEngineCalledStart {
self.syncEngineCalledStart = true
self.syncEngine?.start(api: api, auth: auth)
}
completion(.successfulVoid)
}

syncEngine?.start(api: api, auth: auth)
}

private func tryGetAPIPlugin() -> APICategoryGraphQLBehavior? {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,23 @@ import Combine
import Foundation
import AWSPluginsCore

typealias StorageEngineBehaviorFactory =
(Bool,
DataStoreConfiguration,
String,
String,
String,
UserDefaults) throws -> StorageEngineBehavior

// swiftlint:disable type_body_length
final class StorageEngine: StorageEngineBehavior {

// TODO: Make this private once we get a mutation flow that passes the type of mutation as needed
let storageAdapter: StorageEngineAdapter
private let dataStoreConfiguration: DataStoreConfiguration
var syncEngine: RemoteSyncEngineBehavior?
var syncEngineCalledStart: Bool
let syncEngineStartSerialQueue: DispatchQueue
let validAPIPluginKey: String
let validAuthPluginKey: String
var signInListener: UnsubscribeToken?
Expand Down Expand Up @@ -75,6 +85,8 @@ final class StorageEngine: StorageEngineBehavior {
self.syncEngine = syncEngine
self.validAPIPluginKey = validAPIPluginKey
self.validAuthPluginKey = validAuthPluginKey
self.syncEngineCalledStart = false
self.syncEngineStartSerialQueue = DispatchQueue(label: "com.amazonaws.DataStore.StorageEngineStartSerialQueue")
}

convenience init(isSyncEnabled: Bool,
Expand Down Expand Up @@ -386,6 +398,16 @@ final class StorageEngine: StorageEngineBehavior {
}
}

func stopSync(completion: @escaping DataStoreCallback<Void>) {
if let syncEngine = syncEngine {
syncEngine.stop { _ in
completion(.successfulVoid)
}
} else {
completion(.successfulVoid)
}
}

func reset(onComplete: () -> Void) {
// TOOD: Perform cleanup on StorageAdapter, including releasing its `Connection` if needed
let group = DispatchGroup()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ protocol StorageEngineBehavior: class, ModelStorageBehavior {
var publisher: AnyPublisher<StorageEngineEvent, DataStoreError> { get }

/// start remote sync, based on if sync is enabled and/or authentication is required
func startSync()

func startSync(completion: @escaping DataStoreCallback<Void>)
func stopSync(completion: @escaping DataStoreCallback<Void>)
func clear(completion: @escaping DataStoreCallback<Void>)
}
Loading