WIP: segfault

This commit is contained in:
John Rommel Estropia
2016-07-20 08:12:04 +09:00
parent f486ace437
commit 267c21063a
129 changed files with 2205 additions and 3282 deletions

View File

@@ -53,7 +53,7 @@ public extension CoreStore {
/**
Returns the `NSEntityDescription` for the specified `NSManagedObject` subclass from `defaultStack`'s model.
*/
public static func entityDescriptionForType(type: NSManagedObject.Type) -> NSEntityDescription? {
public static func entityDescriptionForType(_ type: NSManagedObject.Type) -> NSEntityDescription? {
return self.defaultStack.entityDescriptionForType(type)
}
@@ -66,22 +66,24 @@ public extension CoreStore {
- returns: the local SQLite storage added to the `defaultStack`
*/
@discardableResult
public static func addStorageAndWait() throws -> SQLiteStore {
return try self.defaultStack.addStorageAndWait(SQLiteStore)
return try self.defaultStack.addStorageAndWait(SQLiteStore.self)
}
/**
Creates a `StorageInterface` of the specified store type with default values and adds it to the `defaultStack`. This method blocks until completion.
```
try CoreStore.addStorageAndWait(InMemoryStore)
try CoreStore.addStorageAndWait(InMemoryStore.self)
```
- parameter storeType: the `StorageInterface` type
- throws: a `CoreStoreError` value indicating the failure
- returns: the `StorageInterface` added to the `defaultStack`
*/
public static func addStorageAndWait<T: StorageInterface where T: DefaultInitializableStore>(storeType: T.Type) throws -> T {
@discardableResult
public static func addStorageAndWait<T: StorageInterface where T: DefaultInitializableStore>(_ storeType: T.Type) throws -> T {
return try self.defaultStack.addStorageAndWait(storeType.init())
}
@@ -96,7 +98,7 @@ public extension CoreStore {
- throws: a `CoreStoreError` value indicating the failure
- returns: the `StorageInterface` added to the `defaultStack`
*/
public static func addStorageAndWait<T: StorageInterface>(storage: T) throws -> T {
public static func addStorageAndWait<T: StorageInterface>(_ storage: T) throws -> T {
return try self.defaultStack.addStorageAndWait(storage)
}
@@ -104,14 +106,14 @@ public extension CoreStore {
/**
Creates a `LocalStorageface` of the specified store type with default values and adds it to the `defaultStack`. This method blocks until completion.
```
try CoreStore.addStorageAndWait(SQLiteStore)
try CoreStore.addStorageAndWait(SQLiteStore.self)
```
- parameter storeType: the `LocalStorageface` type
- throws: a `CoreStoreError` value indicating the failure
- returns: the local storage added to the `defaultStack`
*/
public static func addStorageAndWait<T: LocalStorage where T: DefaultInitializableStore>(storageType: T.Type) throws -> T {
public static func addStorageAndWait<T: LocalStorage where T: DefaultInitializableStore>(_ storageType: T.Type) throws -> T {
return try self.defaultStack.addStorageAndWait(storageType.init())
}
@@ -126,7 +128,7 @@ public extension CoreStore {
- throws: a `CoreStoreError` value indicating the failure
- returns: the local storage added to the `defaultStack`. Note that this may not always be the same instance as the parameter argument if a previous `LocalStorage` was already added at the same URL and with the same configuration.
*/
public static func addStorageAndWait<T: LocalStorage>(storage: T) throws -> T {
public static func addStorageAndWait<T: LocalStorage>(_ storage: T) throws -> T {
return try self.defaultStack.addStorageAndWait(storage)
}
@@ -140,7 +142,7 @@ public extension CoreStore {
ubiquitousContainerID: "iCloud.com.mycompany.myapp.containername",
ubiquitousPeerToken: "9614d658014f4151a95d8048fb717cf0",
configuration: "Config1",
cloudStorageOptions: .RecreateLocalStoreOnModelMismatch
cloudStorageOptions: .recreateLocalStoreOnModelMismatch
) else {
// iCloud is not available on the device
return
@@ -152,69 +154,8 @@ public extension CoreStore {
- throws: a `CoreStoreError` value indicating the failure
- returns: the cloud storage added to the stack. Note that this 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 static func addStorageAndWait<T: CloudStorage>(storage: T) throws -> T {
public static func addStorageAndWait<T: CloudStorage>(_ storage: T) throws -> T {
return try self.defaultStack.addStorageAndWait(storage)
}
// MARK: Deprecated
/**
Deprecated. Use `addStorageAndWait(_:)` by passing a `InMemoryStore` instance.
```
try CoreStore.addStorage(InMemoryStore(configuration: configuration))
```
*/
@available(*, deprecated=2.0.0, obsoleted=2.0.0, message="Use addStorageAndWait(_:) by passing an InMemoryStore instance.")
public static func addInMemoryStoreAndWait(configuration configuration: String? = nil) throws -> NSPersistentStore {
return try self.defaultStack.addInMemoryStoreAndWait(configuration: configuration)
}
/**
Deprecated. Use `addStorageAndWait(_:)` by passing a `LegacySQLiteStore` instance.
```
try CoreStore.addStorage(
LegacySQLiteStore(
fileName: fileName,
configuration: configuration,
localStorageOptions: .RecreateStoreOnModelMismatch
)
)
```
- Warning: The default SQLite file location for the `LegacySQLiteStore` and `SQLiteStore` are different. If the app was using this method prior to 2.0.0, make sure to use `LegacySQLiteStore`.
*/
@available(*, deprecated=2.0.0, message="Use addStorageAndWait(_:) by passing a LegacySQLiteStore instance. Warning: The default SQLite file location for the LegacySQLiteStore and SQLiteStore are different. If the app was using this method prior to 2.0.0, make sure to use LegacySQLiteStore.")
public static func addSQLiteStoreAndWait(fileName fileName: String, configuration: String? = nil, resetStoreOnModelMismatch: Bool = false) throws -> NSPersistentStore {
return try self.defaultStack.addSQLiteStoreAndWait(
fileName: fileName,
configuration: configuration,
resetStoreOnModelMismatch: resetStoreOnModelMismatch
)
}
/**
Deprecated. Use `addStorageAndWait(_:)` by passing a `LegacySQLiteStore` instance.
```
try CoreStore.addStorage(
LegacySQLiteStore(
fileURL: fileURL,
configuration: configuration,
localStorageOptions: .RecreateStoreOnModelMismatch
)
)
```
- Warning: The default SQLite file location for the `LegacySQLiteStore` and `SQLiteStore` are different. If the app was using this method prior to 2.0.0, make sure to use `LegacySQLiteStore`.
*/
@available(*, deprecated=2.0.0, message="Use addStorageAndWait(_:) by passing a LegacySQLiteStore instance. Warning: The default SQLite file location for the LegacySQLiteStore and SQLiteStore are different. If the app was using this method prior to 2.0.0, make sure to use LegacySQLiteStore.")
public static func addSQLiteStoreAndWait(fileURL fileURL: NSURL = LegacySQLiteStore.defaultFileURL, configuration: String? = nil, resetStoreOnModelMismatch: Bool = false) throws -> NSPersistentStore {
return try self.defaultStack.addSQLiteStoreAndWait(
fileURL: fileURL,
configuration: configuration,
resetStoreOnModelMismatch: resetStoreOnModelMismatch
)
}
}

View File

@@ -44,7 +44,7 @@ public final class DataStack {
- parameter bundle: an optional bundle to load models from. If not specified, the main bundle will be used.
- parameter migrationChain: the `MigrationChain` that indicates the sequence of model versions to be used as the order for progressive migrations. If not specified, will default to a non-migrating data stack.
*/
public convenience init(modelName: String = DataStack.applicationName, bundle: NSBundle = NSBundle.mainBundle(), migrationChain: MigrationChain = nil) {
public convenience init(modelName: String = DataStack.applicationName, bundle: Bundle = Bundle.main, migrationChain: MigrationChain = nil) {
let model = NSManagedObjectModel.fromBundle(
bundle,
@@ -64,7 +64,7 @@ public final class DataStack {
CoreStore.assert(
migrationChain.valid,
"Invalid migration chain passed to the \(cs_typeName(DataStack)). Check that the model versions' order is correct and that no repetitions or ambiguities exist."
"Invalid migration chain passed to the \(cs_typeName(DataStack.self)). Check that the model versions' order is correct and that no repetitions or ambiguities exist."
)
self.coordinator = NSPersistentStoreCoordinator(managedObjectModel: model)
@@ -95,20 +95,20 @@ public final class DataStack {
/**
Returns the `NSEntityDescription` for the specified `NSManagedObject` subclass.
*/
public func entityDescriptionForType(type: NSManagedObject.Type) -> NSEntityDescription? {
public func entityDescriptionForType(_ type: NSManagedObject.Type) -> NSEntityDescription? {
return NSEntityDescription.entityForName(
self.model.entityNameForClass(type),
inManagedObjectContext: self.mainContext
return NSEntityDescription.entity(
forEntityName: self.model.entityNameForClass(type),
in: self.mainContext
)
}
/**
Returns the `NSManagedObjectID` for the specified object URI if it exists in the persistent store.
*/
public func objectIDForURIRepresentation(url: NSURL) -> NSManagedObjectID? {
public func objectIDForURIRepresentation(_ url: URL) -> NSManagedObjectID? {
return self.coordinator.managedObjectIDForURIRepresentation(url)
return self.coordinator.managedObjectID(forURIRepresentation: url)
}
/**
@@ -122,20 +122,20 @@ public final class DataStack {
*/
public func addStorageAndWait() throws -> SQLiteStore {
return try self.addStorageAndWait(SQLiteStore)
return try self.addStorageAndWait(SQLiteStore.self)
}
/**
Creates a `StorageInterface` of the specified store type with default values and adds it to the stack. This method blocks until completion.
```
try dataStack.addStorageAndWait(InMemoryStore)
try dataStack.addStorageAndWait(InMemoryStore.self)
```
- parameter storeType: the `StorageInterface` type
- throws: a `CoreStoreError` value indicating the failure
- returns: the `StorageInterface` added to the stack
*/
public func addStorageAndWait<T: StorageInterface where T: DefaultInitializableStore>(storeType: T.Type) throws -> T {
public func addStorageAndWait<T: StorageInterface where T: DefaultInitializableStore>(_ storeType: T.Type) throws -> T {
return try self.addStorageAndWait(storeType.init())
}
@@ -150,7 +150,7 @@ public final class DataStack {
- throws: a `CoreStoreError` value indicating the failure
- returns: the `StorageInterface` added to the stack
*/
public func addStorageAndWait<T: StorageInterface>(storage: T) throws -> T {
public func addStorageAndWait<T: StorageInterface>(_ storage: T) throws -> T {
do {
@@ -160,8 +160,7 @@ public final class DataStack {
return storage
}
try self.createPersistentStoreFromStorage(
_ = try self.createPersistentStoreFromStorage(
storage,
finalURL: nil,
finalStoreOptions: storage.storeOptions
@@ -183,14 +182,14 @@ public final class DataStack {
/**
Creates a `LocalStorageface` of the specified store type with default values and adds it to the stack. This method blocks until completion.
```
try dataStack.addStorageAndWait(SQLiteStore)
try dataStack.addStorageAndWait(SQLiteStore.self)
```
- parameter storeType: the `LocalStorageface` type
- throws: a `CoreStoreError` value indicating the failure
- returns: the local storage added to the stack
*/
public func addStorageAndWait<T: LocalStorage where T: DefaultInitializableStore>(storageType: T.Type) throws -> T {
public func addStorageAndWait<T: LocalStorage where T: DefaultInitializableStore>(_ storageType: T.Type) throws -> T {
return try self.addStorageAndWait(storageType.init())
}
@@ -205,13 +204,13 @@ public final class DataStack {
- throws: a `CoreStoreError` value indicating the failure
- returns: the local storage added to the stack. Note that this may not always be the same instance as the parameter argument if a previous `LocalStorage` was already added at the same URL and with the same configuration.
*/
public func addStorageAndWait<T: LocalStorage>(storage: T) throws -> T {
public func addStorageAndWait<T: LocalStorage>(_ storage: T) throws -> T {
return try self.coordinator.performSynchronously {
let fileURL = storage.fileURL
CoreStore.assert(
fileURL.fileURL,
fileURL.isFileURL,
"The specified store URL for the \"\(cs_typeName(storage))\" is invalid: \"\(fileURL)\""
)
@@ -220,7 +219,7 @@ public final class DataStack {
return storage
}
if let persistentStore = self.coordinator.persistentStoreForURL(fileURL) {
if let persistentStore = self.coordinator.persistentStore(for: fileURL as URL) {
if let existingStorage = persistentStore.storageInterface as? T
where storage.matchesPersistentStore(persistentStore) {
@@ -228,10 +227,10 @@ public final class DataStack {
return existingStorage
}
let error = CoreStoreError.DifferentStorageExistsAtURL(existingPersistentStoreURL: fileURL)
let error = CoreStoreError.differentStorageExistsAtURL(existingPersistentStoreURL: fileURL)
CoreStore.log(
error,
"Failed to add \(cs_typeName(storage)) at \"\(fileURL)\" because a different \(cs_typeName(NSPersistentStore)) at that URL already exists."
"Failed to add \(cs_typeName(storage)) at \"\(fileURL)\" because a different \(cs_typeName(NSPersistentStore.self)) at that URL already exists."
)
throw error
}
@@ -239,33 +238,32 @@ public final class DataStack {
do {
var localStorageOptions = storage.localStorageOptions
localStorageOptions.remove(.RecreateStoreOnModelMismatch)
localStorageOptions.remove(.recreateStoreOnModelMismatch)
let storeOptions = storage.storeOptionsForOptions(localStorageOptions)
do {
try NSFileManager.defaultManager().createDirectoryAtURL(
fileURL.URLByDeletingLastPathComponent!,
try FileManager.default.createDirectory(
at: try fileURL.deletingLastPathComponent(),
withIntermediateDirectories: true,
attributes: nil
)
try self.createPersistentStoreFromStorage(
_ = try self.createPersistentStoreFromStorage(
storage,
finalURL: fileURL,
finalStoreOptions: storeOptions
)
return storage
}
catch let error as NSError where storage.localStorageOptions.contains(.RecreateStoreOnModelMismatch) && error.isCoreDataMigrationError {
catch let error as NSError where storage.localStorageOptions.contains(.recreateStoreOnModelMismatch) && error.isCoreDataMigrationError {
let metadata = try NSPersistentStoreCoordinator.metadataForPersistentStoreOfType(
storage.dynamicType.storeType,
URL: fileURL,
let metadata = try NSPersistentStoreCoordinator.metadataForPersistentStore(
ofType: storage.dynamicType.storeType,
at: fileURL,
options: storeOptions
)
try _ = self.model[metadata].flatMap(storage.eraseStorageAndWait)
try self.createPersistentStoreFromStorage(
_ = try self.model[metadata].flatMap(storage.eraseStorageAndWait)
_ = try self.createPersistentStoreFromStorage(
storage,
finalURL: fileURL,
finalStoreOptions: storeOptions
@@ -294,7 +292,7 @@ public final class DataStack {
ubiquitousContainerID: "iCloud.com.mycompany.myapp.containername",
ubiquitousPeerToken: "9614d658014f4151a95d8048fb717cf0",
configuration: "Config1",
cloudStorageOptions: .RecreateLocalStoreOnModelMismatch
cloudStorageOptions: .recreateLocalStoreOnModelMismatch
) else {
// iCloud is not available on the device
return
@@ -306,7 +304,7 @@ public final class DataStack {
- throws: a `CoreStoreError` value indicating the failure
- returns: the cloud storage added to the stack. Note that this 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 addStorageAndWait<T: CloudStorage>(storage: T) throws -> T {
public func addStorageAndWait<T: CloudStorage>(_ storage: T) throws -> T {
return try self.coordinator.performSynchronously {
@@ -316,7 +314,7 @@ public final class DataStack {
}
let cacheFileURL = storage.cacheFileURL
if let persistentStore = self.coordinator.persistentStoreForURL(cacheFileURL) {
if let persistentStore = self.coordinator.persistentStore(for: cacheFileURL as URL) {
if let existingStorage = persistentStore.storageInterface as? T
where storage.matchesPersistentStore(persistentStore) {
@@ -324,10 +322,10 @@ public final class DataStack {
return existingStorage
}
let error = CoreStoreError.DifferentStorageExistsAtURL(existingPersistentStoreURL: cacheFileURL)
let error = CoreStoreError.differentStorageExistsAtURL(existingPersistentStoreURL: cacheFileURL)
CoreStore.log(
error,
"Failed to add \(cs_typeName(storage)) at \"\(cacheFileURL)\" because a different \(cs_typeName(NSPersistentStore)) at that URL already exists."
"Failed to add \(cs_typeName(storage)) at \"\(cacheFileURL)\" because a different \(cs_typeName(NSPersistentStore.self)) at that URL already exists."
)
throw error
}
@@ -335,33 +333,32 @@ public final class DataStack {
do {
var cloudStorageOptions = storage.cloudStorageOptions
cloudStorageOptions.remove(.RecreateLocalStoreOnModelMismatch)
cloudStorageOptions.remove(.recreateLocalStoreOnModelMismatch)
let storeOptions = storage.storeOptionsForOptions(cloudStorageOptions)
do {
try NSFileManager.defaultManager().createDirectoryAtURL(
cacheFileURL.URLByDeletingLastPathComponent!,
try FileManager.default.createDirectory(
at: try cacheFileURL.deletingLastPathComponent(),
withIntermediateDirectories: true,
attributes: nil
)
try self.createPersistentStoreFromStorage(
_ = try self.createPersistentStoreFromStorage(
storage,
finalURL: cacheFileURL,
finalStoreOptions: storeOptions
)
return storage
}
catch let error as NSError where storage.cloudStorageOptions.contains(.RecreateLocalStoreOnModelMismatch) && error.isCoreDataMigrationError {
catch let error as NSError where storage.cloudStorageOptions.contains(.recreateLocalStoreOnModelMismatch) && error.isCoreDataMigrationError {
let metadata = try NSPersistentStoreCoordinator.metadataForPersistentStoreOfType(
storage.dynamicType.storeType,
URL: cacheFileURL,
let metadata = try NSPersistentStoreCoordinator.metadataForPersistentStore(
ofType: storage.dynamicType.storeType,
at: cacheFileURL,
options: storeOptions
)
try _ = self.model[metadata].flatMap(storage.eraseStorageAndWait)
try self.createPersistentStoreFromStorage(
_ = try self.model[metadata].flatMap(storage.eraseStorageAndWait)
_ = try self.createPersistentStoreFromStorage(
storage,
finalURL: cacheFileURL,
finalStoreOptions: storeOptions
@@ -384,7 +381,7 @@ public final class DataStack {
// MARK: Internal
internal static let applicationName = (NSBundle.mainBundle().objectForInfoDictionaryKey("CFBundleName") as? String) ?? "CoreData"
internal static let applicationName = (Bundle.main.objectForInfoDictionaryKey("CFBundleName") as? String) ?? "CoreData"
internal let coordinator: NSPersistentStoreCoordinator
internal let rootSavingContext: NSManagedObjectContext
@@ -393,39 +390,32 @@ public final class DataStack {
internal let migrationChain: MigrationChain
internal let childTransactionQueue: GCDQueue = .createSerial("com.coreStore.dataStack.childTransactionQueue")
internal let storeMetadataUpdateQueue = GCDQueue.createConcurrent("com.coreStore.persistentStoreBarrierQueue")
internal let migrationQueue: NSOperationQueue = {
internal let migrationQueue: OperationQueue = {
let migrationQueue = NSOperationQueue()
let migrationQueue = OperationQueue()
migrationQueue.maxConcurrentOperationCount = 1
migrationQueue.name = "com.coreStore.migrationOperationQueue"
#if USE_FRAMEWORKS
migrationQueue.qualityOfService = .Utility
migrationQueue.underlyingQueue = dispatch_queue_create("com.coreStore.migrationQueue", DISPATCH_QUEUE_SERIAL)
#else
if #available(iOS 8.0, *) {
migrationQueue.qualityOfService = .Utility
migrationQueue.underlyingQueue = dispatch_queue_create("com.coreStore.migrationQueue", DISPATCH_QUEUE_SERIAL)
}
#endif
migrationQueue.qualityOfService = .utility
migrationQueue.underlyingQueue = DispatchQueue(
label: "com.coreStore.migrationQueue",
attributes: .serial
)
return migrationQueue
}()
internal func persistentStoreForStorage(storage: StorageInterface) -> NSPersistentStore? {
internal func persistentStoreForStorage(_ storage: StorageInterface) -> NSPersistentStore? {
return self.coordinator.persistentStores
.filter { $0.storageInterface === storage }
.first
}
internal func entityNameForEntityClass(entityClass: AnyClass) -> String? {
internal func entityNameForEntityClass(_ entityClass: AnyClass) -> String? {
return self.model.entityNameForClass(entityClass)
}
internal func persistentStoresForEntityClass(entityClass: AnyClass) -> [NSPersistentStore]? {
internal func persistentStoresForEntityClass(_ entityClass: AnyClass) -> [NSPersistentStore]? {
var returnValue: [NSPersistentStore]? = nil
self.storeMetadataUpdateQueue.barrierSync {
@@ -438,7 +428,7 @@ public final class DataStack {
return returnValue
}
internal func persistentStoreForEntityClass(entityClass: AnyClass, configuration: String?, inferStoreIfPossible: Bool) -> (store: NSPersistentStore?, isAmbiguous: Bool) {
internal func persistentStoreForEntityClass(_ entityClass: AnyClass, configuration: String?, inferStoreIfPossible: Bool) -> (store: NSPersistentStore?, isAmbiguous: Bool) {
var returnValue: (store: NSPersistentStore?, isAmbiguous: Bool) = (store: nil, isAmbiguous: false)
self.storeMetadataUpdateQueue.barrierSync {
@@ -472,12 +462,12 @@ public final class DataStack {
return returnValue
}
internal func createPersistentStoreFromStorage(storage: StorageInterface, finalURL: NSURL?, finalStoreOptions: [String: AnyObject]?) throws -> NSPersistentStore {
internal func createPersistentStoreFromStorage(_ storage: StorageInterface, finalURL: URL?, finalStoreOptions: [String: AnyObject]?) throws -> NSPersistentStore {
let persistentStore = try self.coordinator.addPersistentStoreWithType(
storage.dynamicType.storeType,
configuration: storage.configuration,
URL: finalURL,
let persistentStore = try self.coordinator.addPersistentStore(
ofType: storage.dynamicType.storeType,
configurationName: storage.configuration,
at: finalURL,
options: finalStoreOptions
)
persistentStore.storageInterface = storage
@@ -486,9 +476,9 @@ public final class DataStack {
let configurationName = persistentStore.configurationName
self.configurationStoreMapping[configurationName] = persistentStore
for entityDescription in (self.coordinator.managedObjectModel.entitiesForConfiguration(configurationName) ?? []) {
for entityDescription in (self.coordinator.managedObjectModel.entities(forConfigurationName: configurationName) ?? []) {
let managedObjectClassName = entityDescription.managedObjectClassName
let managedObjectClassName = entityDescription.managedObjectClassName!
CoreStore.assert(
NSClassFromString(managedObjectClassName) != nil,
"The class \(cs_typeName(managedObjectClassName)) for the entity \(cs_typeName(entityDescription.name)) does not exist. Check if the subclass type and module name are properly configured."
@@ -520,79 +510,11 @@ public final class DataStack {
coordinator.persistentStores.forEach {
_ = try? coordinator.removePersistentStore($0)
_ = try? coordinator.remove($0)
}
}
}
}
// MARK: Deprecated
/**
Deprecated. Use `addStorageAndWait(_:)` by passing a `InMemoryStore` instance.
```
try dataStack.addStorage(InMemoryStore(configuration: configuration))
```
*/
@available(*, deprecated=2.0.0, message="Use addStorageAndWait(_:) by passing an InMemoryStore instance.")
public func addInMemoryStoreAndWait(configuration configuration: String? = nil) throws -> NSPersistentStore {
let storage = try self.addStorageAndWait(InMemoryStore(configuration: configuration))
return self.persistentStoreForStorage(storage)!
}
/**
Deprecated. Use `addStorageAndWait(_:)` by passing a `LegacySQLiteStore` instance.
```
try dataStack.addStorage(
LegacySQLiteStore(
fileName: fileName,
configuration: configuration,
localStorageOptions: .RecreateStoreOnModelMismatch
)
)
```
- Warning: The default SQLite file location for the `LegacySQLiteStore` and `SQLiteStore` are different. If the app was using this method prior to 2.0.0, make sure to use `LegacySQLiteStore`.
*/
@available(*, deprecated=2.0.0, message="Use addStorageAndWait(_:) by passing a LegacySQLiteStore instance. Warning: The default SQLite file location for the LegacySQLiteStore and SQLiteStore are different. If the app was using this method prior to 2.0.0, make sure to use LegacySQLiteStore.")
public func addSQLiteStoreAndWait(fileName fileName: String, configuration: String? = nil, resetStoreOnModelMismatch: Bool = false) throws -> NSPersistentStore {
let storage = try self.addStorageAndWait(
LegacySQLiteStore(
fileName: fileName,
configuration: configuration,
localStorageOptions: resetStoreOnModelMismatch ? .RecreateStoreOnModelMismatch : .None
)
)
return self.persistentStoreForStorage(storage)!
}
/**
Deprecated. Use `addStorageAndWait(_:)` by passing a `LegacySQLiteStore` instance.
```
try dataStack.addStorage(
LegacySQLiteStore(
fileURL: fileURL,
configuration: configuration,
localStorageOptions: .RecreateStoreOnModelMismatch
)
)
```
- Warning: The default SQLite file location for the `LegacySQLiteStore` and `SQLiteStore` are different. If the app was using this method prior to 2.0.0, make sure to use `LegacySQLiteStore`.
*/
@available(*, deprecated=2.0.0, message="Use addStorageAndWait(_:) by passing a LegacySQLiteStore instance. Warning: The default SQLite file location for the LegacySQLiteStore and SQLiteStore are different. If the app was using this method prior to 2.0.0, make sure to use LegacySQLiteStore.")
public func addSQLiteStoreAndWait(fileURL fileURL: NSURL = LegacySQLiteStore.defaultFileURL, configuration: String? = nil, resetStoreOnModelMismatch: Bool = false) throws -> NSPersistentStore {
let storage = try self.addStorageAndWait(
LegacySQLiteStore(
fileURL: fileURL,
configuration: configuration,
localStorageOptions: resetStoreOnModelMismatch ? .RecreateStoreOnModelMismatch : .None
)
)
return self.persistentStoreForStorage(storage)!
}
}

View File

@@ -45,7 +45,7 @@ public class ICloudStore: CloudStorage {
ubiquitousContainerID: "iCloud.com.mycompany.myapp.containername",
ubiquitousPeerToken: "9614d658014f4151a95d8048fb717cf0",
configuration: "Config1",
cloudStorageOptions: .RecreateLocalStoreOnModelMismatch
cloudStorageOptions: .recreateLocalStoreOnModelMismatch
) else {
// iCloud is not available on the device
return
@@ -73,7 +73,7 @@ public class ICloudStore: CloudStorage {
"The ubiquitousContentName cannot be empty."
)
CoreStore.assert(
!ubiquitousContentName.containsString("."),
!ubiquitousContentName.contains("."),
"The ubiquitousContentName cannot contain periods."
)
CoreStore.assert(
@@ -85,8 +85,8 @@ public class ICloudStore: CloudStorage {
"The ubiquitousPeerToken should not be empty if provided."
)
let fileManager = NSFileManager.defaultManager()
guard let cacheFileURL = fileManager.URLForUbiquityContainerIdentifier(ubiquitousContainerID) else {
let fileManager = FileManager.default
guard let cacheFileURL = fileManager.urlForUbiquityContainerIdentifier(ubiquitousContainerID) else {
return nil
}
@@ -110,10 +110,10 @@ public class ICloudStore: CloudStorage {
- parameter observer: the observer to start sending ubiquitous notifications to
*/
public func addObserver<T: ICloudStoreObserver>(observer: T) {
public func addObserver<T: ICloudStoreObserver>(_ observer: T) {
CoreStore.assert(
NSThread.isMainThread(),
Thread.isMainThread,
"Attempted to add an observer of type \(cs_typeName(observer)) outside the main thread."
)
@@ -198,10 +198,10 @@ public class ICloudStore: CloudStorage {
- parameter observer: the observer to stop sending ubiquitous notifications to
*/
public func removeObserver(observer: ICloudStoreObserver) {
public func removeObserver(_ observer: ICloudStoreObserver) {
CoreStore.assert(
NSThread.isMainThread(),
Thread.isMainThread,
"Attempted to remove an observer of type \(cs_typeName(observer)) outside the main thread."
)
let nilValue: AnyObject? = nil
@@ -271,7 +271,7 @@ public class ICloudStore: CloudStorage {
/**
Do not call directly. Used by the `DataStack` internally.
*/
public func didAddToDataStack(dataStack: DataStack) {
public func didAddToDataStack(_ dataStack: DataStack) {
self.didRemoveFromDataStack(dataStack)
@@ -280,38 +280,38 @@ public class ICloudStore: CloudStorage {
cs_setAssociatedRetainedObject(
NotificationObserver(
notificationName: NSPersistentStoreCoordinatorStoresWillChangeNotification,
notificationName: NSNotification.Name.NSPersistentStoreCoordinatorStoresWillChange.rawValue,
object: coordinator,
closure: { [weak self, weak dataStack] (note) -> Void in
guard let `self` = self,
let dataStack = dataStack,
let userInfo = note.userInfo,
let userInfo = (note as NSNotification).userInfo,
let transitionType = userInfo[NSPersistentStoreUbiquitousTransitionTypeKey] as? NSNumber else {
return
}
let notification: String
switch NSPersistentStoreUbiquitousTransitionType(rawValue: transitionType.unsignedIntegerValue) {
switch NSPersistentStoreUbiquitousTransitionType(rawValue: transitionType.uintValue) {
case .InitialImportCompleted?:
case .initialImportCompleted?:
notification = ICloudUbiquitousStoreWillFinishInitialImportNotification
case .AccountAdded?:
case .accountAdded?:
notification = ICloudUbiquitousStoreWillAddAccountNotification
case .AccountRemoved?:
case .accountRemoved?:
notification = ICloudUbiquitousStoreWillRemoveAccountNotification
case .ContentRemoved?:
case .contentRemoved?:
notification = ICloudUbiquitousStoreWillRemoveContentNotification
default:
return
}
NSNotificationCenter.defaultCenter().postNotificationName(
notification,
NotificationCenter.default.post(
name: Notification.Name(rawValue: notification),
object: self,
userInfo: [UserInfoKeyDataStack: dataStack]
)
@@ -322,38 +322,38 @@ public class ICloudStore: CloudStorage {
)
cs_setAssociatedRetainedObject(
NotificationObserver(
notificationName: NSPersistentStoreCoordinatorStoresDidChangeNotification,
notificationName: NSNotification.Name.NSPersistentStoreCoordinatorStoresDidChange.rawValue,
object: coordinator,
closure: { [weak self, weak dataStack] (note) -> Void in
guard let `self` = self,
let dataStack = dataStack,
let userInfo = note.userInfo,
let userInfo = (note as NSNotification).userInfo,
let transitionType = userInfo[NSPersistentStoreUbiquitousTransitionTypeKey] as? NSNumber else {
return
}
let notification: String
switch NSPersistentStoreUbiquitousTransitionType(rawValue: transitionType.unsignedIntegerValue) {
switch NSPersistentStoreUbiquitousTransitionType(rawValue: transitionType.uintValue) {
case .InitialImportCompleted?:
case .initialImportCompleted?:
notification = ICloudUbiquitousStoreDidFinishInitialImportNotification
case .AccountAdded?:
case .accountAdded?:
notification = ICloudUbiquitousStoreDidAddAccountNotification
case .AccountRemoved?:
case .accountRemoved?:
notification = ICloudUbiquitousStoreDidRemoveAccountNotification
case .ContentRemoved?:
case .contentRemoved?:
notification = ICloudUbiquitousStoreDidRemoveContentNotification
default:
return
}
NSNotificationCenter.defaultCenter().postNotificationName(
notification,
NotificationCenter.default.post(
name: Notification.Name(rawValue: notification),
object: self,
userInfo: [UserInfoKeyDataStack: dataStack]
)
@@ -367,7 +367,7 @@ public class ICloudStore: CloudStorage {
/**
Do not call directly. Used by the `DataStack` internally.
*/
public func didRemoveFromDataStack(dataStack: DataStack) {
public func didRemoveFromDataStack(_ dataStack: DataStack) {
let coordinator = dataStack.coordinator
let nilValue: AnyObject? = nil
@@ -391,7 +391,7 @@ public class ICloudStore: CloudStorage {
/**
The `NSURL` that points to the ubiquity container file
*/
public let cacheFileURL: NSURL
public let cacheFileURL: URL
/**
Options that tell the `DataStack` how to setup the persistent store
@@ -401,20 +401,20 @@ public class ICloudStore: CloudStorage {
/**
The options dictionary for the specified `CloudStorageOptions`
*/
public func storeOptionsForOptions(options: CloudStorageOptions) -> [String: AnyObject]? {
public func storeOptionsForOptions(_ options: CloudStorageOptions) -> [String: AnyObject]? {
if options == .None {
if options == .none {
return self.storeOptions
}
var storeOptions = self.storeOptions ?? [:]
if options.contains(.AllowSynchronousLightweightMigration) {
if options.contains(.allowSynchronousLightweightMigration) {
storeOptions[NSMigratePersistentStoresAutomaticallyOption] = true
storeOptions[NSInferMappingModelAutomaticallyOption] = true
}
if options.contains(.RecreateLocalStoreOnModelMismatch) {
if options.contains(.recreateLocalStoreOnModelMismatch) {
storeOptions[NSPersistentStoreRebuildFromUbiquitousContentOption] = true
}
@@ -424,7 +424,7 @@ public class ICloudStore: CloudStorage {
/**
Called by the `DataStack` to perform actual deletion of the store file from disk. Do not call directly! The `sourceModel` argument is a hint for the existing store's model version. For `SQLiteStore`, this converts the database's WAL journaling mode to DELETE before deleting the file.
*/
public func eraseStorageAndWait(soureModel soureModel: NSManagedObjectModel) throws {
public func eraseStorageAndWait(soureModel: NSManagedObjectModel) throws {
// TODO: check if attached to persistent store
@@ -436,18 +436,18 @@ public class ICloudStore: CloudStorage {
NSSQLitePragmasOption: ["journal_mode": "DELETE"],
NSPersistentStoreRemoveUbiquitousMetadataOption: true
]
let store = try journalUpdatingCoordinator.addPersistentStoreWithType(
self.dynamicType.storeType,
configuration: self.configuration,
URL: cacheFileURL,
let store = try journalUpdatingCoordinator.addPersistentStore(
ofType: self.dynamicType.storeType,
configurationName: self.configuration,
at: cacheFileURL,
options: options
)
try journalUpdatingCoordinator.removePersistentStore(store)
try NSPersistentStoreCoordinator.removeUbiquitousContentAndPersistentStoreAtURL(
cacheFileURL,
try journalUpdatingCoordinator.remove(store)
try NSPersistentStoreCoordinator.removeUbiquitousContentAndPersistentStore(
at: cacheFileURL,
options: options
)
try NSFileManager.defaultManager().removeItemAtURL(cacheFileURL)
try FileManager.default.removeItem(at: cacheFileURL)
}
}
@@ -471,7 +471,7 @@ public class ICloudStore: CloudStorage {
private weak var dataStack: DataStack?
private func registerNotification<T: ICloudStoreObserver>(notificationKey: UnsafePointer<Void>, name: String, toObserver observer: T, callback: (observer: T, storage: ICloudStore, dataStack: DataStack) -> Void) {
private func registerNotification<T: ICloudStoreObserver>(_ notificationKey: UnsafePointer<Void>, name: String, toObserver observer: T, callback: (observer: T, storage: ICloudStore, dataStack: DataStack) -> Void) {
cs_setAssociatedRetainedObject(
NotificationObserver(
@@ -481,7 +481,7 @@ public class ICloudStore: CloudStorage {
guard let `self` = self,
let observer = observer,
let dataStack = note.userInfo?[UserInfoKeyDataStack] as? DataStack
let dataStack = (note as NSNotification).userInfo?[UserInfoKeyDataStack] as? DataStack
where self.dataStack === dataStack else {
return

View File

@@ -45,7 +45,7 @@ public protocol ICloudStoreObserver: class {
- parameter storage: the `ICloudStore` instance being observed
- parameter dataStack: the `DataStack` that manages the peristent store
*/
func iCloudStoreWillFinishUbiquitousStoreInitialImport(storage storage: ICloudStore, dataStack: DataStack)
func iCloudStoreWillFinishUbiquitousStoreInitialImport(storage: ICloudStore, dataStack: DataStack)
/**
Notifies that the initial ubiquitous store import completed
@@ -53,7 +53,7 @@ public protocol ICloudStoreObserver: class {
- parameter storage: the `ICloudStore` instance being observed
- parameter dataStack: the `DataStack` that manages the peristent store
*/
func iCloudStoreDidFinishUbiquitousStoreInitialImport(storage storage: ICloudStore, dataStack: DataStack)
func iCloudStoreDidFinishUbiquitousStoreInitialImport(storage: ICloudStore, dataStack: DataStack)
/**
Notifies that an iCloud account will be added to the coordinator
@@ -61,7 +61,7 @@ public protocol ICloudStoreObserver: class {
- parameter storage: the `ICloudStore` instance being observed
- parameter dataStack: the `DataStack` that manages the peristent store
*/
func iCloudStoreWillAddAccount(storage storage: ICloudStore, dataStack: DataStack)
func iCloudStoreWillAddAccount(storage: ICloudStore, dataStack: DataStack)
/**
Notifies that an iCloud account was added to the coordinator
@@ -69,7 +69,7 @@ public protocol ICloudStoreObserver: class {
- parameter storage: the `ICloudStore` instance being observed
- parameter dataStack: the `DataStack` that manages the peristent store
*/
func iCloudStoreDidAddAccount(storage storage: ICloudStore, dataStack: DataStack)
func iCloudStoreDidAddAccount(storage: ICloudStore, dataStack: DataStack)
/**
Notifies that an iCloud account will be removed from the coordinator
@@ -77,7 +77,7 @@ public protocol ICloudStoreObserver: class {
- parameter storage: the `ICloudStore` instance being observed
- parameter dataStack: the `DataStack` that manages the peristent store
*/
func iCloudStoreWillRemoveAccount(storage storage: ICloudStore, dataStack: DataStack)
func iCloudStoreWillRemoveAccount(storage: ICloudStore, dataStack: DataStack)
/**
Notifies that an iCloud account was removed from the coordinator
@@ -85,7 +85,7 @@ public protocol ICloudStoreObserver: class {
- parameter storage: the `ICloudStore` instance being observed
- parameter dataStack: the `DataStack` that manages the peristent store
*/
func iCloudStoreDidRemoveAccount(storage storage: ICloudStore, dataStack: DataStack)
func iCloudStoreDidRemoveAccount(storage: ICloudStore, dataStack: DataStack)
/**
Notifies that iCloud contents will be deleted
@@ -93,7 +93,7 @@ public protocol ICloudStoreObserver: class {
- parameter storage: the `ICloudStore` instance being observed
- parameter dataStack: the `DataStack` that manages the peristent store
*/
func iCloudStoreWillRemoveContent(storage storage: ICloudStore, dataStack: DataStack)
func iCloudStoreWillRemoveContent(storage: ICloudStore, dataStack: DataStack)
/**
Notifies that iCloud contents were deleted
@@ -101,26 +101,26 @@ public protocol ICloudStoreObserver: class {
- parameter storage: the `ICloudStore` instance being observed
- parameter dataStack: the `DataStack` that manages the peristent store
*/
func iCloudStoreDidRemoveContent(storage storage: ICloudStore, dataStack: DataStack)
func iCloudStoreDidRemoveContent(storage: ICloudStore, dataStack: DataStack)
}
public extension ICloudStoreObserver {
public func iCloudStoreWillFinishUbiquitousStoreInitialImport(storage storage: ICloudStore, dataStack: DataStack) {}
public func iCloudStoreWillFinishUbiquitousStoreInitialImport(storage: ICloudStore, dataStack: DataStack) {}
public func iCloudStoreDidFinishUbiquitousStoreInitialImport(storage storage: ICloudStore, dataStack: DataStack) {}
public func iCloudStoreDidFinishUbiquitousStoreInitialImport(storage: ICloudStore, dataStack: DataStack) {}
public func iCloudStoreWillAddAccount(storage storage: ICloudStore, dataStack: DataStack) {}
public func iCloudStoreWillAddAccount(storage: ICloudStore, dataStack: DataStack) {}
public func iCloudStoreDidAddAccount(storage storage: ICloudStore, dataStack: DataStack) {}
public func iCloudStoreDidAddAccount(storage: ICloudStore, dataStack: DataStack) {}
public func iCloudStoreWillRemoveAccount(storage storage: ICloudStore, dataStack: DataStack) {}
public func iCloudStoreWillRemoveAccount(storage: ICloudStore, dataStack: DataStack) {}
public func iCloudStoreDidRemoveAccount(storage storage: ICloudStore, dataStack: DataStack) {}
public func iCloudStoreDidRemoveAccount(storage: ICloudStore, dataStack: DataStack) {}
public func iCloudStoreWillRemoveContent(storage storage: ICloudStore, dataStack: DataStack) {}
public func iCloudStoreWillRemoveContent(storage: ICloudStore, dataStack: DataStack) {}
public func iCloudStoreDidRemoveContent(storage storage: ICloudStore, dataStack: DataStack) {}
public func iCloudStoreDidRemoveContent(storage: ICloudStore, dataStack: DataStack) {}
}
#endif

View File

@@ -74,7 +74,7 @@ public final class InMemoryStore: StorageInterface, DefaultInitializableStore {
/**
Do not call directly. Used by the `DataStack` internally.
*/
public func didAddToDataStack(dataStack: DataStack) {
public func didAddToDataStack(_ dataStack: DataStack) {
self.dataStack = dataStack
}
@@ -82,7 +82,7 @@ public final class InMemoryStore: StorageInterface, DefaultInitializableStore {
/**
Do not call directly. Used by the `DataStack` internally.
*/
public func didRemoveFromDataStack(dataStack: DataStack) {
public func didRemoveFromDataStack(_ dataStack: DataStack) {
self.dataStack = nil
}

View File

@@ -44,7 +44,7 @@ public final class LegacySQLiteStore: LocalStorage, DefaultInitializableStore {
- parameter mappingModelBundles: a list of `NSBundle`s from which to search mapping models for migration.
- parameter localStorageOptions: When the `SQLiteStore` is passed to the `DataStack`'s `addStorage()` methods, tells the `DataStack` how to setup the persistent store. Defaults to `.None`.
*/
public init(fileURL: NSURL, configuration: String? = nil, mappingModelBundles: [NSBundle] = NSBundle.allBundles(), localStorageOptions: LocalStorageOptions = nil) {
public init(fileURL: URL, configuration: String? = nil, mappingModelBundles: [Bundle] = Bundle.allBundles, localStorageOptions: LocalStorageOptions = nil) {
self.fileURL = fileURL
self.configuration = configuration
@@ -61,9 +61,9 @@ public final class LegacySQLiteStore: LocalStorage, DefaultInitializableStore {
- parameter mappingModelBundles: a list of `NSBundle`s from which to search mapping models for migration.
- parameter localStorageOptions: When the `SQLiteStore` is passed to the `DataStack`'s `addStorage()` methods, tells the `DataStack` how to setup the persistent store. Defaults to `.None`.
*/
public init(fileName: String, configuration: String? = nil, mappingModelBundles: [NSBundle] = NSBundle.allBundles(), localStorageOptions: LocalStorageOptions = nil) {
public init(fileName: String, configuration: String? = nil, mappingModelBundles: [Bundle] = Bundle.allBundles, localStorageOptions: LocalStorageOptions = nil) {
self.fileURL = LegacySQLiteStore.defaultRootDirectory.URLByAppendingPathComponent(
self.fileURL = try! LegacySQLiteStore.defaultRootDirectory.appendingPathComponent(
fileName,
isDirectory: false
)
@@ -84,7 +84,7 @@ public final class LegacySQLiteStore: LocalStorage, DefaultInitializableStore {
self.fileURL = LegacySQLiteStore.defaultFileURL
self.configuration = nil
self.mappingModelBundles = NSBundle.allBundles()
self.mappingModelBundles = Bundle.allBundles
self.localStorageOptions = nil
}
@@ -99,15 +99,15 @@ public final class LegacySQLiteStore: LocalStorage, DefaultInitializableStore {
/**
The options dictionary for the specified `LocalStorageOptions`
*/
public func storeOptionsForOptions(options: LocalStorageOptions) -> [String: AnyObject]? {
public func storeOptionsForOptions(_ options: LocalStorageOptions) -> [String: AnyObject]? {
if options == .None {
if options == .none {
return self.storeOptions
}
var storeOptions = self.storeOptions ?? [:]
if options.contains(.AllowSynchronousLightweightMigration) {
if options.contains(.allowSynchronousLightweightMigration) {
storeOptions[NSMigratePersistentStoresAutomaticallyOption] = true
storeOptions[NSInferMappingModelAutomaticallyOption] = true
@@ -131,7 +131,7 @@ public final class LegacySQLiteStore: LocalStorage, DefaultInitializableStore {
/**
Do not call directly. Used by the `DataStack` internally.
*/
public func didAddToDataStack(dataStack: DataStack) {
public func didAddToDataStack(_ dataStack: DataStack) {
self.dataStack = dataStack
}
@@ -139,7 +139,7 @@ public final class LegacySQLiteStore: LocalStorage, DefaultInitializableStore {
/**
Do not call directly. Used by the `DataStack` internally.
*/
public func didRemoveFromDataStack(dataStack: DataStack) {
public func didRemoveFromDataStack(_ dataStack: DataStack) {
self.dataStack = nil
}
@@ -150,12 +150,12 @@ public final class LegacySQLiteStore: LocalStorage, DefaultInitializableStore {
/**
The `NSURL` that points to the SQLite file
*/
public let fileURL: NSURL
public let fileURL: URL
/**
The `NSBundle`s from which to search mapping models for migrations
*/
public let mappingModelBundles: [NSBundle]
public let mappingModelBundles: [Bundle]
/**
Options that tell the `DataStack` how to setup the persistent store
@@ -165,7 +165,7 @@ public final class LegacySQLiteStore: LocalStorage, DefaultInitializableStore {
/**
Called by the `DataStack` to perform actual deletion of the store file from disk. Do not call directly! The `sourceModel` argument is a hint for the existing store's model version. For `SQLiteStore`, this converts the database's WAL journaling mode to DELETE before deleting the file.
*/
public func eraseStorageAndWait(soureModel soureModel: NSManagedObjectModel) throws {
public func eraseStorageAndWait(soureModel: NSManagedObjectModel) throws {
// TODO: check if attached to persistent store
@@ -173,37 +173,37 @@ public final class LegacySQLiteStore: LocalStorage, DefaultInitializableStore {
try cs_autoreleasepool {
let journalUpdatingCoordinator = NSPersistentStoreCoordinator(managedObjectModel: soureModel)
let store = try journalUpdatingCoordinator.addPersistentStoreWithType(
self.dynamicType.storeType,
configuration: self.configuration,
URL: fileURL,
let store = try journalUpdatingCoordinator.addPersistentStore(
ofType: self.dynamicType.storeType,
configurationName: self.configuration,
at: fileURL,
options: [NSSQLitePragmasOption: ["journal_mode": "DELETE"]]
)
try journalUpdatingCoordinator.removePersistentStore(store)
try NSFileManager.defaultManager().removeItemAtURL(fileURL)
try journalUpdatingCoordinator.remove(store)
try FileManager.default.removeItem(at: fileURL)
}
}
// MARK: Internal
internal static let defaultRootDirectory: NSURL = {
internal static let defaultRootDirectory: URL = {
#if os(tvOS)
let systemDirectorySearchPath = NSSearchPathDirectory.CachesDirectory
#else
let systemDirectorySearchPath = NSSearchPathDirectory.ApplicationSupportDirectory
let systemDirectorySearchPath = FileManager.SearchPathDirectory.applicationSupportDirectory
#endif
return NSFileManager.defaultManager().URLsForDirectory(
return FileManager.default.urlsForDirectory(
systemDirectorySearchPath,
inDomains: .UserDomainMask
inDomains: .userDomainMask
).first!
}()
internal static let defaultFileURL = LegacySQLiteStore.defaultRootDirectory
.URLByAppendingPathComponent(DataStack.applicationName, isDirectory: false)
.URLByAppendingPathExtension("sqlite")
internal static let defaultFileURL = try! LegacySQLiteStore.defaultRootDirectory
.appendingPathComponent(DataStack.applicationName, isDirectory: false)
.appendingPathExtension("sqlite")
// MARK: Private

View File

@@ -43,7 +43,7 @@ public final class SQLiteStore: LocalStorage, DefaultInitializableStore {
- parameter mappingModelBundles: a list of `NSBundle`s from which to search mapping models (*.xcmappingmodel) for migration.
- parameter localStorageOptions: When the `SQLiteStore` is passed to the `DataStack`'s `addStorage()` methods, tells the `DataStack` how to setup the persistent store. Defaults to `.None`.
*/
public init(fileURL: NSURL, configuration: String? = nil, mappingModelBundles: [NSBundle] = NSBundle.allBundles(), localStorageOptions: LocalStorageOptions = nil) {
public init(fileURL: URL, configuration: String? = nil, mappingModelBundles: [Bundle] = Bundle.allBundles, localStorageOptions: LocalStorageOptions = nil) {
self.fileURL = fileURL
self.configuration = configuration
@@ -60,10 +60,10 @@ public final class SQLiteStore: LocalStorage, DefaultInitializableStore {
- parameter mappingModelBundles: a list of `NSBundle`s from which to search mapping models (*.xcmappingmodel) for migration
- parameter localStorageOptions: When the `SQLiteStore` is passed to the `DataStack`'s `addStorage()` methods, tells the `DataStack` how to setup the persistent store. Defaults to `.None`.
*/
public init(fileName: String, configuration: String? = nil, mappingModelBundles: [NSBundle] = NSBundle.allBundles(), localStorageOptions: LocalStorageOptions = nil) {
public init(fileName: String, configuration: String? = nil, mappingModelBundles: [Bundle] = Bundle.allBundles, localStorageOptions: LocalStorageOptions = nil) {
self.fileURL = SQLiteStore.defaultRootDirectory
.URLByAppendingPathComponent(fileName, isDirectory: false)
self.fileURL = try! SQLiteStore.defaultRootDirectory
.appendingPathComponent(fileName, isDirectory: false)
self.configuration = configuration
self.mappingModelBundles = mappingModelBundles
self.localStorageOptions = localStorageOptions
@@ -81,7 +81,7 @@ public final class SQLiteStore: LocalStorage, DefaultInitializableStore {
self.fileURL = SQLiteStore.defaultFileURL
self.configuration = nil
self.mappingModelBundles = NSBundle.allBundles()
self.mappingModelBundles = Bundle.allBundles
self.localStorageOptions = nil
}
@@ -109,7 +109,7 @@ public final class SQLiteStore: LocalStorage, DefaultInitializableStore {
/**
Do not call directly. Used by the `DataStack` internally.
*/
public func didAddToDataStack(dataStack: DataStack) {
public func didAddToDataStack(_ dataStack: DataStack) {
self.dataStack = dataStack
}
@@ -117,7 +117,7 @@ public final class SQLiteStore: LocalStorage, DefaultInitializableStore {
/**
Do not call directly. Used by the `DataStack` internally.
*/
public func didRemoveFromDataStack(dataStack: DataStack) {
public func didRemoveFromDataStack(_ dataStack: DataStack) {
self.dataStack = nil
}
@@ -128,12 +128,12 @@ public final class SQLiteStore: LocalStorage, DefaultInitializableStore {
/**
The `NSURL` that points to the SQLite file
*/
public let fileURL: NSURL
public let fileURL: URL
/**
The `NSBundle`s from which to search mapping models for migrations
*/
public let mappingModelBundles: [NSBundle]
public let mappingModelBundles: [Bundle]
/**
Options that tell the `DataStack` how to setup the persistent store
@@ -143,15 +143,15 @@ public final class SQLiteStore: LocalStorage, DefaultInitializableStore {
/**
The options dictionary for the specified `LocalStorageOptions`
*/
public func storeOptionsForOptions(options: LocalStorageOptions) -> [String: AnyObject]? {
public func storeOptionsForOptions(_ options: LocalStorageOptions) -> [String: AnyObject]? {
if options == .None {
if options == .none {
return self.storeOptions
}
var storeOptions = self.storeOptions ?? [:]
if options.contains(.AllowSynchronousLightweightMigration) {
if options.contains(.allowSynchronousLightweightMigration) {
storeOptions[NSMigratePersistentStoresAutomaticallyOption] = true
storeOptions[NSInferMappingModelAutomaticallyOption] = true
@@ -162,7 +162,7 @@ public final class SQLiteStore: LocalStorage, DefaultInitializableStore {
/**
Called by the `DataStack` to perform actual deletion of the store file from disk. Do not call directly! The `sourceModel` argument is a hint for the existing store's model version. For `SQLiteStore`, this converts the database's WAL journaling mode to DELETE before deleting the file.
*/
public func eraseStorageAndWait(soureModel soureModel: NSManagedObjectModel) throws {
public func eraseStorageAndWait(soureModel: NSManagedObjectModel) throws {
// TODO: check if attached to persistent store
@@ -170,44 +170,43 @@ public final class SQLiteStore: LocalStorage, DefaultInitializableStore {
try cs_autoreleasepool {
let journalUpdatingCoordinator = NSPersistentStoreCoordinator(managedObjectModel: soureModel)
let store = try journalUpdatingCoordinator.addPersistentStoreWithType(
self.dynamicType.storeType,
configuration: self.configuration,
URL: fileURL,
let store = try journalUpdatingCoordinator.addPersistentStore(
ofType: self.dynamicType.storeType,
configurationName: self.configuration,
at: fileURL,
options: [NSSQLitePragmasOption: ["journal_mode": "DELETE"]]
)
try journalUpdatingCoordinator.removePersistentStore(store)
try NSFileManager.defaultManager().removeItemAtURL(fileURL)
try journalUpdatingCoordinator.remove(store)
try FileManager.default.removeItem(at: fileURL)
}
}
// MARK: Internal
internal static let defaultRootDirectory: NSURL = {
internal static let defaultRootDirectory: URL = {
#if os(tvOS)
let systemDirectorySearchPath = NSSearchPathDirectory.CachesDirectory
#else
let systemDirectorySearchPath = NSSearchPathDirectory.ApplicationSupportDirectory
let systemDirectorySearchPath = FileManager.SearchPathDirectory.applicationSupportDirectory
#endif
let defaultSystemDirectory = NSFileManager
.defaultManager()
.URLsForDirectory(systemDirectorySearchPath, inDomains: .UserDomainMask).first!
let defaultSystemDirectory = FileManager.default
.urlsForDirectory(systemDirectorySearchPath, inDomains: .userDomainMask).first!
return defaultSystemDirectory.URLByAppendingPathComponent(
NSBundle.mainBundle().bundleIdentifier ?? "com.CoreStore.DataStack",
return try! defaultSystemDirectory.appendingPathComponent(
Bundle.main.bundleIdentifier ?? "com.CoreStore.DataStack",
isDirectory: true
)
}()
internal static let defaultFileURL = SQLiteStore.defaultRootDirectory
.URLByAppendingPathComponent(
(NSBundle.mainBundle().objectForInfoDictionaryKey("CFBundleName") as? String) ?? "CoreData",
internal static let defaultFileURL = try! SQLiteStore.defaultRootDirectory
.appendingPathComponent(
(Bundle.main.objectForInfoDictionaryKey("CFBundleName") as? String) ?? "CoreData",
isDirectory: false
)
.URLByAppendingPathExtension("sqlite")
.appendingPathExtension("sqlite")
// MARK: Private

View File

@@ -54,12 +54,12 @@ public protocol StorageInterface: class {
/**
Do not call directly. Used by the `DataStack` internally.
*/
func didAddToDataStack(dataStack: DataStack)
func didAddToDataStack(_ dataStack: DataStack)
/**
Do not call directly. Used by the `DataStack` internally.
*/
func didRemoveFromDataStack(dataStack: DataStack)
func didRemoveFromDataStack(_ dataStack: DataStack)
}
@@ -82,27 +82,27 @@ public protocol DefaultInitializableStore: StorageInterface {
/**
The `LocalStorageOptions` provides settings that tells the `DataStack` how to setup the persistent store for `LocalStorage` implementers.
*/
public struct LocalStorageOptions: OptionSetType, NilLiteralConvertible {
public struct LocalStorageOptions: OptionSet, NilLiteralConvertible {
/**
Tells the `DataStack` that the store should not be migrated or recreated, and should simply fail on model mismatch
*/
public static let None = LocalStorageOptions(rawValue: 0)
public static let none = LocalStorageOptions(rawValue: 0)
/**
Tells the `DataStack` to delete and recreate the store on model mismatch, otherwise exceptions will be thrown on failure instead
*/
public static let RecreateStoreOnModelMismatch = LocalStorageOptions(rawValue: 1 << 0)
public static let recreateStoreOnModelMismatch = LocalStorageOptions(rawValue: 1 << 0)
/**
Tells the `DataStack` to prevent progressive migrations for the store
*/
public static let PreventProgressiveMigration = LocalStorageOptions(rawValue: 1 << 1)
public static let preventProgressiveMigration = LocalStorageOptions(rawValue: 1 << 1)
/**
Tells the `DataStack` to allow lightweight migration for the store when added synchronously
*/
public static let AllowSynchronousLightweightMigration = LocalStorageOptions(rawValue: 1 << 2)
public static let allowSynchronousLightweightMigration = LocalStorageOptions(rawValue: 1 << 2)
@@ -138,12 +138,12 @@ public protocol LocalStorage: StorageInterface {
/**
The `NSURL` that points to the store file
*/
var fileURL: NSURL { get }
var fileURL: URL { get }
/**
The `NSBundle`s from which to search mapping models (*.xcmappingmodel) for migrations
*/
var mappingModelBundles: [NSBundle] { get }
var mappingModelBundles: [Bundle] { get }
/**
Options that tell the `DataStack` how to setup the persistent store
@@ -153,21 +153,21 @@ public protocol LocalStorage: StorageInterface {
/**
The options dictionary for the specified `LocalStorageOptions`
*/
func storeOptionsForOptions(options: LocalStorageOptions) -> [String: AnyObject]?
func storeOptionsForOptions(_ options: LocalStorageOptions) -> [String: AnyObject]?
/**
Called by the `DataStack` to perform actual deletion of the store file from disk. **Do not call directly!** The `sourceModel` argument is a hint for the existing store's model version. Implementers can use the `sourceModel` to perform necessary store operations. (SQLite stores for example, can convert WAL journaling mode to DELETE before deleting)
*/
func eraseStorageAndWait(soureModel soureModel: NSManagedObjectModel) throws
func eraseStorageAndWait(soureModel: NSManagedObjectModel) throws
}
internal extension LocalStorage {
internal func matchesPersistentStore(persistentStore: NSPersistentStore) -> Bool {
internal func matchesPersistentStore(_ persistentStore: NSPersistentStore) -> Bool {
return persistentStore.type == self.dynamicType.storeType
&& persistentStore.configurationName == (self.configuration ?? Into.defaultConfigurationName)
&& persistentStore.URL == self.fileURL
&& persistentStore.url == self.fileURL
}
}
@@ -177,22 +177,22 @@ internal extension LocalStorage {
/**
The `CloudStorageOptions` provides settings that tells the `DataStack` how to setup the persistent store for `LocalStorage` implementers.
*/
public struct CloudStorageOptions: OptionSetType, NilLiteralConvertible {
public struct CloudStorageOptions: OptionSet, NilLiteralConvertible {
/**
Tells the `DataStack` that the store should not be migrated or recreated, and should simply fail on model mismatch
*/
public static let None = CloudStorageOptions(rawValue: 0)
public static let none = CloudStorageOptions(rawValue: 0)
/**
Tells the `DataStack` to delete and recreate the local store from the cloud store on model mismatch, otherwise exceptions will be thrown on failure instead
*/
public static let RecreateLocalStoreOnModelMismatch = CloudStorageOptions(rawValue: 1 << 0)
public static let recreateLocalStoreOnModelMismatch = CloudStorageOptions(rawValue: 1 << 0)
/**
Tells the `DataStack` to allow lightweight migration for the store when added synchronously
*/
public static let AllowSynchronousLightweightMigration = CloudStorageOptions(rawValue: 1 << 2)
public static let allowSynchronousLightweightMigration = CloudStorageOptions(rawValue: 1 << 2)
// MARK: OptionSetType
@@ -227,7 +227,7 @@ public protocol CloudStorage: StorageInterface {
/**
The `NSURL` that points to the store file
*/
var cacheFileURL: NSURL { get }
var cacheFileURL: URL { get }
/**
Options that tell the `DataStack` how to setup the persistent store
@@ -237,24 +237,24 @@ public protocol CloudStorage: StorageInterface {
/**
The options dictionary for the specified `CloudStorageOptions`
*/
func storeOptionsForOptions(options: CloudStorageOptions) -> [String: AnyObject]?
func storeOptionsForOptions(_ options: CloudStorageOptions) -> [String: AnyObject]?
/**
Called by the `DataStack` to perform actual deletion of the store file from disk. **Do not call directly!** The `sourceModel` argument is a hint for the existing store's model version. Implementers can use the `sourceModel` to perform necessary store operations. (Cloud stores for example, can set the NSPersistentStoreRemoveUbiquitousMetadataOption option before deleting)
*/
func eraseStorageAndWait(soureModel soureModel: NSManagedObjectModel) throws
func eraseStorageAndWait(soureModel: NSManagedObjectModel) throws
}
internal extension CloudStorage {
internal func matchesPersistentStore(persistentStore: NSPersistentStore) -> Bool {
internal func matchesPersistentStore(_ persistentStore: NSPersistentStore) -> Bool {
guard persistentStore.type == self.dynamicType.storeType
&& persistentStore.configurationName == (self.configuration ?? Into.defaultConfigurationName) else {
return false
}
guard persistentStore.URL == self.cacheFileURL else {
guard persistentStore.url == self.cacheFileURL else {
return false
}