mirror of
https://github.com/JohnEstropia/CoreStore.git
synced 2026-03-25 02:41:10 +01:00
WIP: segfault
This commit is contained in:
@@ -31,7 +31,18 @@ import CoreData
|
||||
|
||||
// Bugfix for NSFetchRequest messing up memory management for `affectedStores`
|
||||
// http://stackoverflow.com/questions/14396375/nsfetchedresultscontroller-crashes-in-ios-6-if-affectedstores-is-specified
|
||||
internal final class CoreStoreFetchRequest: NSFetchRequest {
|
||||
internal final class CoreStoreFetchRequest<T: NSFetchRequestResult>: NSFetchRequest<NSFetchRequestResult> {
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
@nonobjc
|
||||
internal func dynamicCast<U: NSFetchRequestResult>() -> NSFetchRequest<U> {
|
||||
|
||||
return unsafeBitCast(self, to: NSFetchRequest<U>.self)
|
||||
}
|
||||
|
||||
|
||||
// MARK: NSFetchRequest
|
||||
|
||||
@objc
|
||||
override var affectedStores: [NSPersistentStore]? {
|
||||
|
||||
@@ -31,12 +31,12 @@ import CoreData
|
||||
|
||||
// MARK: - CoreStoreFetchedResultsController
|
||||
|
||||
internal final class CoreStoreFetchedResultsController: NSFetchedResultsController {
|
||||
internal final class CoreStoreFetchedResultsController: NSFetchedResultsController<NSManagedObject> {
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
@nonobjc
|
||||
internal convenience init<T: NSManagedObject>(dataStack: DataStack, fetchRequest: NSFetchRequest, from: From<T>? = nil, sectionBy: SectionBy? = nil, applyFetchClauses: (fetchRequest: NSFetchRequest) -> Void) {
|
||||
internal convenience init<T: NSManagedObject>(dataStack: DataStack, fetchRequest: NSFetchRequest<NSManagedObject>, from: From<T>? = nil, sectionBy: SectionBy? = nil, applyFetchClauses: (fetchRequest: NSFetchRequest<NSManagedObject>) -> Void) {
|
||||
|
||||
self.init(
|
||||
context: dataStack.mainContext,
|
||||
@@ -48,14 +48,14 @@ internal final class CoreStoreFetchedResultsController: NSFetchedResultsControll
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
internal init<T: NSManagedObject>(context: NSManagedObjectContext, fetchRequest: NSFetchRequest, from: From<T>? = nil, sectionBy: SectionBy? = nil, applyFetchClauses: (fetchRequest: NSFetchRequest) -> Void) {
|
||||
internal init<T: NSManagedObject>(context: NSManagedObjectContext, fetchRequest: NSFetchRequest<NSManagedObject>, from: From<T>? = nil, sectionBy: SectionBy? = nil, applyFetchClauses: (fetchRequest: NSFetchRequest<NSManagedObject>) -> Void) {
|
||||
|
||||
_ = from?.applyToFetchRequest(
|
||||
fetchRequest,
|
||||
context: context,
|
||||
applyAffectedStores: false
|
||||
)
|
||||
applyFetchClauses(fetchRequest: fetchRequest)
|
||||
applyFetchClauses(fetchRequest: fetchRequest.cs_dynamicCast())
|
||||
|
||||
if let from = from {
|
||||
|
||||
@@ -68,7 +68,7 @@ internal final class CoreStoreFetchedResultsController: NSFetchedResultsControll
|
||||
|
||||
guard let from = (fetchRequest.entity.flatMap { $0.managedObjectClassName }).flatMap(NSClassFromString).flatMap(From.init) else {
|
||||
|
||||
CoreStore.abort("Attempted to create an \(cs_typeName(NSFetchedResultsController)) without a \(cs_typeName(From)) clause or an \(cs_typeName(NSEntityDescription)).")
|
||||
CoreStore.abort("Attempted to create a \(CoreStoreFetchedResultsController.self) without a \(cs_typeName(From<T>.self)) clause or an \(cs_typeName(NSEntityDescription.self)).")
|
||||
}
|
||||
|
||||
self.reapplyAffectedStores = { fetchRequest, context in
|
||||
@@ -91,13 +91,19 @@ internal final class CoreStoreFetchedResultsController: NSFetchedResultsControll
|
||||
if !self.reapplyAffectedStores(fetchRequest: self.fetchRequest, context: self.managedObjectContext) {
|
||||
|
||||
CoreStore.log(
|
||||
.Warning,
|
||||
message: "Attempted to perform a fetch on an \(cs_typeName(NSFetchedResultsController)) but could not find any persistent store for the entity \(cs_typeName(self.fetchRequest.entityName))"
|
||||
.warning,
|
||||
message: "Attempted to perform a fetch on an \(cs_typeName(self)) but could not find any persistent store for the entity \(cs_typeName(self.fetchRequest.entityName))"
|
||||
)
|
||||
}
|
||||
try self.performFetch()
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
internal func dynamicCast<U: NSFetchRequestResult>() -> NSFetchedResultsController<U> {
|
||||
|
||||
return unsafeBitCast(self, to: NSFetchedResultsController<U>.self)
|
||||
}
|
||||
|
||||
deinit {
|
||||
|
||||
self.delegate = nil
|
||||
@@ -107,7 +113,7 @@ internal final class CoreStoreFetchedResultsController: NSFetchedResultsControll
|
||||
// MARK: Private
|
||||
|
||||
@nonobjc
|
||||
private let reapplyAffectedStores: (fetchRequest: NSFetchRequest, context: NSManagedObjectContext) -> Bool
|
||||
private let reapplyAffectedStores: (fetchRequest: NSFetchRequest<NSManagedObject>, context: NSManagedObjectContext) -> Bool
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -33,21 +33,21 @@ import CoreData
|
||||
|
||||
internal protocol FetchedResultsControllerHandler: class {
|
||||
|
||||
func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?)
|
||||
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChangeObject anObject: AnyObject, atIndexPath indexPath: IndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: IndexPath?)
|
||||
|
||||
func controller(controller: NSFetchedResultsController, didChangeSection sectionInfo: NSFetchedResultsSectionInfo, atIndex sectionIndex: Int, forChangeType type: NSFetchedResultsChangeType)
|
||||
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChangeSection sectionInfo: NSFetchedResultsSectionInfo, atIndex sectionIndex: Int, forChangeType type: NSFetchedResultsChangeType)
|
||||
|
||||
func controllerWillChangeContent(controller: NSFetchedResultsController)
|
||||
func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>)
|
||||
|
||||
func controllerDidChangeContent(controller: NSFetchedResultsController)
|
||||
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>)
|
||||
|
||||
func controller(controller: NSFetchedResultsController, sectionIndexTitleForSectionName sectionName: String?) -> String?
|
||||
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, sectionIndexTitleForSectionName sectionName: String?) -> String?
|
||||
}
|
||||
|
||||
|
||||
// MARK: - FetchedResultsControllerDelegate
|
||||
|
||||
internal final class FetchedResultsControllerDelegate: NSObject, NSFetchedResultsControllerDelegate {
|
||||
internal final class FetchedResultsControllerDelegate<EntityType: NSManagedObject>: NSObject, NSFetchedResultsControllerDelegate {
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
@@ -58,7 +58,7 @@ internal final class FetchedResultsControllerDelegate: NSObject, NSFetchedResult
|
||||
internal weak var handler: FetchedResultsControllerHandler?
|
||||
|
||||
@nonobjc
|
||||
internal weak var fetchedResultsController: NSFetchedResultsController? {
|
||||
internal weak var fetchedResultsController: CoreStoreFetchedResultsController? {
|
||||
|
||||
didSet {
|
||||
|
||||
@@ -76,7 +76,7 @@ internal final class FetchedResultsControllerDelegate: NSObject, NSFetchedResult
|
||||
// MARK: NSFetchedResultsControllerDelegate
|
||||
|
||||
@objc
|
||||
dynamic func controllerWillChangeContent(controller: NSFetchedResultsController) {
|
||||
dynamic func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
|
||||
|
||||
guard self.enabled else {
|
||||
|
||||
@@ -90,7 +90,7 @@ internal final class FetchedResultsControllerDelegate: NSObject, NSFetchedResult
|
||||
}
|
||||
|
||||
@objc
|
||||
dynamic func controllerDidChangeContent(controller: NSFetchedResultsController) {
|
||||
dynamic func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
|
||||
|
||||
guard self.enabled else {
|
||||
|
||||
@@ -101,7 +101,7 @@ internal final class FetchedResultsControllerDelegate: NSObject, NSFetchedResult
|
||||
}
|
||||
|
||||
@objc
|
||||
dynamic func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
|
||||
dynamic func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: AnyObject, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
|
||||
|
||||
guard self.enabled else {
|
||||
|
||||
@@ -123,8 +123,8 @@ internal final class FetchedResultsControllerDelegate: NSObject, NSFetchedResult
|
||||
|
||||
switch actualType {
|
||||
|
||||
case .Update:
|
||||
guard let section = indexPath?.indexAtPosition(0) else {
|
||||
case .update:
|
||||
guard let section = indexPath?[0] else {
|
||||
|
||||
return
|
||||
}
|
||||
@@ -134,7 +134,7 @@ internal final class FetchedResultsControllerDelegate: NSObject, NSFetchedResult
|
||||
return
|
||||
}
|
||||
|
||||
case .Move:
|
||||
case .move:
|
||||
guard let indexPath = indexPath, let newIndexPath = newIndexPath else {
|
||||
|
||||
return
|
||||
@@ -143,25 +143,25 @@ internal final class FetchedResultsControllerDelegate: NSObject, NSFetchedResult
|
||||
|
||||
break
|
||||
}
|
||||
if self.insertedSections.contains(indexPath.indexAtPosition(0)) {
|
||||
if self.insertedSections.contains(indexPath[0]) {
|
||||
|
||||
// Observers that handle the .Move change are advised to delete then reinsert the object instead of just moving. This is especially true when indexPath and newIndexPath are equal. For example, calling tableView.moveRowAtIndexPath(_:toIndexPath) when both indexPaths are the same will crash the tableView.
|
||||
self.handler?.controller(
|
||||
controller,
|
||||
didChangeObject: anObject,
|
||||
atIndexPath: indexPath,
|
||||
forChangeType: .Move,
|
||||
forChangeType: .move,
|
||||
newIndexPath: newIndexPath
|
||||
)
|
||||
return
|
||||
}
|
||||
if self.deletedSections.contains(indexPath.indexAtPosition(0)) {
|
||||
if self.deletedSections.contains(indexPath[0]) {
|
||||
|
||||
self.handler?.controller(
|
||||
controller,
|
||||
didChangeObject: anObject,
|
||||
atIndexPath: nil,
|
||||
forChangeType: .Insert,
|
||||
forChangeType: .insert,
|
||||
newIndexPath: indexPath
|
||||
)
|
||||
return
|
||||
@@ -170,7 +170,7 @@ internal final class FetchedResultsControllerDelegate: NSObject, NSFetchedResult
|
||||
controller,
|
||||
didChangeObject: anObject,
|
||||
atIndexPath: indexPath,
|
||||
forChangeType: .Update,
|
||||
forChangeType: .update,
|
||||
newIndexPath: nil
|
||||
)
|
||||
return
|
||||
@@ -189,7 +189,7 @@ internal final class FetchedResultsControllerDelegate: NSObject, NSFetchedResult
|
||||
}
|
||||
|
||||
@objc
|
||||
dynamic func controller(controller: NSFetchedResultsController, didChangeSection sectionInfo: NSFetchedResultsSectionInfo, atIndex sectionIndex: Int, forChangeType type: NSFetchedResultsChangeType) {
|
||||
dynamic func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange sectionInfo: NSFetchedResultsSectionInfo, atSectionIndex sectionIndex: Int, for type: NSFetchedResultsChangeType) {
|
||||
|
||||
guard self.enabled else {
|
||||
|
||||
@@ -198,8 +198,8 @@ internal final class FetchedResultsControllerDelegate: NSObject, NSFetchedResult
|
||||
|
||||
switch type {
|
||||
|
||||
case .Delete: self.deletedSections.insert(sectionIndex)
|
||||
case .Insert: self.insertedSections.insert(sectionIndex)
|
||||
case .delete: self.deletedSections.insert(sectionIndex)
|
||||
case .insert: self.insertedSections.insert(sectionIndex)
|
||||
default: break
|
||||
}
|
||||
|
||||
@@ -212,7 +212,7 @@ internal final class FetchedResultsControllerDelegate: NSObject, NSFetchedResult
|
||||
}
|
||||
|
||||
@objc
|
||||
dynamic func controller(controller: NSFetchedResultsController, sectionIndexTitleForSectionName sectionName: String) -> String? {
|
||||
dynamic func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, sectionIndexTitleForSectionName sectionName: String) -> String? {
|
||||
|
||||
return self.handler?.controller(
|
||||
controller,
|
||||
|
||||
@@ -28,12 +28,12 @@ import Foundation
|
||||
|
||||
// MARK: - Custom AutoreleasePool
|
||||
|
||||
internal func cs_autoreleasepool(@noescape closure: () -> Void) {
|
||||
internal func cs_autoreleasepool(@noescape _ closure: () -> Void) {
|
||||
|
||||
autoreleasepool(closure)
|
||||
}
|
||||
|
||||
internal func cs_autoreleasepool<T>(@noescape closure: () -> T) -> T {
|
||||
internal func cs_autoreleasepool<T>(@noescape _ closure: () -> T) -> T {
|
||||
|
||||
var closureValue: T!
|
||||
autoreleasepool {
|
||||
@@ -44,10 +44,10 @@ internal func cs_autoreleasepool<T>(@noescape closure: () -> T) -> T {
|
||||
return closureValue
|
||||
}
|
||||
|
||||
internal func cs_autoreleasepool<T>(@noescape closure: () throws -> T) throws -> T {
|
||||
internal func cs_autoreleasepool<T>(@noescape _ closure: () throws -> T) throws -> T {
|
||||
|
||||
var closureValue: T!
|
||||
var closureError: ErrorType?
|
||||
var closureError: ErrorProtocol?
|
||||
autoreleasepool {
|
||||
|
||||
do {
|
||||
@@ -67,9 +67,9 @@ internal func cs_autoreleasepool<T>(@noescape closure: () throws -> T) throws ->
|
||||
return closureValue
|
||||
}
|
||||
|
||||
internal func cs_autoreleasepool(@noescape closure: () throws -> Void) throws {
|
||||
internal func cs_autoreleasepool(@noescape _ closure: () throws -> Void) throws {
|
||||
|
||||
var closureError: ErrorType?
|
||||
var closureError: ErrorProtocol?
|
||||
autoreleasepool {
|
||||
|
||||
do {
|
||||
@@ -88,7 +88,7 @@ internal func cs_autoreleasepool(@noescape closure: () throws -> Void) throws {
|
||||
}
|
||||
}
|
||||
|
||||
internal func cs_getAssociatedObjectForKey<T: AnyObject>(key: UnsafePointer<Void>, inObject object: AnyObject) -> T? {
|
||||
internal func cs_getAssociatedObjectForKey<T: AnyObject>(_ key: UnsafePointer<Void>, inObject object: AnyObject) -> T? {
|
||||
|
||||
switch objc_getAssociatedObject(object, key) {
|
||||
|
||||
@@ -103,17 +103,17 @@ internal func cs_getAssociatedObjectForKey<T: AnyObject>(key: UnsafePointer<Void
|
||||
}
|
||||
}
|
||||
|
||||
internal func cs_setAssociatedRetainedObject<T: AnyObject>(associatedObject: T?, forKey key: UnsafePointer<Void>, inObject object: AnyObject) {
|
||||
internal func cs_setAssociatedRetainedObject<T: AnyObject>(_ associatedObject: T?, forKey key: UnsafePointer<Void>, inObject object: AnyObject) {
|
||||
|
||||
objc_setAssociatedObject(object, key, associatedObject, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
|
||||
}
|
||||
|
||||
internal func cs_setAssociatedCopiedObject<T: AnyObject>(associatedObject: T?, forKey key: UnsafePointer<Void>, inObject object: AnyObject) {
|
||||
internal func cs_setAssociatedCopiedObject<T: AnyObject>(_ associatedObject: T?, forKey key: UnsafePointer<Void>, inObject object: AnyObject) {
|
||||
|
||||
objc_setAssociatedObject(object, key, associatedObject, .OBJC_ASSOCIATION_COPY_NONATOMIC)
|
||||
}
|
||||
|
||||
internal func cs_setAssociatedWeakObject<T: AnyObject>(associatedObject: T?, forKey key: UnsafePointer<Void>, inObject object: AnyObject) {
|
||||
internal func cs_setAssociatedWeakObject<T: AnyObject>(_ associatedObject: T?, forKey key: UnsafePointer<Void>, inObject object: AnyObject) {
|
||||
|
||||
if let associatedObject = associatedObject {
|
||||
|
||||
@@ -128,22 +128,22 @@ internal func cs_setAssociatedWeakObject<T: AnyObject>(associatedObject: T?, for
|
||||
|
||||
// MARK: Printing Utilities
|
||||
|
||||
internal func cs_typeName<T>(value: T) -> String {
|
||||
internal func cs_typeName<T>(_ value: T) -> String {
|
||||
|
||||
return "'\(String(reflecting: value.dynamicType))'"
|
||||
}
|
||||
|
||||
internal func cs_typeName<T>(value: T.Type) -> String {
|
||||
internal func cs_typeName<T>(_ value: T.Type) -> String {
|
||||
|
||||
return "'\(value)'"
|
||||
}
|
||||
|
||||
internal func cs_typeName(value: AnyClass) -> String {
|
||||
internal func cs_typeName(_ value: AnyClass) -> String {
|
||||
|
||||
return "'\(value)'"
|
||||
}
|
||||
|
||||
internal func cs_typeName(name: String?) -> String {
|
||||
internal func cs_typeName(_ name: String?) -> String {
|
||||
|
||||
return "<\(name ?? "unknown")>"
|
||||
}
|
||||
|
||||
@@ -29,13 +29,13 @@ import CoreData
|
||||
|
||||
// MARK: - MigrationManager
|
||||
|
||||
internal final class MigrationManager: NSMigrationManager, NSProgressReporting {
|
||||
internal final class MigrationManager: NSMigrationManager, ProgressReporting {
|
||||
|
||||
// MARK: NSObject
|
||||
|
||||
override func didChangeValueForKey(key: String) {
|
||||
override func didChangeValue(forKey key: String) {
|
||||
|
||||
super.didChangeValueForKey(key)
|
||||
super.didChangeValue(forKey: key)
|
||||
|
||||
guard key == "migrationProgress" else {
|
||||
|
||||
@@ -48,7 +48,7 @@ internal final class MigrationManager: NSMigrationManager, NSProgressReporting {
|
||||
|
||||
// MARK: NSMigrationManager
|
||||
|
||||
init(sourceModel: NSManagedObjectModel, destinationModel: NSManagedObjectModel, progress: NSProgress) {
|
||||
init(sourceModel: NSManagedObjectModel, destinationModel: NSManagedObjectModel, progress: Progress) {
|
||||
|
||||
self.progress = progress
|
||||
|
||||
@@ -58,5 +58,5 @@ internal final class MigrationManager: NSMigrationManager, NSProgressReporting {
|
||||
|
||||
// MARK: NSProgressReporting
|
||||
|
||||
let progress: NSProgress
|
||||
let progress: Progress
|
||||
}
|
||||
|
||||
20
Sources/Internal/NSFetchRequest+CoreStore.swift
Normal file
20
Sources/Internal/NSFetchRequest+CoreStore.swift
Normal file
@@ -0,0 +1,20 @@
|
||||
//
|
||||
// NSFetchRequest+CoreStore.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Created by John Rommel Estropia on 2016/07/20.
|
||||
// Copyright © 2016 John Rommel Estropia. All rights reserved.
|
||||
//
|
||||
|
||||
import CoreData
|
||||
|
||||
internal extension NSFetchRequest {
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
@nonobjc
|
||||
internal func cs_dynamicCast<U: NSFetchRequestResult>() -> NSFetchRequest<U> {
|
||||
|
||||
return unsafeBitCast(self, to: NSFetchRequest<U>.self)
|
||||
}
|
||||
}
|
||||
@@ -50,7 +50,7 @@ internal extension NSManagedObjectContext {
|
||||
set {
|
||||
|
||||
cs_setAssociatedCopiedObject(
|
||||
NSNumber(bool: newValue),
|
||||
NSNumber(value: newValue),
|
||||
forKey: &PropertyKeys.shouldCascadeSavesToParent,
|
||||
inObject: self
|
||||
)
|
||||
@@ -58,26 +58,26 @@ internal extension NSManagedObjectContext {
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
internal func entityDescriptionForEntityType(entity: NSManagedObject.Type) -> NSEntityDescription? {
|
||||
internal func entityDescriptionForEntityType(_ entity: NSManagedObject.Type) -> NSEntityDescription? {
|
||||
|
||||
return self.entityDescriptionForEntityClass(entity)
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
internal func entityDescriptionForEntityClass(entity: AnyClass) -> NSEntityDescription? {
|
||||
internal func entityDescriptionForEntityClass(_ entity: AnyClass) -> NSEntityDescription? {
|
||||
|
||||
guard let entityName = self.parentStack?.entityNameForEntityClass(entity) else {
|
||||
|
||||
return nil
|
||||
}
|
||||
return NSEntityDescription.entityForName(
|
||||
entityName,
|
||||
inManagedObjectContext: self
|
||||
return NSEntityDescription.entity(
|
||||
forEntityName: entityName,
|
||||
in: self
|
||||
)
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
internal func setupForCoreStoreWithContextName(contextName: String) {
|
||||
internal func setupForCoreStoreWithContextName(_ contextName: String) {
|
||||
|
||||
#if USE_FRAMEWORKS
|
||||
|
||||
@@ -91,7 +91,7 @@ internal extension NSManagedObjectContext {
|
||||
#endif
|
||||
|
||||
self.observerForWillSaveNotification = NotificationObserver(
|
||||
notificationName: NSManagedObjectContextWillSaveNotification,
|
||||
notificationName: NSNotification.Name.NSManagedObjectContextWillSave.rawValue,
|
||||
object: self,
|
||||
closure: { (note) -> Void in
|
||||
|
||||
@@ -105,7 +105,7 @@ internal extension NSManagedObjectContext {
|
||||
|
||||
do {
|
||||
|
||||
try context.obtainPermanentIDsForObjects(Array(insertedObjects))
|
||||
try context.obtainPermanentIDs(for: Array(insertedObjects))
|
||||
}
|
||||
catch {
|
||||
|
||||
|
||||
@@ -34,15 +34,15 @@ internal extension NSManagedObjectContext {
|
||||
// MARK: Internal: Fetch Existing
|
||||
|
||||
@nonobjc
|
||||
internal func fetchExisting<T: NSManagedObject>(object: T) -> T? {
|
||||
internal func fetchExisting<T: NSManagedObject>(_ object: T) -> T? {
|
||||
|
||||
if object.objectID.temporaryID {
|
||||
if object.objectID.isTemporaryID {
|
||||
|
||||
do {
|
||||
|
||||
try withExtendedLifetime(self) { (context: NSManagedObjectContext) -> Void in
|
||||
|
||||
try context.obtainPermanentIDsForObjects([object])
|
||||
try context.obtainPermanentIDs(for: [object])
|
||||
}
|
||||
}
|
||||
catch {
|
||||
@@ -54,10 +54,9 @@ internal extension NSManagedObjectContext {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
|
||||
let existingObject = try self.existingObjectWithID(object.objectID)
|
||||
let existingObject = try self.existingObject(with: object.objectID)
|
||||
return (existingObject as! T)
|
||||
}
|
||||
catch {
|
||||
@@ -74,38 +73,38 @@ internal extension NSManagedObjectContext {
|
||||
// MARK: Internal: Fetch One
|
||||
|
||||
@nonobjc
|
||||
internal func fetchOne<T: NSManagedObject>(from: From<T>, _ fetchClauses: FetchClause...) -> T? {
|
||||
internal func fetchOne<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> T? {
|
||||
|
||||
return self.fetchOne(from, fetchClauses)
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
internal func fetchOne<T: NSManagedObject>(from: From<T>, _ fetchClauses: [FetchClause]) -> T? {
|
||||
internal func fetchOne<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> T? {
|
||||
|
||||
let fetchRequest = CoreStoreFetchRequest()
|
||||
let fetchRequest = CoreStoreFetchRequest<T>()
|
||||
let storeFound = from.applyToFetchRequest(fetchRequest, context: self)
|
||||
|
||||
fetchRequest.fetchLimit = 1
|
||||
fetchRequest.resultType = .ManagedObjectResultType
|
||||
fetchRequest.resultType = .managedObjectResultType
|
||||
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
|
||||
|
||||
guard storeFound else {
|
||||
|
||||
return nil
|
||||
}
|
||||
return self.fetchOne(fetchRequest)
|
||||
return self.fetchOne(fetchRequest.dynamicCast())
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
internal func fetchOne<T: NSManagedObject>(fetchRequest: NSFetchRequest) -> T? {
|
||||
internal func fetchOne<T: NSManagedObject>(_ fetchRequest: NSFetchRequest<T>) -> T? {
|
||||
|
||||
var fetchResults: [T]?
|
||||
var fetchError: ErrorType?
|
||||
self.performBlockAndWait {
|
||||
var fetchError: ErrorProtocol?
|
||||
self.performAndWait {
|
||||
|
||||
do {
|
||||
|
||||
fetchResults = try self.executeFetchRequest(fetchRequest) as? [T]
|
||||
fetchResults = try self.fetch(fetchRequest)
|
||||
}
|
||||
catch {
|
||||
|
||||
@@ -120,7 +119,6 @@ internal extension NSManagedObjectContext {
|
||||
)
|
||||
return nil
|
||||
}
|
||||
|
||||
return fetchResults?.first
|
||||
}
|
||||
|
||||
@@ -128,38 +126,38 @@ internal extension NSManagedObjectContext {
|
||||
// MARK: Internal: Fetch All
|
||||
|
||||
@nonobjc
|
||||
internal func fetchAll<T: NSManagedObject>(from: From<T>, _ fetchClauses: FetchClause...) -> [T]? {
|
||||
internal func fetchAll<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> [T]? {
|
||||
|
||||
return self.fetchAll(from, fetchClauses)
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
internal func fetchAll<T: NSManagedObject>(from: From<T>, _ fetchClauses: [FetchClause]) -> [T]? {
|
||||
internal func fetchAll<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> [T]? {
|
||||
|
||||
let fetchRequest = CoreStoreFetchRequest()
|
||||
let fetchRequest = CoreStoreFetchRequest<T>()
|
||||
let storeFound = from.applyToFetchRequest(fetchRequest, context: self)
|
||||
|
||||
fetchRequest.fetchLimit = 0
|
||||
fetchRequest.resultType = .ManagedObjectResultType
|
||||
fetchRequest.resultType = .managedObjectResultType
|
||||
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
|
||||
|
||||
guard storeFound else {
|
||||
|
||||
return nil
|
||||
}
|
||||
return self.fetchAll(fetchRequest)
|
||||
return self.fetchAll(fetchRequest.dynamicCast())
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
internal func fetchAll<T: NSManagedObject>(fetchRequest: NSFetchRequest) -> [T]? {
|
||||
internal func fetchAll<T: NSManagedObject>(_ fetchRequest: NSFetchRequest<T>) -> [T]? {
|
||||
|
||||
var fetchResults: [T]?
|
||||
var fetchError: ErrorType?
|
||||
self.performBlockAndWait {
|
||||
var fetchError: ErrorProtocol?
|
||||
self.performAndWait {
|
||||
|
||||
do {
|
||||
|
||||
fetchResults = try self.executeFetchRequest(fetchRequest) as? [T]
|
||||
fetchResults = try self.fetch(fetchRequest)
|
||||
}
|
||||
catch {
|
||||
|
||||
@@ -174,7 +172,6 @@ internal extension NSManagedObjectContext {
|
||||
)
|
||||
return nil
|
||||
}
|
||||
|
||||
return fetchResults
|
||||
}
|
||||
|
||||
@@ -182,15 +179,15 @@ internal extension NSManagedObjectContext {
|
||||
// MARK: Internal: Count
|
||||
|
||||
@nonobjc
|
||||
internal func fetchCount<T: NSManagedObject>(from: From<T>, _ fetchClauses: FetchClause...) -> Int? {
|
||||
internal func fetchCount<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> Int? {
|
||||
|
||||
return self.fetchCount(from, fetchClauses)
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
internal func fetchCount<T: NSManagedObject>(from: From<T>, _ fetchClauses: [FetchClause]) -> Int? {
|
||||
internal func fetchCount<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> Int? {
|
||||
|
||||
let fetchRequest = CoreStoreFetchRequest()
|
||||
let fetchRequest = CoreStoreFetchRequest<T>()
|
||||
let storeFound = from.applyToFetchRequest(fetchRequest, context: self)
|
||||
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
|
||||
|
||||
@@ -198,27 +195,33 @@ internal extension NSManagedObjectContext {
|
||||
|
||||
return nil
|
||||
}
|
||||
return self.fetchCount(fetchRequest)
|
||||
return self.fetchCount(fetchRequest.dynamicCast())
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
internal func fetchCount(fetchRequest: NSFetchRequest) -> Int? {
|
||||
internal func fetchCount<T: NSManagedObject>(_ fetchRequest: NSFetchRequest<T>) -> Int? {
|
||||
|
||||
var count = 0
|
||||
var error: NSError?
|
||||
self.performBlockAndWait {
|
||||
var countError: ErrorProtocol?
|
||||
self.performAndWait {
|
||||
|
||||
count = self.countForFetchRequest(fetchRequest, error: &error)
|
||||
do {
|
||||
|
||||
count = try self.count(for: fetchRequest)
|
||||
}
|
||||
catch {
|
||||
|
||||
countError = error
|
||||
}
|
||||
}
|
||||
if count == NSNotFound {
|
||||
|
||||
CoreStore.log(
|
||||
CoreStoreError(error),
|
||||
"Failed executing fetch request."
|
||||
CoreStoreError(countError),
|
||||
"Failed executing count request."
|
||||
)
|
||||
return nil
|
||||
}
|
||||
|
||||
return count
|
||||
}
|
||||
|
||||
@@ -226,38 +229,38 @@ internal extension NSManagedObjectContext {
|
||||
// MARK: Internal: Object ID
|
||||
|
||||
@nonobjc
|
||||
internal func fetchObjectID<T: NSManagedObject>(from: From<T>, _ fetchClauses: FetchClause...) -> NSManagedObjectID? {
|
||||
internal func fetchObjectID<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> NSManagedObjectID? {
|
||||
|
||||
return self.fetchObjectID(from, fetchClauses)
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
internal func fetchObjectID<T: NSManagedObject>(from: From<T>, _ fetchClauses: [FetchClause]) -> NSManagedObjectID? {
|
||||
internal func fetchObjectID<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> NSManagedObjectID? {
|
||||
|
||||
let fetchRequest = CoreStoreFetchRequest()
|
||||
let fetchRequest = CoreStoreFetchRequest<NSManagedObjectID>()
|
||||
let storeFound = from.applyToFetchRequest(fetchRequest, context: self)
|
||||
|
||||
fetchRequest.fetchLimit = 1
|
||||
fetchRequest.resultType = .ManagedObjectIDResultType
|
||||
fetchRequest.resultType = .managedObjectIDResultType
|
||||
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
|
||||
|
||||
guard storeFound else {
|
||||
|
||||
return nil
|
||||
}
|
||||
return self.fetchObjectID(fetchRequest)
|
||||
return self.fetchObjectID(fetchRequest.dynamicCast())
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
internal func fetchObjectID(fetchRequest: NSFetchRequest) -> NSManagedObjectID? {
|
||||
internal func fetchObjectID(_ fetchRequest: NSFetchRequest<NSManagedObjectID>) -> NSManagedObjectID? {
|
||||
|
||||
var fetchResults: [NSManagedObjectID]?
|
||||
var fetchError: ErrorType?
|
||||
self.performBlockAndWait {
|
||||
var fetchError: ErrorProtocol?
|
||||
self.performAndWait {
|
||||
|
||||
do {
|
||||
|
||||
fetchResults = try self.executeFetchRequest(fetchRequest) as? [NSManagedObjectID]
|
||||
fetchResults = try self.fetch(fetchRequest)
|
||||
}
|
||||
catch {
|
||||
|
||||
@@ -272,7 +275,6 @@ internal extension NSManagedObjectContext {
|
||||
)
|
||||
return nil
|
||||
}
|
||||
|
||||
return fetchResults?.first
|
||||
}
|
||||
|
||||
@@ -280,38 +282,38 @@ internal extension NSManagedObjectContext {
|
||||
// MARK: Internal: Object IDs
|
||||
|
||||
@nonobjc
|
||||
internal func fetchObjectIDs<T: NSManagedObject>(from: From<T>, _ fetchClauses: FetchClause...) -> [NSManagedObjectID]? {
|
||||
internal func fetchObjectIDs<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> [NSManagedObjectID]? {
|
||||
|
||||
return self.fetchObjectIDs(from, fetchClauses)
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
internal func fetchObjectIDs<T: NSManagedObject>(from: From<T>, _ fetchClauses: [FetchClause]) -> [NSManagedObjectID]? {
|
||||
internal func fetchObjectIDs<T: NSManagedObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> [NSManagedObjectID]? {
|
||||
|
||||
let fetchRequest = CoreStoreFetchRequest()
|
||||
let fetchRequest = CoreStoreFetchRequest<NSManagedObjectID>()
|
||||
let storeFound = from.applyToFetchRequest(fetchRequest, context: self)
|
||||
|
||||
fetchRequest.fetchLimit = 0
|
||||
fetchRequest.resultType = .ManagedObjectIDResultType
|
||||
fetchRequest.resultType = .managedObjectIDResultType
|
||||
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
|
||||
|
||||
guard storeFound else {
|
||||
|
||||
return nil
|
||||
}
|
||||
return self.fetchObjectIDs(fetchRequest)
|
||||
return self.fetchObjectIDs(fetchRequest.dynamicCast())
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
internal func fetchObjectIDs(fetchRequest: NSFetchRequest) -> [NSManagedObjectID]? {
|
||||
internal func fetchObjectIDs(_ fetchRequest: NSFetchRequest<NSManagedObjectID>) -> [NSManagedObjectID]? {
|
||||
|
||||
var fetchResults: [NSManagedObjectID]?
|
||||
var fetchError: ErrorType?
|
||||
self.performBlockAndWait {
|
||||
var fetchError: ErrorProtocol?
|
||||
self.performAndWait {
|
||||
|
||||
do {
|
||||
|
||||
fetchResults = try self.executeFetchRequest(fetchRequest) as? [NSManagedObjectID]
|
||||
fetchResults = try self.fetch(fetchRequest)
|
||||
}
|
||||
catch {
|
||||
|
||||
@@ -326,7 +328,6 @@ internal extension NSManagedObjectContext {
|
||||
)
|
||||
return nil
|
||||
}
|
||||
|
||||
return fetchResults
|
||||
}
|
||||
|
||||
@@ -334,19 +335,19 @@ internal extension NSManagedObjectContext {
|
||||
// MARK: Internal: Delete All
|
||||
|
||||
@nonobjc
|
||||
internal func deleteAll<T: NSManagedObject>(from: From<T>, _ deleteClauses: DeleteClause...) -> Int? {
|
||||
internal func deleteAll<T: NSManagedObject>(_ from: From<T>, _ deleteClauses: DeleteClause...) -> Int? {
|
||||
|
||||
return self.deleteAll(from, deleteClauses)
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
internal func deleteAll<T: NSManagedObject>(from: From<T>, _ deleteClauses: [DeleteClause]) -> Int? {
|
||||
internal func deleteAll<T: NSManagedObject>(_ from: From<T>, _ deleteClauses: [DeleteClause]) -> Int? {
|
||||
|
||||
let fetchRequest = CoreStoreFetchRequest()
|
||||
let fetchRequest = CoreStoreFetchRequest<T>()
|
||||
let storeFound = from.applyToFetchRequest(fetchRequest, context: self)
|
||||
|
||||
fetchRequest.fetchLimit = 0
|
||||
fetchRequest.resultType = .ManagedObjectResultType
|
||||
fetchRequest.resultType = .managedObjectResultType
|
||||
fetchRequest.returnsObjectsAsFaults = true
|
||||
fetchRequest.includesPropertyValues = false
|
||||
deleteClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
|
||||
@@ -355,24 +356,24 @@ internal extension NSManagedObjectContext {
|
||||
|
||||
return nil
|
||||
}
|
||||
return self.deleteAll(fetchRequest)
|
||||
return self.deleteAll(fetchRequest.dynamicCast())
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
internal func deleteAll(fetchRequest: NSFetchRequest) -> Int? {
|
||||
internal func deleteAll<T: NSManagedObject>(_ fetchRequest: NSFetchRequest<T>) -> Int? {
|
||||
|
||||
var numberOfDeletedObjects: Int?
|
||||
var fetchError: ErrorType?
|
||||
self.performBlockAndWait {
|
||||
var fetchError: ErrorProtocol?
|
||||
self.performAndWait {
|
||||
|
||||
cs_autoreleasepool {
|
||||
|
||||
do {
|
||||
|
||||
let fetchResults = try self.executeFetchRequest(fetchRequest) as? [NSManagedObject] ?? []
|
||||
let fetchResults = try self.fetch(fetchRequest)
|
||||
for object in fetchResults {
|
||||
|
||||
self.deleteObject(object)
|
||||
self.delete(object)
|
||||
}
|
||||
numberOfDeletedObjects = fetchResults.count
|
||||
}
|
||||
@@ -390,7 +391,6 @@ internal extension NSManagedObjectContext {
|
||||
)
|
||||
return nil
|
||||
}
|
||||
|
||||
return numberOfDeletedObjects
|
||||
}
|
||||
|
||||
@@ -398,15 +398,15 @@ internal extension NSManagedObjectContext {
|
||||
// MARK: Internal: Value
|
||||
|
||||
@nonobjc
|
||||
internal func queryValue<T: NSManagedObject, U: SelectValueResultType>(from: From<T>, _ selectClause: Select<U>, _ queryClauses: QueryClause...) -> U? {
|
||||
internal func queryValue<T: NSManagedObject, U: SelectValueResultType>(_ from: From<T>, _ selectClause: Select<U>, _ queryClauses: QueryClause...) -> U? {
|
||||
|
||||
return self.queryValue(from, selectClause, queryClauses)
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
internal func queryValue<T: NSManagedObject, U: SelectValueResultType>(from: From<T>, _ selectClause: Select<U>, _ queryClauses: [QueryClause]) -> U? {
|
||||
internal func queryValue<T: NSManagedObject, U: SelectValueResultType>(_ from: From<T>, _ selectClause: Select<U>, _ queryClauses: [QueryClause]) -> U? {
|
||||
|
||||
let fetchRequest = CoreStoreFetchRequest()
|
||||
let fetchRequest = CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
let storeFound = from.applyToFetchRequest(fetchRequest, context: self)
|
||||
|
||||
fetchRequest.fetchLimit = 0
|
||||
@@ -423,15 +423,15 @@ internal extension NSManagedObjectContext {
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
internal func queryValue<U: SelectValueResultType>(selectTerms: [SelectTerm], fetchRequest: NSFetchRequest) -> U? {
|
||||
internal func queryValue<U: SelectValueResultType>(_ selectTerms: [SelectTerm], fetchRequest: NSFetchRequest<NSFetchRequestResult>) -> U? {
|
||||
|
||||
var fetchResults: [AnyObject]?
|
||||
var fetchError: ErrorType?
|
||||
self.performBlockAndWait {
|
||||
var fetchError: ErrorProtocol?
|
||||
self.performAndWait {
|
||||
|
||||
do {
|
||||
|
||||
fetchResults = try self.executeFetchRequest(fetchRequest)
|
||||
fetchResults = try self.fetch(fetchRequest)
|
||||
}
|
||||
catch {
|
||||
|
||||
@@ -456,15 +456,15 @@ internal extension NSManagedObjectContext {
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
internal func queryValue(selectTerms: [SelectTerm], fetchRequest: NSFetchRequest) -> AnyObject? {
|
||||
internal func queryValue(_ selectTerms: [SelectTerm], fetchRequest: NSFetchRequest<NSFetchRequestResult>) -> AnyObject? {
|
||||
|
||||
var fetchResults: [AnyObject]?
|
||||
var fetchError: ErrorType?
|
||||
self.performBlockAndWait {
|
||||
var fetchError: ErrorProtocol?
|
||||
self.performAndWait {
|
||||
|
||||
do {
|
||||
|
||||
fetchResults = try self.executeFetchRequest(fetchRequest)
|
||||
fetchResults = try self.fetch(fetchRequest)
|
||||
}
|
||||
catch {
|
||||
|
||||
@@ -492,15 +492,15 @@ internal extension NSManagedObjectContext {
|
||||
// MARK: Internal: Attributes
|
||||
|
||||
@nonobjc
|
||||
internal func queryAttributes<T: NSManagedObject>(from: From<T>, _ selectClause: Select<NSDictionary>, _ queryClauses: QueryClause...) -> [[NSString: AnyObject]]? {
|
||||
internal func queryAttributes<T: NSManagedObject>(_ from: From<T>, _ selectClause: Select<NSDictionary>, _ queryClauses: QueryClause...) -> [[NSString: AnyObject]]? {
|
||||
|
||||
return self.queryAttributes(from, selectClause, queryClauses)
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
internal func queryAttributes<T: NSManagedObject>(from: From<T>, _ selectClause: Select<NSDictionary>, _ queryClauses: [QueryClause]) -> [[NSString: AnyObject]]? {
|
||||
internal func queryAttributes<T: NSManagedObject>(_ from: From<T>, _ selectClause: Select<NSDictionary>, _ queryClauses: [QueryClause]) -> [[NSString: AnyObject]]? {
|
||||
|
||||
let fetchRequest = CoreStoreFetchRequest()
|
||||
let fetchRequest = CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
let storeFound = from.applyToFetchRequest(fetchRequest, context: self)
|
||||
|
||||
fetchRequest.fetchLimit = 0
|
||||
@@ -516,15 +516,15 @@ internal extension NSManagedObjectContext {
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
internal func queryAttributes(fetchRequest: NSFetchRequest) -> [[NSString: AnyObject]]? {
|
||||
internal func queryAttributes(_ fetchRequest: NSFetchRequest<NSFetchRequestResult>) -> [[NSString: AnyObject]]? {
|
||||
|
||||
var fetchResults: [AnyObject]?
|
||||
var fetchError: ErrorType?
|
||||
self.performBlockAndWait {
|
||||
var fetchError: ErrorProtocol?
|
||||
self.performAndWait {
|
||||
|
||||
do {
|
||||
|
||||
fetchResults = try self.executeFetchRequest(fetchRequest)
|
||||
fetchResults = try self.fetch(fetchRequest)
|
||||
}
|
||||
catch {
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ internal extension NSManagedObjectContext {
|
||||
|
||||
get {
|
||||
|
||||
if let parentContext = self.parentContext {
|
||||
if let parentContext = self.parent {
|
||||
|
||||
return parentContext.parentStack
|
||||
}
|
||||
@@ -47,7 +47,7 @@ internal extension NSManagedObjectContext {
|
||||
}
|
||||
set {
|
||||
|
||||
guard self.parentContext == nil else {
|
||||
guard self.parent == nil else {
|
||||
|
||||
return
|
||||
}
|
||||
@@ -61,9 +61,9 @@ internal extension NSManagedObjectContext {
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
internal static func rootSavingContextForCoordinator(coordinator: NSPersistentStoreCoordinator) -> NSManagedObjectContext {
|
||||
internal static func rootSavingContextForCoordinator(_ coordinator: NSPersistentStoreCoordinator) -> NSManagedObjectContext {
|
||||
|
||||
let context = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType)
|
||||
let context = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
|
||||
context.persistentStoreCoordinator = coordinator
|
||||
context.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
|
||||
context.undoManager = nil
|
||||
@@ -72,18 +72,18 @@ internal extension NSManagedObjectContext {
|
||||
#if os(iOS) || os(OSX)
|
||||
|
||||
context.observerForDidImportUbiquitousContentChangesNotification = NotificationObserver(
|
||||
notificationName: NSPersistentStoreDidImportUbiquitousContentChangesNotification,
|
||||
notificationName: NSNotification.Name.NSPersistentStoreDidImportUbiquitousContentChanges.rawValue,
|
||||
object: coordinator,
|
||||
closure: { [weak context] (note) -> Void in
|
||||
|
||||
context?.performBlock { () -> Void in
|
||||
context?.perform { () -> Void in
|
||||
|
||||
let updatedObjectIDs = (note.userInfo?[NSUpdatedObjectsKey] as? Set<NSManagedObjectID>) ?? []
|
||||
let updatedObjectIDs = ((note as NSNotification).userInfo?[NSUpdatedObjectsKey] as? Set<NSManagedObjectID>) ?? []
|
||||
for objectID in updatedObjectIDs {
|
||||
|
||||
context?.objectWithID(objectID).willAccessValueForKey(nil)
|
||||
context?.object(with: objectID).willAccessValue(forKey: nil)
|
||||
}
|
||||
context?.mergeChangesFromContextDidSaveNotification(note)
|
||||
context?.mergeChanges(fromContextDidSave: note)
|
||||
}
|
||||
}
|
||||
)
|
||||
@@ -94,15 +94,15 @@ internal extension NSManagedObjectContext {
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
internal static func mainContextForRootContext(rootContext: NSManagedObjectContext) -> NSManagedObjectContext {
|
||||
internal static func mainContextForRootContext(_ rootContext: NSManagedObjectContext) -> NSManagedObjectContext {
|
||||
|
||||
let context = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
|
||||
context.parentContext = rootContext
|
||||
let context = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
|
||||
context.parent = rootContext
|
||||
context.mergePolicy = NSRollbackMergePolicy
|
||||
context.undoManager = nil
|
||||
context.setupForCoreStoreWithContextName("com.corestore.maincontext")
|
||||
context.observerForDidSaveNotification = NotificationObserver(
|
||||
notificationName: NSManagedObjectContextDidSaveNotification,
|
||||
notificationName: NSNotification.Name.NSManagedObjectContextDidSave.rawValue,
|
||||
object: rootContext,
|
||||
closure: { [weak context] (note) -> Void in
|
||||
|
||||
@@ -113,21 +113,21 @@ internal extension NSManagedObjectContext {
|
||||
}
|
||||
let mergeChanges = { () -> Void in
|
||||
|
||||
let updatedObjects = (note.userInfo?[NSUpdatedObjectsKey] as? Set<NSManagedObject>) ?? []
|
||||
let updatedObjects = ((note as NSNotification).userInfo?[NSUpdatedObjectsKey] as? Set<NSManagedObject>) ?? []
|
||||
for object in updatedObjects {
|
||||
|
||||
context.objectWithID(object.objectID).willAccessValueForKey(nil)
|
||||
context.object(with: object.objectID).willAccessValue(forKey: nil)
|
||||
}
|
||||
context.mergeChangesFromContextDidSaveNotification(note)
|
||||
context.mergeChanges(fromContextDidSave: note)
|
||||
}
|
||||
|
||||
if rootContext.isSavingSynchronously == true {
|
||||
|
||||
context.performBlockAndWait(mergeChanges)
|
||||
context.performAndWait(mergeChanges)
|
||||
}
|
||||
else {
|
||||
|
||||
context.performBlock(mergeChanges)
|
||||
context.perform(mergeChanges)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
@@ -70,7 +70,7 @@ internal extension NSManagedObjectContext {
|
||||
set {
|
||||
|
||||
cs_setAssociatedWeakObject(
|
||||
newValue.flatMap { NSNumber(bool: $0) },
|
||||
newValue.flatMap { NSNumber(value: $0) },
|
||||
forKey: &PropertyKeys.isSavingSynchronously,
|
||||
inObject: self
|
||||
)
|
||||
@@ -88,10 +88,10 @@ internal extension NSManagedObjectContext {
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
internal func temporaryContextInTransactionWithConcurrencyType(concurrencyType: NSManagedObjectContextConcurrencyType) -> NSManagedObjectContext {
|
||||
internal func temporaryContextInTransactionWithConcurrencyType(_ concurrencyType: NSManagedObjectContextConcurrencyType) -> NSManagedObjectContext {
|
||||
|
||||
let context = NSManagedObjectContext(concurrencyType: concurrencyType)
|
||||
context.parentContext = self
|
||||
context.parent = self
|
||||
context.parentStack = self.parentStack
|
||||
context.setupForCoreStoreWithContextName("com.corestore.temporarycontext")
|
||||
context.shouldCascadeSavesToParent = (self.parentStack?.rootSavingContext == self)
|
||||
@@ -105,7 +105,7 @@ internal extension NSManagedObjectContext {
|
||||
|
||||
var result = SaveResult(hasChanges: false)
|
||||
|
||||
self.performBlockAndWait {
|
||||
self.performAndWait {
|
||||
|
||||
guard self.hasChanges else {
|
||||
|
||||
@@ -123,20 +123,20 @@ internal extension NSManagedObjectContext {
|
||||
let saveError = CoreStoreError(error)
|
||||
CoreStore.log(
|
||||
saveError,
|
||||
"Failed to save \(cs_typeName(NSManagedObjectContext))."
|
||||
"Failed to save \(cs_typeName(NSManagedObjectContext.self))."
|
||||
)
|
||||
result = SaveResult(saveError)
|
||||
return
|
||||
}
|
||||
|
||||
if let parentContext = self.parentContext where self.shouldCascadeSavesToParent {
|
||||
if let parentContext = self.parent where self.shouldCascadeSavesToParent {
|
||||
|
||||
switch parentContext.saveSynchronously() {
|
||||
|
||||
case .Success:
|
||||
case .success:
|
||||
result = SaveResult(hasChanges: true)
|
||||
|
||||
case .Failure(let error):
|
||||
case .failure(let error):
|
||||
result = SaveResult(error)
|
||||
}
|
||||
}
|
||||
@@ -150,13 +150,13 @@ internal extension NSManagedObjectContext {
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
internal func saveAsynchronouslyWithCompletion(completion: ((result: SaveResult) -> Void) = { _ in }) {
|
||||
internal func saveAsynchronouslyWithCompletion(_ completion: ((result: SaveResult) -> Void) = { _ in }) {
|
||||
|
||||
self.performBlock {
|
||||
self.perform {
|
||||
|
||||
guard self.hasChanges else {
|
||||
|
||||
GCDQueue.Main.async {
|
||||
GCDQueue.main.async {
|
||||
|
||||
completion(result: SaveResult(hasChanges: false))
|
||||
}
|
||||
@@ -174,22 +174,22 @@ internal extension NSManagedObjectContext {
|
||||
let saveError = CoreStoreError(error)
|
||||
CoreStore.log(
|
||||
saveError,
|
||||
"Failed to save \(cs_typeName(NSManagedObjectContext))."
|
||||
"Failed to save \(cs_typeName(NSManagedObjectContext.self))."
|
||||
)
|
||||
GCDQueue.Main.async {
|
||||
GCDQueue.main.async {
|
||||
|
||||
completion(result: SaveResult(saveError))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if let parentContext = self.parentContext where self.shouldCascadeSavesToParent {
|
||||
if let parentContext = self.parent where self.shouldCascadeSavesToParent {
|
||||
|
||||
parentContext.saveAsynchronouslyWithCompletion(completion)
|
||||
}
|
||||
else {
|
||||
|
||||
GCDQueue.Main.async {
|
||||
GCDQueue.main.async {
|
||||
|
||||
completion(result: SaveResult(hasChanges: true))
|
||||
}
|
||||
@@ -206,7 +206,7 @@ internal extension NSManagedObjectContext {
|
||||
}
|
||||
else {
|
||||
|
||||
self.registeredObjects.forEach { self.refreshObject($0, mergeChanges: true) }
|
||||
self.registeredObjects.forEach { self.refresh($0, mergeChanges: true) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,17 +34,17 @@ internal extension NSManagedObjectModel {
|
||||
// MARK: Internal
|
||||
|
||||
@nonobjc
|
||||
internal static func fromBundle(bundle: NSBundle, modelName: String, modelVersionHints: Set<String> = []) -> NSManagedObjectModel {
|
||||
internal static func fromBundle(_ bundle: Bundle, modelName: String, modelVersionHints: Set<String> = []) -> NSManagedObjectModel {
|
||||
|
||||
guard let modelFilePath = bundle.pathForResource(modelName, ofType: "momd") else {
|
||||
|
||||
CoreStore.abort("Could not find \"\(modelName).momd\" from the bundle. \(bundle)")
|
||||
}
|
||||
|
||||
let modelFileURL = NSURL(fileURLWithPath: modelFilePath)
|
||||
let versionInfoPlistURL = modelFileURL.URLByAppendingPathComponent("VersionInfo.plist", isDirectory: false)
|
||||
let modelFileURL = URL(fileURLWithPath: modelFilePath)
|
||||
let versionInfoPlistURL = try! modelFileURL.appendingPathComponent("VersionInfo.plist", isDirectory: false)
|
||||
|
||||
guard let versionInfo = NSDictionary(contentsOfURL: versionInfoPlistURL),
|
||||
guard let versionInfo = NSDictionary(contentsOf: versionInfoPlistURL),
|
||||
let versionHashes = versionInfo["NSManagedObjectModel_VersionHashes"] as? [String: AnyObject] else {
|
||||
|
||||
CoreStore.abort("Could not load \(cs_typeName(NSManagedObjectModel)) metadata from path \"\(versionInfoPlistURL)\".")
|
||||
@@ -56,10 +56,10 @@ internal extension NSManagedObjectModel {
|
||||
|
||||
currentModelVersion = plistModelVersion
|
||||
}
|
||||
else if let resolvedVersion = modelVersions.intersect(modelVersionHints).first {
|
||||
else if let resolvedVersion = modelVersions.intersection(modelVersionHints).first {
|
||||
|
||||
CoreStore.log(
|
||||
.Warning,
|
||||
.warning,
|
||||
message: "The MigrationChain leaf versions do not include the model file's current version. Resolving to version \"\(resolvedVersion)\"."
|
||||
)
|
||||
currentModelVersion = resolvedVersion
|
||||
@@ -69,7 +69,7 @@ internal extension NSManagedObjectModel {
|
||||
if !modelVersionHints.isEmpty {
|
||||
|
||||
CoreStore.log(
|
||||
.Warning,
|
||||
.warning,
|
||||
message: "The MigrationChain leaf versions do not include any of the model file's embedded versions. Resolving to version \"\(resolvedVersion)\"."
|
||||
)
|
||||
}
|
||||
@@ -80,10 +80,10 @@ internal extension NSManagedObjectModel {
|
||||
CoreStore.abort("No model files were found in URL \"\(modelFileURL)\".")
|
||||
}
|
||||
|
||||
var modelVersionFileURL: NSURL?
|
||||
var modelVersionFileURL: URL?
|
||||
for modelVersion in modelVersions {
|
||||
|
||||
let fileURL = modelFileURL.URLByAppendingPathComponent("\(modelVersion).mom", isDirectory: false)
|
||||
let fileURL = try! modelFileURL.appendingPathComponent("\(modelVersion).mom", isDirectory: false)
|
||||
|
||||
if modelVersion == currentModelVersion {
|
||||
|
||||
@@ -92,13 +92,13 @@ internal extension NSManagedObjectModel {
|
||||
}
|
||||
|
||||
precondition(
|
||||
NSManagedObjectModel(contentsOfURL: fileURL) != nil,
|
||||
NSManagedObjectModel(contentsOf: fileURL) != nil,
|
||||
"Could not find the \"\(modelVersion).mom\" version file for the model at URL \"\(modelFileURL)\"."
|
||||
)
|
||||
}
|
||||
|
||||
if let modelVersionFileURL = modelVersionFileURL,
|
||||
let rootModel = NSManagedObjectModel(contentsOfURL: modelVersionFileURL) {
|
||||
let rootModel = NSManagedObjectModel(contentsOf: modelVersionFileURL) {
|
||||
|
||||
rootModel.modelVersionFileURL = modelVersionFileURL
|
||||
rootModel.modelVersions = modelVersions
|
||||
@@ -152,7 +152,7 @@ internal extension NSManagedObjectModel {
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
internal func entityNameForClass(entityClass: AnyClass) -> String {
|
||||
internal func entityNameForClass(_ entityClass: AnyClass) -> String {
|
||||
|
||||
return self.entityNameMapping[NSStringFromClass(entityClass)]!
|
||||
}
|
||||
@@ -189,8 +189,8 @@ internal extension NSManagedObjectModel {
|
||||
return nil
|
||||
}
|
||||
|
||||
let versionModelFileURL = modelFileURL.URLByAppendingPathComponent("\(modelVersion).mom", isDirectory: false)
|
||||
guard let model = NSManagedObjectModel(contentsOfURL: versionModelFileURL) else {
|
||||
let versionModelFileURL = try! modelFileURL.appendingPathComponent("\(modelVersion).mom", isDirectory: false)
|
||||
guard let model = NSManagedObjectModel(contentsOf: versionModelFileURL) else {
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -204,7 +204,7 @@ internal extension NSManagedObjectModel {
|
||||
@nonobjc
|
||||
internal subscript(metadata: [String: AnyObject]) -> NSManagedObjectModel? {
|
||||
|
||||
guard let modelHashes = metadata[NSStoreModelVersionHashesKey] as? [String : NSData] else {
|
||||
guard let modelHashes = metadata[NSStoreModelVersionHashesKey] as? [String : Data] else {
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -222,16 +222,16 @@ internal extension NSManagedObjectModel {
|
||||
// MARK: Private
|
||||
|
||||
@nonobjc
|
||||
private var modelFileURL: NSURL? {
|
||||
private var modelFileURL: URL? {
|
||||
|
||||
get {
|
||||
|
||||
return self.modelVersionFileURL?.URLByDeletingLastPathComponent
|
||||
return try! self.modelVersionFileURL?.deletingLastPathComponent()
|
||||
}
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
private var modelVersionFileURL: NSURL? {
|
||||
private var modelVersionFileURL: URL? {
|
||||
|
||||
get {
|
||||
|
||||
@@ -239,12 +239,12 @@ internal extension NSManagedObjectModel {
|
||||
&PropertyKeys.modelVersionFileURL,
|
||||
inObject: self
|
||||
)
|
||||
return value
|
||||
return value as URL?
|
||||
}
|
||||
set {
|
||||
|
||||
cs_setAssociatedCopiedObject(
|
||||
newValue,
|
||||
newValue as NSURL?,
|
||||
forKey: &PropertyKeys.modelVersionFileURL,
|
||||
inObject: self
|
||||
)
|
||||
@@ -270,7 +270,7 @@ internal extension NSManagedObjectModel {
|
||||
}
|
||||
|
||||
let className = $0.managedObjectClassName
|
||||
mapping[className] = entityName
|
||||
mapping[className!] = entityName
|
||||
}
|
||||
cs_setAssociatedCopiedObject(
|
||||
mapping as NSDictionary,
|
||||
|
||||
@@ -36,124 +36,47 @@ import CoreData
|
||||
internal extension NSPersistentStoreCoordinator {
|
||||
|
||||
@nonobjc
|
||||
internal func performAsynchronously(closure: () -> Void) {
|
||||
internal func performAsynchronously(_ closure: () -> Void) {
|
||||
|
||||
#if USE_FRAMEWORKS
|
||||
|
||||
self.performBlock(closure)
|
||||
#else
|
||||
|
||||
if #available(iOS 8.0, *) {
|
||||
|
||||
self.performBlock(closure)
|
||||
}
|
||||
else {
|
||||
|
||||
self.lock()
|
||||
GCDQueue.Default.async {
|
||||
|
||||
closure()
|
||||
self.unlock()
|
||||
}
|
||||
}
|
||||
#endif
|
||||
self.perform(closure)
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
internal func performSynchronously<T>(closure: () -> T) -> T {
|
||||
internal func performSynchronously<T>(_ closure: () -> T) -> T {
|
||||
|
||||
var result: T?
|
||||
#if USE_FRAMEWORKS
|
||||
self.performAndWait {
|
||||
|
||||
self.performBlockAndWait {
|
||||
|
||||
result = closure()
|
||||
}
|
||||
#else
|
||||
|
||||
if #available(iOS 8.0, *) {
|
||||
|
||||
self.performBlockAndWait {
|
||||
|
||||
result = closure()
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
self.lock()
|
||||
cs_autoreleasepool {
|
||||
|
||||
result = closure()
|
||||
}
|
||||
self.unlock()
|
||||
}
|
||||
#endif
|
||||
|
||||
result = closure()
|
||||
}
|
||||
return result!
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
internal func performSynchronously<T>(closure: () throws -> T) throws -> T {
|
||||
internal func performSynchronously<T>(_ closure: () throws -> T) throws -> T {
|
||||
|
||||
var closureError: ErrorType?
|
||||
var closureError: ErrorProtocol?
|
||||
var result: T?
|
||||
#if USE_FRAMEWORKS
|
||||
self.performAndWait {
|
||||
|
||||
self.performBlockAndWait {
|
||||
do {
|
||||
|
||||
do {
|
||||
|
||||
result = try closure()
|
||||
}
|
||||
catch {
|
||||
|
||||
closureError = error
|
||||
}
|
||||
result = try closure()
|
||||
}
|
||||
#else
|
||||
|
||||
if #available(iOS 8.0, *) {
|
||||
catch {
|
||||
|
||||
self.performBlockAndWait {
|
||||
|
||||
do {
|
||||
|
||||
result = try closure()
|
||||
}
|
||||
catch {
|
||||
|
||||
closureError = error
|
||||
}
|
||||
}
|
||||
closureError = error
|
||||
}
|
||||
else {
|
||||
|
||||
self.lock()
|
||||
cs_autoreleasepool {
|
||||
|
||||
do {
|
||||
|
||||
result = try closure()
|
||||
}
|
||||
catch {
|
||||
|
||||
closureError = error
|
||||
}
|
||||
}
|
||||
self.unlock()
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
if let closureError = closureError {
|
||||
|
||||
throw closureError
|
||||
}
|
||||
|
||||
return result!
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
internal func addPersistentStoreSynchronously(storeType: String, configuration: String?, URL storeURL: NSURL?, options: [NSObject : AnyObject]?) throws -> NSPersistentStore {
|
||||
internal func addPersistentStoreSynchronously(_ storeType: String, configuration: String?, URL storeURL: URL?, options: [NSObject : AnyObject]?) throws -> NSPersistentStore {
|
||||
|
||||
var store: NSPersistentStore?
|
||||
var storeError: NSError?
|
||||
@@ -161,10 +84,10 @@ internal extension NSPersistentStoreCoordinator {
|
||||
|
||||
do {
|
||||
|
||||
store = try self.addPersistentStoreWithType(
|
||||
storeType,
|
||||
configuration: configuration,
|
||||
URL: storeURL,
|
||||
store = try self.addPersistentStore(
|
||||
ofType: storeType,
|
||||
configurationName: configuration,
|
||||
at: storeURL,
|
||||
options: options
|
||||
)
|
||||
}
|
||||
@@ -173,12 +96,10 @@ internal extension NSPersistentStoreCoordinator {
|
||||
storeError = error as NSError
|
||||
}
|
||||
}
|
||||
|
||||
if let store = store {
|
||||
|
||||
return store
|
||||
}
|
||||
|
||||
throw CoreStoreError(storeError)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,23 +36,23 @@ internal final class NotificationObserver {
|
||||
let object: AnyObject?
|
||||
let observer: NSObjectProtocol
|
||||
|
||||
init(notificationName: String, object: AnyObject?, queue: NSOperationQueue? = nil, closure: (note: NSNotification) -> Void) {
|
||||
init(notificationName: String, object: AnyObject?, queue: OperationQueue? = nil, closure: (note: Notification) -> Void) {
|
||||
|
||||
self.notificationName = notificationName
|
||||
self.object = object
|
||||
self.observer = NSNotificationCenter.defaultCenter().addObserverForName(
|
||||
notificationName,
|
||||
self.observer = NotificationCenter.default.addObserver(
|
||||
forName: NSNotification.Name(rawValue: notificationName),
|
||||
object: object,
|
||||
queue: queue,
|
||||
usingBlock: closure
|
||||
using: closure
|
||||
)
|
||||
}
|
||||
|
||||
deinit {
|
||||
|
||||
NSNotificationCenter.defaultCenter().removeObserver(
|
||||
NotificationCenter.default.removeObserver(
|
||||
self.observer,
|
||||
name: self.notificationName,
|
||||
name: NSNotification.Name(rawValue: self.notificationName),
|
||||
object: self.object
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user