NSManagedObject features are now fully supported for CoreStoreObject types. MacOSX 10.12 onwards now support ListMonitors and ObjectMonitors

This commit is contained in:
John Estropia
2017-04-07 20:14:13 +09:00
parent 4aa1a63f9a
commit c0ae129b22
58 changed files with 1172 additions and 803 deletions

View File

@@ -27,10 +27,9 @@ import Foundation
import CoreData
#if os(iOS) || os(watchOS) || os(tvOS)
// MARK: - CoreStore
@available(OSX 10.12, *)
public extension CoreStore {
/**
@@ -144,5 +143,3 @@ public extension CoreStore {
self.defaultStack.monitorSectionedList(createAsynchronously: createAsynchronously, from, sectionBy, fetchClauses)
}
}
#endif

View File

@@ -27,10 +27,9 @@ import Foundation
import CoreData
#if os(iOS) || os(watchOS) || os(tvOS)
// MARK: - DataStack
@available(OSX 10.12, *)
public extension DataStack {
/**
@@ -220,5 +219,3 @@ public extension DataStack {
)
}
}
#endif

View File

@@ -27,8 +27,6 @@ import Foundation
import CoreData
#if os(iOS) || os(watchOS) || os(tvOS)
// MARK: - ListMonitor
/**
@@ -68,7 +66,8 @@ import CoreData
```
In the example above, both `person1` and `person2` will contain the object at section=2, index=3.
*/
public final class ListMonitor<T: NSManagedObject>: Hashable {
@available(OSX 10.12, *)
public final class ListMonitor<T: DynamicObject>: Hashable {
// MARK: Public (Accessors)
@@ -80,7 +79,15 @@ public final class ListMonitor<T: NSManagedObject>: Hashable {
*/
public subscript(index: Int) -> T {
return self.objectsInAllSections()[index]
CoreStore.assert(
!self.isPendingRefetch || Thread.isMainThread,
"Attempted to access a \(cs_typeName(self)) outside the main thread while a refetch is in progress."
)
if self.isSectioned {
return T.cs_fromRaw(object: self.fetchedResultsController.fetchedObjects![index])
}
return self[0, index]
}
/**
@@ -91,12 +98,16 @@ public final class ListMonitor<T: NSManagedObject>: Hashable {
*/
public subscript(safeIndex index: Int) -> T? {
let objects = self.objectsInAllSections()
guard objects.indices.contains(index) else {
if self.isSectioned {
let fetchedObjects = self.fetchedResultsController.fetchedObjects!
if index < fetchedObjects.count && index >= 0 {
return T.cs_fromRaw(object: fetchedObjects[index])
}
return nil
}
return objects[index]
return self[safeSectionIndex: 0, safeItemIndex: index]
}
/**
@@ -128,7 +139,7 @@ public final class ListMonitor<T: NSManagedObject>: Hashable {
return nil
}
return section.objects?[itemIndex] as? T
return T.cs_fromRaw(object: section.objects![itemIndex] as! NSManagedObject)
}
/**
@@ -143,7 +154,7 @@ public final class ListMonitor<T: NSManagedObject>: Hashable {
!self.isPendingRefetch || Thread.isMainThread,
"Attempted to access a \(cs_typeName(self)) outside the main thread while a refetch is in progress."
)
return self.fetchedResultsController.object(at: indexPath) as! T
return T.cs_fromRaw(object: self.fetchedResultsController.object(at: indexPath))
}
/**
@@ -191,42 +202,6 @@ public final class ListMonitor<T: NSManagedObject>: Hashable {
return self.numberOfObjectsInSection(safeSectionIndex: section)! > 0
}
/**
Returns all objects in all sections
- returns: all objects in all sections
*/
public func objectsInAllSections() -> [T] {
CoreStore.assert(
!self.isPendingRefetch || Thread.isMainThread,
"Attempted to access a \(cs_typeName(self)) outside the main thread while a refetch is in progress."
)
return (self.fetchedResultsController.dynamicCast() as NSFetchedResultsController<T>).fetchedObjects ?? []
}
/**
Returns all objects in the specified section
- parameter section: the section index. Using an index outside the valid range will raise an exception.
- returns: all objects in the specified section
*/
public func objectsInSection(_ section: Int) -> [T] {
return (self.sectionInfoAtIndex(section).objects as! [T]?) ?? []
}
/**
Returns all objects in the specified section, or `nil` if out of bounds.
- parameter section: the section index. Using an index outside the valid range will return `nil`.
- returns: all objects in the specified section
*/
public func objectsInSection(safeSectionIndex section: Int) -> [T]? {
return self.sectionInfoAtIndex(safeSectionIndex: section)?.objects as! [T]?
}
/**
Returns the number of sections
@@ -371,7 +346,11 @@ public final class ListMonitor<T: NSManagedObject>: Hashable {
!self.isPendingRefetch || Thread.isMainThread,
"Attempted to access a \(cs_typeName(self)) outside the main thread while a refetch is in progress."
)
return (self.fetchedResultsController.dynamicCast() as NSFetchedResultsController<T>).fetchedObjects?.index(of: object)
if self.isSectioned {
return self.fetchedResultsController.fetchedObjects?.index(of: object.cs_toRaw())
}
return self.fetchedResultsController.indexPath(forObject: object.cs_toRaw())?[1]
}
/**
@@ -386,7 +365,7 @@ public final class ListMonitor<T: NSManagedObject>: Hashable {
!self.isPendingRefetch || Thread.isMainThread,
"Attempted to access a \(cs_typeName(self)) outside the main thread while a refetch is in progress."
)
return self.fetchedResultsController.indexPath(forObject: object)
return self.fetchedResultsController.indexPath(forObject: object.cs_toRaw())
}
@@ -596,22 +575,22 @@ public final class ListMonitor<T: NSManagedObject>: Hashable {
// MARK: Equatable
public static func == <T: NSManagedObject>(lhs: ListMonitor<T>, rhs: ListMonitor<T>) -> Bool {
return lhs === rhs
}
public static func == <T: NSManagedObject, U: NSManagedObject>(lhs: ListMonitor<T>, rhs: ListMonitor<U>) -> Bool {
public static func == (lhs: ListMonitor<T>, rhs: ListMonitor<T>) -> Bool {
return lhs.fetchedResultsController === rhs.fetchedResultsController
}
public static func ~= <T: NSManagedObject>(lhs: ListMonitor<T>, rhs: ListMonitor<T>) -> Bool {
public static func == <T: DynamicObject, U: DynamicObject>(lhs: ListMonitor<T>, rhs: ListMonitor<U>) -> Bool {
return lhs === rhs
return lhs.fetchedResultsController === rhs.fetchedResultsController
}
public static func ~= <T: NSManagedObject, U: NSManagedObject>(lhs: ListMonitor<T>, rhs: ListMonitor<U>) -> Bool {
public static func ~= (lhs: ListMonitor<T>, rhs: ListMonitor<T>) -> Bool {
return lhs.fetchedResultsController === rhs.fetchedResultsController
}
public static func ~= <T: DynamicObject, U: DynamicObject>(lhs: ListMonitor<T>, rhs: ListMonitor<U>) -> Bool {
return lhs.fetchedResultsController === rhs.fetchedResultsController
}
@@ -675,16 +654,6 @@ public final class ListMonitor<T: NSManagedObject>: Hashable {
)
}
internal func downcast() -> ListMonitor<NSManagedObject> {
@inline(__always)
func noWarnUnsafeBitCast<T, U>(_ x: T, to type: U.Type) -> U {
return unsafeBitCast(x, to: type)
}
return noWarnUnsafeBitCast(self, to: ListMonitor<NSManagedObject>.self)
}
internal func registerChangeNotification(_ notificationKey: UnsafeRawPointer, name: Notification.Name, toObserver observer: AnyObject, callback: @escaping (_ monitor: ListMonitor<T>) -> Void) {
cs_setAssociatedRetainedObject(
@@ -1001,6 +970,8 @@ public final class ListMonitor<T: NSManagedObject>: Hashable {
fileprivate let taskGroup = DispatchGroup()
fileprivate let sectionIndexTransformer: (_ sectionName: KeyPath?) -> String?
private let isSectioned: Bool
private var willChangeListKey: Void?
private var didChangeListKey: Void?
private var willRefetchListKey: Void?
@@ -1014,7 +985,7 @@ public final class ListMonitor<T: NSManagedObject>: Hashable {
private var didInsertSectionKey: Void?
private var didDeleteSectionKey: Void?
private let fetchedResultsControllerDelegate: FetchedResultsControllerDelegate<T>
private let fetchedResultsControllerDelegate: FetchedResultsControllerDelegate
private var observerForWillChangePersistentStore: NotificationObserver!
private var observerForDidChangePersistentStore: NotificationObserver!
private let transactionQueue: DispatchQueue
@@ -1043,6 +1014,8 @@ public final class ListMonitor<T: NSManagedObject>: Hashable {
private init(context: NSManagedObjectContext, transactionQueue: DispatchQueue, from: From<T>, sectionBy: SectionBy?, applyFetchClauses: @escaping (_ fetchRequest: NSFetchRequest<NSManagedObject>) -> Void, createAsynchronously: ((ListMonitor<T>) -> Void)?) {
self.isSectioned = (sectionBy != nil)
let fetchRequest = CoreStoreFetchRequest()
fetchRequest.fetchLimit = 0
fetchRequest.resultType = .managedObjectResultType
@@ -1058,7 +1031,7 @@ public final class ListMonitor<T: NSManagedObject>: Hashable {
applyFetchClauses: applyFetchClauses
)
let fetchedResultsControllerDelegate = FetchedResultsControllerDelegate<T>()
let fetchedResultsControllerDelegate = FetchedResultsControllerDelegate()
self.fetchedResultsController = fetchedResultsController
self.fetchedResultsControllerDelegate = fetchedResultsControllerDelegate
@@ -1150,9 +1123,99 @@ public final class ListMonitor<T: NSManagedObject>: Hashable {
}
}
// MARK: - ListMonitor where T: NSManagedObject
@available(OSX 10.12, *)
extension ListMonitor where T: NSManagedObject {
/**
Returns all objects in all sections
- returns: all objects in all sections
*/
public func objectsInAllSections() -> [T] {
CoreStore.assert(
!self.isPendingRefetch || Thread.isMainThread,
"Attempted to access a \(cs_typeName(self)) outside the main thread while a refetch is in progress."
)
return (self.fetchedResultsController.dynamicCast() as NSFetchedResultsController<T>).fetchedObjects ?? []
}
/**
Returns all objects in the specified section
- parameter section: the section index. Using an index outside the valid range will raise an exception.
- returns: all objects in the specified section
*/
public func objectsInSection(_ section: Int) -> [T] {
return (self.sectionInfoAtIndex(section).objects as! [T]?) ?? []
}
/**
Returns all objects in the specified section, or `nil` if out of bounds.
- parameter section: the section index. Using an index outside the valid range will return `nil`.
- returns: all objects in the specified section
*/
public func objectsInSection(safeSectionIndex section: Int) -> [T]? {
return self.sectionInfoAtIndex(safeSectionIndex: section)?.objects as! [T]?
}
}
// MARK: - ListMonitor where T: CoreStoreObject
@available(OSX 10.12, *)
extension ListMonitor where T: CoreStoreObject {
/**
Returns all objects in all sections
- returns: all objects in all sections
*/
public func objectsInAllSections() -> [T] {
CoreStore.assert(
!self.isPendingRefetch || Thread.isMainThread,
"Attempted to access a \(cs_typeName(self)) outside the main thread while a refetch is in progress."
)
return (self.fetchedResultsController.fetchedObjects ?? [])
.map(T.cs_fromRaw)
}
/**
Returns all objects in the specified section
- parameter section: the section index. Using an index outside the valid range will raise an exception.
- returns: all objects in the specified section
*/
public func objectsInSection(_ section: Int) -> [T] {
return (self.sectionInfoAtIndex(section).objects ?? [])
.map({ T.cs_fromRaw(object: $0 as! NSManagedObject) })
}
/**
Returns all objects in the specified section, or `nil` if out of bounds.
- parameter section: the section index. Using an index outside the valid range will return `nil`.
- returns: all objects in the specified section
*/
public func objectsInSection(safeSectionIndex section: Int) -> [T]? {
return (self.sectionInfoAtIndex(safeSectionIndex: section)?.objects)?
.map({ T.cs_fromRaw(object: $0 as! NSManagedObject) })
}
}
// MARK: - ListMonitor: FetchedResultsControllerHandler
@available(OSX 10.12, *)
extension ListMonitor: FetchedResultsControllerHandler {
// MARK: FetchedResultsControllerHandler
@@ -1259,7 +1322,8 @@ extension ListMonitor: FetchedResultsControllerHandler {
// MARK: - Notification Keys
@available(OSX 10.12, *)
fileprivate extension Notification.Name {
fileprivate static let listMonitorWillChangeList = Notification.Name(rawValue: "listMonitorWillChangeList")
@@ -1273,5 +1337,3 @@ fileprivate extension Notification.Name {
fileprivate static let listMonitorDidInsertSection = Notification.Name(rawValue: "listMonitorDidInsertSection")
fileprivate static let listMonitorDidDeleteSection = Notification.Name(rawValue: "listMonitorDidDeleteSection")
}
#endif

View File

@@ -27,8 +27,6 @@ import Foundation
import CoreData
#if os(iOS) || os(watchOS) || os(tvOS)
// MARK: - ListObserver
/**
@@ -41,12 +39,13 @@ import CoreData
monitor.addObserver(self)
```
*/
@available(OSX 10.12, *)
public protocol ListObserver: class {
/**
The `NSManagedObject` type for the observed list
*/
associatedtype ListEntityType: NSManagedObject
associatedtype ListEntityType: DynamicObject
/**
Handles processing just before a change to the observed list occurs. (Optional)
@@ -85,6 +84,7 @@ public protocol ListObserver: class {
// MARK: - ListObserver (Default Implementations)
@available(OSX 10.12, *)
public extension ListObserver {
public func listMonitorWillChange(_ monitor: ListMonitor<ListEntityType>) { }
@@ -109,6 +109,7 @@ public extension ListObserver {
monitor.addObserver(self)
```
*/
@available(OSX 10.12, *)
public protocol ListObjectObserver: ListObserver {
/**
@@ -156,6 +157,7 @@ public protocol ListObjectObserver: ListObserver {
// MARK: - ListObjectObserver (Default Implementations)
@available(OSX 10.12, *)
public extension ListObjectObserver {
public func listMonitor(_ monitor: ListMonitor<ListEntityType>, didInsertObject object: ListEntityType, toIndexPath indexPath: IndexPath) { }
@@ -181,6 +183,7 @@ public extension ListObjectObserver {
monitor.addObserver(self)
```
*/
@available(OSX 10.12, *)
public protocol ListSectionObserver: ListObjectObserver {
/**
@@ -207,11 +210,10 @@ public protocol ListSectionObserver: ListObjectObserver {
// MARK: - ListSectionObserver (Default Implementations)
@available(OSX 10.12, *)
public extension ListSectionObserver {
public func listMonitor(_ monitor: ListMonitor<ListEntityType>, didInsertSection sectionInfo: NSFetchedResultsSectionInfo, toSectionIndex sectionIndex: Int) { }
public func listMonitor(_ monitor: ListMonitor<ListEntityType>, didDeleteSection sectionInfo: NSFetchedResultsSectionInfo, fromSectionIndex sectionIndex: Int) { }
}
#endif

View File

@@ -27,8 +27,6 @@ import Foundation
import CoreData
#if os(iOS) || os(watchOS) || os(tvOS)
// MARK: - ObjectMonitor
/**
@@ -41,14 +39,18 @@ import CoreData
Observers registered via `addObserver(_:)` are not retained. `ObjectMonitor` only keeps a `weak` reference to all observers, thus keeping itself free from retain-cycles.
*/
public final class ObjectMonitor<EntityType: NSManagedObject>: Equatable {
@available(OSX 10.12, *)
public final class ObjectMonitor<EntityType: DynamicObject>: Equatable {
/**
Returns the `NSManagedObject` instance being observed, or `nil` if the object was already deleted.
*/
public var object: EntityType? {
return self.fetchedResultsController.fetchedObjects?.first as? EntityType
return self.fetchedResultsController
.fetchedObjects?
.first
.flatMap({ EntityType.cs_fromRaw(object: $0) })
}
/**
@@ -56,7 +58,7 @@ public final class ObjectMonitor<EntityType: NSManagedObject>: Equatable {
*/
public var isObjectDeleted: Bool {
return self.object?.managedObjectContext == nil
return self.object?.cs_toRaw().managedObjectContext == nil
}
/**
@@ -105,22 +107,22 @@ public final class ObjectMonitor<EntityType: NSManagedObject>: Equatable {
// MARK: Equatable
public static func == <T: NSManagedObject>(lhs: ObjectMonitor<T>, rhs: ObjectMonitor<T>) -> Bool {
public static func == <T: DynamicObject>(lhs: ObjectMonitor<T>, rhs: ObjectMonitor<T>) -> Bool {
return lhs === rhs
}
public static func == <T: NSManagedObject, U: NSManagedObject>(lhs: ObjectMonitor<T>, rhs: ObjectMonitor<U>) -> Bool {
public static func == <T: DynamicObject, U: NSManagedObject>(lhs: ObjectMonitor<T>, rhs: ObjectMonitor<U>) -> Bool {
return lhs.fetchedResultsController === rhs.fetchedResultsController
}
public static func ~= <T: NSManagedObject>(lhs: ObjectMonitor<T>, rhs: ObjectMonitor<T>) -> Bool {
public static func ~= <T: DynamicObject>(lhs: ObjectMonitor<T>, rhs: ObjectMonitor<T>) -> Bool {
return lhs === rhs
}
public static func ~= <T: NSManagedObject, U: NSManagedObject>(lhs: ObjectMonitor<T>, rhs: ObjectMonitor<U>) -> Bool {
public static func ~= <T: DynamicObject, U: DynamicObject>(lhs: ObjectMonitor<T>, rhs: ObjectMonitor<U>) -> Bool {
return lhs.fetchedResultsController === rhs.fetchedResultsController
}
@@ -190,7 +192,7 @@ public final class ObjectMonitor<EntityType: NSManagedObject>: Equatable {
}
let previousCommitedAttributes = self.lastCommittedAttributes
let currentCommitedAttributes = object.committedValues(forKeys: nil) as! [String: NSObject]
let currentCommitedAttributes = object.cs_toRaw().committedValues(forKeys: nil) as! [String: NSObject]
var changedKeys = Set<String>()
for key in currentCommitedAttributes.keys {
@@ -220,16 +222,6 @@ public final class ObjectMonitor<EntityType: NSManagedObject>: Equatable {
cs_setAssociatedRetainedObject(nilValue, forKey: &self.didUpdateObjectKey, inObject: observer)
}
internal func downcast() -> ObjectMonitor<NSManagedObject> {
@inline(__always)
func noWarnUnsafeBitCast<T, U>(_ x: T, to type: U.Type) -> U {
return unsafeBitCast(x, to: type)
}
return noWarnUnsafeBitCast(self, to: ObjectMonitor<NSManagedObject>.self)
}
deinit {
self.fetchedResultsControllerDelegate.fetchedResultsController = nil
@@ -239,7 +231,7 @@ public final class ObjectMonitor<EntityType: NSManagedObject>: Equatable {
// MARK: Private
private let fetchedResultsController: CoreStoreFetchedResultsController
private let fetchedResultsControllerDelegate: FetchedResultsControllerDelegate<EntityType>
private let fetchedResultsControllerDelegate: FetchedResultsControllerDelegate
private var lastCommittedAttributes = [String: NSObject]()
private var willChangeObjectKey: Void?
@@ -248,22 +240,24 @@ public final class ObjectMonitor<EntityType: NSManagedObject>: Equatable {
private init(context: NSManagedObjectContext, object: EntityType) {
let rawObject = object.cs_toRaw()
let fetchRequest = CoreStoreFetchRequest()
fetchRequest.entity = object.entity
fetchRequest.entity = rawObject.entity
fetchRequest.fetchLimit = 0
fetchRequest.resultType = .managedObjectResultType
fetchRequest.sortDescriptors = []
fetchRequest.includesPendingChanges = false
fetchRequest.shouldRefreshRefetchedObjects = true
let objectID = object.objectID
let objectID = rawObject.objectID
let fetchedResultsController = CoreStoreFetchedResultsController(
context: context,
fetchRequest: fetchRequest.dynamicCast(),
from: nil as From<EntityType>?,
applyFetchClauses: Where("SELF", isEqualTo: objectID).applyToFetchRequest
)
let fetchedResultsControllerDelegate = FetchedResultsControllerDelegate<EntityType>()
let fetchedResultsControllerDelegate = FetchedResultsControllerDelegate()
self.fetchedResultsController = fetchedResultsController
self.fetchedResultsControllerDelegate = fetchedResultsControllerDelegate
@@ -272,7 +266,7 @@ public final class ObjectMonitor<EntityType: NSManagedObject>: Equatable {
fetchedResultsControllerDelegate.fetchedResultsController = fetchedResultsController
try! fetchedResultsController.performFetchFromSpecifiedStores()
self.lastCommittedAttributes = (self.object?.committedValues(forKeys: nil) as? [String: NSObject]) ?? [:]
self.lastCommittedAttributes = (self.object?.cs_toRaw().committedValues(forKeys: nil) as? [String: NSObject]) ?? [:]
}
private func registerChangeNotification(_ notificationKey: UnsafeRawPointer, name: Notification.Name, toObserver observer: AnyObject, callback: @escaping (_ monitor: ObjectMonitor<EntityType>) -> Void) {
@@ -281,7 +275,7 @@ public final class ObjectMonitor<EntityType: NSManagedObject>: Equatable {
NotificationObserver(
notificationName: name,
object: self,
closure: { [weak self] (note) -> Void in
closure: { [weak self] _ in
guard let `self` = self else {
@@ -301,15 +295,15 @@ public final class ObjectMonitor<EntityType: NSManagedObject>: Equatable {
NotificationObserver(
notificationName: name,
object: self,
closure: { [weak self] (note) -> Void in
closure: { [weak self] (note) in
guard let `self` = self,
let userInfo = note.userInfo,
let object = userInfo[String(describing: NSManagedObject.self)] as? EntityType else {
let object = userInfo[String(describing: NSManagedObject.self)] as! NSManagedObject? else {
return
}
callback(self, object)
callback(self, EntityType.cs_fromRaw(object: object))
}
),
forKey: notificationKey,
@@ -321,6 +315,7 @@ public final class ObjectMonitor<EntityType: NSManagedObject>: Equatable {
// MARK: - ObjectMonitor: FetchedResultsControllerHandler
@available(OSX 10.12, *)
extension ObjectMonitor: FetchedResultsControllerHandler {
// MARK: FetchedResultsControllerHandler
@@ -370,11 +365,10 @@ extension ObjectMonitor: FetchedResultsControllerHandler {
// MARK: - Notification.Name
@available(OSX 10.12, *)
fileprivate extension Notification.Name {
fileprivate static let objectMonitorWillChangeObject = Notification.Name(rawValue: "objectMonitorWillChangeObject")
fileprivate static let objectMonitorDidDeleteObject = Notification.Name(rawValue: "objectMonitorDidDeleteObject")
fileprivate static let objectMonitorDidUpdateObject = Notification.Name(rawValue: "objectMonitorDidUpdateObject")
}
#endif

View File

@@ -27,8 +27,6 @@ import Foundation
import CoreData
#if os(iOS) || os(watchOS) || os(tvOS)
// MARK: - ObjectObserver
/**
@@ -38,12 +36,13 @@ import CoreData
monitor.addObserver(self)
```
*/
@available(OSX 10.12, *)
public protocol ObjectObserver: class {
/**
The `NSManagedObject` type for the observed object
*/
associatedtype ObjectEntityType: NSManagedObject
associatedtype ObjectEntityType: DynamicObject
/**
Handles processing just before a change to the observed `object` occurs. (Optional)
@@ -77,6 +76,7 @@ public protocol ObjectObserver: class {
// MARK: - ObjectObserver (Default Implementations)
@available(OSX 10.12, *)
public extension ObjectObserver {
public func objectMonitor(_ monitor: ObjectMonitor<ObjectEntityType>, willUpdateObject object: ObjectEntityType) { }
@@ -85,5 +85,3 @@ public extension ObjectObserver {
public func objectMonitor(_ monitor: ObjectMonitor<ObjectEntityType>, didDeleteObject object: ObjectEntityType) { }
}
#endif

View File

@@ -27,8 +27,6 @@ import Foundation
import CoreData
#if os(iOS) || os(watchOS) || os(tvOS)
// MARK: - SectionBy
/**
@@ -41,6 +39,7 @@ import CoreData
)
```
*/
@available(OSX 10.12, *)
public struct SectionBy {
/**
@@ -72,5 +71,3 @@ public struct SectionBy {
internal let sectionKeyPath: KeyPath
internal let sectionIndexTransformer: (_ sectionName: String?) -> String?
}
#endif

View File

@@ -27,10 +27,9 @@ import Foundation
import CoreData
#if os(iOS) || os(watchOS) || os(tvOS)
// MARK: - UnsafeDataTransaction
@available(OSX 10.12, *)
public extension UnsafeDataTransaction {
/**
@@ -201,5 +200,3 @@ public extension UnsafeDataTransaction {
)
}
}
#endif