README update

This commit is contained in:
John Estropia
2019-10-21 21:15:46 +09:00
parent f5fed063ee
commit 145edd5a7d
15 changed files with 129 additions and 520 deletions

View File

@@ -248,142 +248,6 @@ extension DataStack {
}
}
/**
Asynchronously adds a `CloudStorage` to the stack. Migrations are also initiated by default.
```
guard let storage = ICloudStore(
ubiquitousContentName: "MyAppCloudData",
ubiquitousContentTransactionLogsSubdirectory: "logs/config1",
ubiquitousContainerID: "iCloud.com.mycompany.myapp.containername",
ubiquitousPeerToken: "9614d658014f4151a95d8048fb717cf0",
configuration: "Config1",
cloudStorageOptions: .recreateLocalStoreOnModelMismatch
) else {
// iCloud is not available on the device
return
}
dataStack.addStorage(
storage,
completion: { result in
switch result {
case .success(let storage): // ...
case .failure(let error): // ...
}
}
)
```
- parameter storage: the cloud storage
- parameter completion: the closure to be executed on the main queue when the process completes, either due to success or failure. The closure's `SetupResult` argument indicates the result. Note that the `CloudStorage` associated to the `SetupResult.success` may not always be the same instance as the parameter argument if a previous `CloudStorage` was already added at the same URL and with the same configuration.
*/
public func addStorage<T: CloudStorage>(_ storage: T, completion: @escaping (SetupResult<T>) -> Void) {
let cacheFileURL = storage.cacheFileURL
self.coordinator.performSynchronously {
if let _ = self.persistentStoreForStorage(storage) {
DispatchQueue.main.async {
completion(.success(storage))
}
return
}
if let persistentStore = self.coordinator.persistentStore(for: cacheFileURL as URL) {
if let existingStorage = persistentStore.storageInterface as? T,
storage.matchesPersistentStore(persistentStore) {
DispatchQueue.main.async {
completion(.success(existingStorage))
}
return
}
let error = CoreStoreError.differentStorageExistsAtURL(existingPersistentStoreURL: cacheFileURL)
Internals.log(
error,
"Failed to add \(Internals.typeName(storage)) at \"\(cacheFileURL)\" because a different \(Internals.typeName(NSPersistentStore.self)) at that URL already exists."
)
DispatchQueue.main.async {
completion(.failure(error))
}
return
}
do {
var cloudStorageOptions = storage.cloudStorageOptions
cloudStorageOptions.remove(.recreateLocalStoreOnModelMismatch)
let storeOptions = storage.dictionary(forOptions: cloudStorageOptions)
do {
_ = try self.createPersistentStoreFromStorage(
storage,
finalURL: cacheFileURL,
finalStoreOptions: storeOptions
)
DispatchQueue.main.async {
completion(.success(storage))
}
}
catch let error as NSError where storage.cloudStorageOptions.contains(.recreateLocalStoreOnModelMismatch) && error.isCoreDataMigrationError {
let finalStoreOptions = storage.dictionary(forOptions: storage.cloudStorageOptions)
let metadata = try NSPersistentStoreCoordinator.metadataForPersistentStore(
ofType: type(of: storage).storeType,
at: cacheFileURL,
options: storeOptions
)
_ = try self.schemaHistory
.schema(for: metadata)
.flatMap({ try storage.cs_eraseStorageAndWait(soureModel: $0.rawModel()) })
_ = try self.createPersistentStoreFromStorage(
storage,
finalURL: cacheFileURL,
finalStoreOptions: finalStoreOptions
)
}
}
catch let error as NSError
where error.code == NSFileReadNoSuchFileError && error.domain == NSCocoaErrorDomain {
do {
_ = try self.addStorageAndWait(storage)
DispatchQueue.main.async {
completion(.success(storage))
}
}
catch {
DispatchQueue.main.async {
completion(.failure(CoreStoreError(error)))
}
}
}
catch {
let storeError = CoreStoreError(error)
Internals.log(
storeError,
"Failed to load \(Internals.typeName(NSPersistentStore.self)) metadata."
)
DispatchQueue.main.async {
completion(.failure(storeError))
}
}
}
}
/**
Migrates a local storage to match the `DataStack`'s managed object model version. This method does NOT add the migrated store to the data stack.