mirror of
https://github.com/JohnEstropia/CoreStore.git
synced 2026-03-19 07:54:26 +01:00
remov stateIDs
This commit is contained in:
@@ -29,11 +29,10 @@ import CoreData
|
||||
|
||||
// MARK: - AttributeProtocol
|
||||
|
||||
internal protocol AttributeProtocol: AnyObject {
|
||||
internal protocol AttributeProtocol: PropertyProtocol {
|
||||
|
||||
static var attributeType: NSAttributeType { get }
|
||||
|
||||
var keyPath: KeyPathString { get }
|
||||
var isOptional: Bool { get }
|
||||
var isTransient: Bool { get }
|
||||
var allowsExternalBinaryDataStorage: Bool { get }
|
||||
|
||||
@@ -13,7 +13,7 @@ import Combine
|
||||
|
||||
// MARK: - LiveList: ObservableObject
|
||||
|
||||
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 15.0, *)
|
||||
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *)
|
||||
extension CoreStoreObject: ObservableObject {
|
||||
|
||||
// MARK: ObservableObject
|
||||
|
||||
@@ -116,6 +116,27 @@ open /*abstract*/ class CoreStoreObject: DynamicObject, Hashable {
|
||||
|
||||
internal let rawObject: CoreStoreManagedObject?
|
||||
internal let isMeta: Bool
|
||||
|
||||
internal class func metaProperties(includeSuperclasses: Bool) -> [PropertyProtocol] {
|
||||
|
||||
func keyPaths(_ allKeyPaths: inout [PropertyProtocol], for dynamicType: CoreStoreObject.Type) {
|
||||
|
||||
allKeyPaths.append(contentsOf: dynamicType.meta.propertyProtocolsByName())
|
||||
guard
|
||||
includeSuperclasses,
|
||||
case let superType as CoreStoreObject.Type = (dynamicType as AnyClass).superclass(),
|
||||
superType != CoreStoreObject.self
|
||||
else {
|
||||
|
||||
return
|
||||
}
|
||||
keyPaths(&allKeyPaths, for: superType)
|
||||
}
|
||||
|
||||
var allKeyPaths: [PropertyProtocol] = []
|
||||
keyPaths(&allKeyPaths, for: self)
|
||||
return allKeyPaths
|
||||
}
|
||||
|
||||
|
||||
// MARK: Private
|
||||
@@ -144,6 +165,22 @@ open /*abstract*/ class CoreStoreObject: DynamicObject, Hashable {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func propertyProtocolsByName() -> [PropertyProtocol] {
|
||||
|
||||
Internals.assert(self.isMeta, "'propertyProtocolsByName()' accessed from non-meta instance of \(Internals.typeName(self))")
|
||||
|
||||
let cacheKey = ObjectIdentifier(Self.self)
|
||||
if let properties = Static.propertiesCache[cacheKey] {
|
||||
|
||||
return properties
|
||||
}
|
||||
let values: [PropertyProtocol] = Mirror(reflecting: self)
|
||||
.children
|
||||
.compactMap({ $0.value as? PropertyProtocol })
|
||||
Static.propertiesCache[cacheKey] = values
|
||||
return values
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -187,4 +224,5 @@ fileprivate enum Static {
|
||||
// MARK: FilePrivate
|
||||
|
||||
fileprivate static var metaCache: [ObjectIdentifier: Any] = [:]
|
||||
fileprivate static var propertiesCache: [ObjectIdentifier: [PropertyProtocol]] = [:]
|
||||
}
|
||||
|
||||
@@ -283,9 +283,9 @@ public final class CoreStoreSchema: DynamicSchema {
|
||||
func createProperties(for type: CoreStoreObject.Type) -> [NSPropertyDescription] {
|
||||
|
||||
var propertyDescriptions: [NSPropertyDescription] = []
|
||||
for child in Mirror(reflecting: type.meta).children {
|
||||
for property in type.metaProperties(includeSuperclasses: false) {
|
||||
|
||||
switch child.value {
|
||||
switch property {
|
||||
|
||||
case let attribute as AttributeProtocol:
|
||||
Internals.assert(
|
||||
@@ -378,9 +378,10 @@ public final class CoreStoreSchema: DynamicSchema {
|
||||
for (entity, entityDescription) in entityDescriptionsByEntity {
|
||||
|
||||
let relationshipsByName = relationshipsByNameByEntity[entity]!
|
||||
for child in Mirror(reflecting: (entity.type as! CoreStoreObject.Type).meta).children {
|
||||
let entityType = entity.type as! CoreStoreObject.Type
|
||||
for property in entityType.metaProperties(includeSuperclasses: false) {
|
||||
|
||||
switch child.value {
|
||||
switch property {
|
||||
|
||||
case let relationship as RelationshipProtocol:
|
||||
let (destinationType, destinationKeyPath) = relationship.inverse
|
||||
|
||||
@@ -31,7 +31,7 @@ import CoreData
|
||||
|
||||
// MARK: - DataStack
|
||||
|
||||
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 15.0, *)
|
||||
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *)
|
||||
extension DataStack {
|
||||
|
||||
public func liveList<D>(_ from: From<D>, _ fetchClauses: FetchClause...) -> LiveList<D> {
|
||||
|
||||
@@ -48,7 +48,7 @@ import CoreData
|
||||
// self.tableView = tableView
|
||||
// self.cellProvider = cellProvider
|
||||
//
|
||||
// if #available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 15.0, *) {
|
||||
// if #available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *) {
|
||||
//
|
||||
// self.rawDataSource = UITableViewDiffableDataSource<String, D.ObjectID>(
|
||||
// tableView: tableView,
|
||||
@@ -71,7 +71,7 @@ import CoreData
|
||||
// public func apply(_ snapshot: ListSnapshot<ObjectType>, animatingDifferences: Bool = true) {
|
||||
//
|
||||
// let dataSource = UITableViewDiffableDataSource<String, D>.
|
||||
// if #available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 15.0, *) {
|
||||
// if #available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *) {
|
||||
//
|
||||
// self.rawDataSource! as! UITableViewDiffableDataSource<String, D>
|
||||
//
|
||||
@@ -95,7 +95,7 @@ import CoreData
|
||||
// private let cellProvider: (UITableView, IndexPath, ObjectType) -> UITableViewCell?
|
||||
// private let rawDataSource: Any?
|
||||
//
|
||||
// @available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 15.0, *)
|
||||
// @available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *)
|
||||
// private var diffableDataSource: UITableViewDiffableDataSource<String, D.ObjectID> {
|
||||
//
|
||||
// return self.rawDataSource! as! UITableViewDiffableDataSource<String, D.ObjectID>
|
||||
|
||||
34
Sources/DiffableDataSourceSnapshotProtocol.swift
Normal file
34
Sources/DiffableDataSourceSnapshotProtocol.swift
Normal file
@@ -0,0 +1,34 @@
|
||||
//
|
||||
// DiffableDataSourceSnapshotProtocol.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright © 2018 John Rommel Estropia
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import CoreData
|
||||
|
||||
|
||||
// MARK: - DiffableDataSourceSnapshotProtocol
|
||||
|
||||
internal protocol DiffableDataSourceSnapshotProtocol {
|
||||
|
||||
}
|
||||
@@ -74,10 +74,10 @@ extension DynamicObject {
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
internal static func keyPathBuilder() -> DynamicObjectMeta<Never, Self> {
|
||||
|
||||
return .init(keyPathString: "SELF")
|
||||
}
|
||||
// internal static func keyPathBuilder() -> DynamicObjectMeta<Never, Self> {
|
||||
//
|
||||
// return .init(keyPathString: "SELF")
|
||||
// }
|
||||
|
||||
internal func runtimeType() -> Self.Type {
|
||||
|
||||
|
||||
@@ -2,8 +2,25 @@
|
||||
// EnvironmentKeys.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Created by John Rommel Estropia on 2019/10/05.
|
||||
// Copyright © 2019 John Rommel Estropia. All rights reserved.
|
||||
// Copyright © 2018 John Rommel Estropia
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
|
||||
#if canImport(SwiftUI)
|
||||
@@ -13,7 +30,7 @@ import SwiftUI
|
||||
|
||||
// MARK: - DataStackEnvironmentKey
|
||||
|
||||
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 15.0, *)
|
||||
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *)
|
||||
public struct DataStackEnvironmentKey: EnvironmentKey {
|
||||
|
||||
// MARK: Public
|
||||
@@ -27,7 +44,7 @@ public struct DataStackEnvironmentKey: EnvironmentKey {
|
||||
|
||||
// MARK: - EnvironmentValues
|
||||
|
||||
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 15.0, *)
|
||||
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *)
|
||||
extension EnvironmentValues {
|
||||
|
||||
// MARK: Public
|
||||
|
||||
@@ -48,18 +48,14 @@ extension Internals {
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
internal let nextStateTag: UUID
|
||||
|
||||
init() {
|
||||
|
||||
self.structure = .init()
|
||||
self.nextStateTag = .init()
|
||||
}
|
||||
|
||||
init(sections: [NSFetchedResultsSectionInfo], previousStateTag: UUID, nextStateTag: UUID) {
|
||||
init(sections: [NSFetchedResultsSectionInfo]) {
|
||||
|
||||
self.structure = .init(sections: sections, previousStateTag: previousStateTag)
|
||||
self.nextStateTag = nextStateTag
|
||||
self.structure = .init(sections: sections)
|
||||
}
|
||||
|
||||
var numberOfItems: Int {
|
||||
@@ -77,21 +73,11 @@ extension Internals {
|
||||
return self.structure.allSectionIDs
|
||||
}
|
||||
|
||||
var allSectionStateIDs: [SectionStateID] {
|
||||
|
||||
return self.structure.allSectionStateIDs
|
||||
}
|
||||
|
||||
var allItemIDs: [NSManagedObjectID] {
|
||||
|
||||
return self.structure.allItemIDs
|
||||
}
|
||||
|
||||
var allItemStateIDs: [ItemStateID] {
|
||||
|
||||
return self.structure.allItemStateIDs
|
||||
}
|
||||
|
||||
func numberOfItems(inSection identifier: String) -> Int {
|
||||
|
||||
return self.itemIDs(inSection: identifier).count
|
||||
@@ -102,21 +88,11 @@ extension Internals {
|
||||
return self.structure.items(in: identifier)
|
||||
}
|
||||
|
||||
func itemStateIDs(inSection identifier: String) -> [ItemStateID] {
|
||||
|
||||
return self.structure.itemStateIDs(in: identifier)
|
||||
}
|
||||
|
||||
func sectionIDs(containingItem identifier: NSManagedObjectID) -> String? {
|
||||
|
||||
return self.structure.section(containing: identifier)
|
||||
}
|
||||
|
||||
func sectionStateIDs(containingItem identifier: NSManagedObjectID) -> SectionStateID? {
|
||||
|
||||
return self.structure.sectionStateID(containing: identifier)
|
||||
}
|
||||
|
||||
func indexOfItemID(_ identifier: NSManagedObjectID) -> Int? {
|
||||
|
||||
return self.structure.allItemIDs.firstIndex(of: identifier)
|
||||
@@ -127,24 +103,19 @@ extension Internals {
|
||||
return self.structure.allSectionIDs.firstIndex(of: identifier)
|
||||
}
|
||||
|
||||
func itemIDs(where stateCondition: @escaping (UUID) -> Bool) -> [NSManagedObjectID] {
|
||||
mutating func appendItems(_ identifiers: [NSManagedObjectID], toSection sectionIdentifier: String?) {
|
||||
|
||||
return self.structure.itemsIDs(where: stateCondition)
|
||||
self.structure.append(itemIDs: identifiers, to: sectionIdentifier)
|
||||
}
|
||||
|
||||
mutating func appendItems(_ identifiers: [NSManagedObjectID], toSection sectionIdentifier: String?, nextStateTag: UUID) {
|
||||
mutating func insertItems(_ identifiers: [NSManagedObjectID], beforeItem beforeIdentifier: NSManagedObjectID) {
|
||||
|
||||
self.structure.append(itemIDs: identifiers, to: sectionIdentifier, nextStateTag: nextStateTag)
|
||||
self.structure.insert(itemIDs: identifiers, before: beforeIdentifier)
|
||||
}
|
||||
|
||||
mutating func insertItems(_ identifiers: [NSManagedObjectID], beforeItem beforeIdentifier: NSManagedObjectID, nextStateTag: UUID) {
|
||||
mutating func insertItems(_ identifiers: [NSManagedObjectID], afterItem afterIdentifier: NSManagedObjectID) {
|
||||
|
||||
self.structure.insert(itemIDs: identifiers, before: beforeIdentifier, nextStateTag: nextStateTag)
|
||||
}
|
||||
|
||||
mutating func insertItems(_ identifiers: [NSManagedObjectID], afterItem afterIdentifier: NSManagedObjectID, nextStateTag: UUID) {
|
||||
|
||||
self.structure.insert(itemIDs: identifiers, after: afterIdentifier, nextStateTag: nextStateTag)
|
||||
self.structure.insert(itemIDs: identifiers, after: afterIdentifier)
|
||||
}
|
||||
|
||||
mutating func deleteItems(_ identifiers: [NSManagedObjectID]) {
|
||||
@@ -172,19 +143,19 @@ extension Internals {
|
||||
self.structure.update(itemIDs: identifiers, nextStateTag: nextStateTag)
|
||||
}
|
||||
|
||||
mutating func appendSections(_ identifiers: [String], nextStateTag: UUID) {
|
||||
mutating func appendSections(_ identifiers: [String]) {
|
||||
|
||||
self.structure.append(sectionIDs: identifiers, nextStateTag: nextStateTag)
|
||||
self.structure.append(sectionIDs: identifiers)
|
||||
}
|
||||
|
||||
mutating func insertSections(_ identifiers: [String], beforeSection toIdentifier: String, nextStateTag: UUID) {
|
||||
mutating func insertSections(_ identifiers: [String], beforeSection toIdentifier: String) {
|
||||
|
||||
self.structure.insert(sectionIDs: identifiers, before: toIdentifier, nextStateTag: nextStateTag)
|
||||
self.structure.insert(sectionIDs: identifiers, before: toIdentifier)
|
||||
}
|
||||
|
||||
mutating func insertSections(_ identifiers: [String], afterSection toIdentifier: String, nextStateTag: UUID) {
|
||||
mutating func insertSections(_ identifiers: [String], afterSection toIdentifier: String) {
|
||||
|
||||
self.structure.insert(sectionIDs: identifiers, after: toIdentifier, nextStateTag: nextStateTag)
|
||||
self.structure.insert(sectionIDs: identifiers, after: toIdentifier)
|
||||
}
|
||||
|
||||
mutating func deleteSections(_ identifiers: [String]) {
|
||||
@@ -271,7 +242,7 @@ extension Internals {
|
||||
self.sections = []
|
||||
}
|
||||
|
||||
init(sections: [NSFetchedResultsSectionInfo], previousStateTag: UUID) {
|
||||
init(sections: [NSFetchedResultsSectionInfo]) {
|
||||
|
||||
self.sections = sections.map {
|
||||
|
||||
@@ -279,8 +250,7 @@ extension Internals {
|
||||
id: $0.name,
|
||||
items: $0.objects?
|
||||
.compactMap({ ($0 as? NSManagedObject)?.objectID })
|
||||
.map({ Item(id: $0, stateTag: previousStateTag) }) ?? [],
|
||||
stateTag: previousStateTag
|
||||
.map({ Item(id: $0) }) ?? []
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -290,21 +260,11 @@ extension Internals {
|
||||
return self.sections.map({ $0.id })
|
||||
}
|
||||
|
||||
var allSectionStateIDs: [SectionStateID] {
|
||||
|
||||
return self.sections.map({ $0.stateID })
|
||||
}
|
||||
|
||||
var allItemIDs: [NSManagedObjectID] {
|
||||
|
||||
return self.sections.lazy.flatMap({ $0.elements }).map({ $0.id })
|
||||
}
|
||||
|
||||
var allItemStateIDs: [ItemStateID] {
|
||||
|
||||
return self.sections.lazy.flatMap({ $0.elements }).map({ $0.stateID })
|
||||
}
|
||||
|
||||
func items(in sectionID: String) -> [NSManagedObjectID] {
|
||||
|
||||
guard let sectionIndex = self.sectionIndex(of: sectionID) else {
|
||||
@@ -314,33 +274,12 @@ extension Internals {
|
||||
return self.sections[sectionIndex].elements.map({ $0.id })
|
||||
}
|
||||
|
||||
func itemsIDs(where stateCondition: @escaping (UUID) -> Bool) -> [NSManagedObjectID] {
|
||||
|
||||
return self.sections.lazy
|
||||
.flatMap({ $0.elements.filter({ stateCondition($0.stateTag) }) })
|
||||
.map({ $0.id })
|
||||
}
|
||||
|
||||
func itemStateIDs(in sectionID: String) -> [ItemStateID] {
|
||||
|
||||
guard let sectionIndex = self.sectionIndex(of: sectionID) else {
|
||||
|
||||
Internals.abort("Section \"\(sectionID)\" does not exist")
|
||||
}
|
||||
return self.sections[sectionIndex].elements.map({ $0.stateID })
|
||||
}
|
||||
|
||||
func section(containing itemID: NSManagedObjectID) -> String? {
|
||||
|
||||
return self.itemPositionMap()[itemID]?.section.id
|
||||
}
|
||||
|
||||
func sectionStateID(containing itemID: NSManagedObjectID) -> SectionStateID? {
|
||||
|
||||
return self.itemPositionMap()[itemID]?.section.stateID
|
||||
}
|
||||
|
||||
mutating func append(itemIDs: [NSManagedObjectID], to sectionID: String?, nextStateTag: UUID) {
|
||||
mutating func append(itemIDs: [NSManagedObjectID], to sectionID: String?) {
|
||||
|
||||
let index: Array<Section>.Index
|
||||
if let sectionID = sectionID {
|
||||
@@ -360,22 +299,22 @@ extension Internals {
|
||||
}
|
||||
index = section.index(before: section.endIndex)
|
||||
}
|
||||
let items = itemIDs.lazy.map({ Item(id: $0, stateTag: nextStateTag) })
|
||||
let items = itemIDs.lazy.map({ Item(id: $0) })
|
||||
self.sections[index].elements.append(contentsOf: items)
|
||||
}
|
||||
|
||||
mutating func insert(itemIDs: [NSManagedObjectID], before beforeItemID: NSManagedObjectID, nextStateTag: UUID) {
|
||||
mutating func insert(itemIDs: [NSManagedObjectID], before beforeItemID: NSManagedObjectID) {
|
||||
|
||||
guard let itemPosition = self.itemPositionMap()[beforeItemID] else {
|
||||
|
||||
Internals.abort("Item \(beforeItemID) does not exist")
|
||||
}
|
||||
let items = itemIDs.lazy.map({ Item(id: $0, stateTag: nextStateTag) })
|
||||
let items = itemIDs.lazy.map({ Item(id: $0) })
|
||||
self.sections[itemPosition.sectionIndex].elements
|
||||
.insert(contentsOf: items, at: itemPosition.itemRelativeIndex)
|
||||
}
|
||||
|
||||
mutating func insert(itemIDs: [NSManagedObjectID], after afterItemID: NSManagedObjectID, nextStateTag: UUID) {
|
||||
mutating func insert(itemIDs: [NSManagedObjectID], after afterItemID: NSManagedObjectID) {
|
||||
|
||||
guard let itemPosition = self.itemPositionMap()[afterItemID] else {
|
||||
|
||||
@@ -383,7 +322,7 @@ extension Internals {
|
||||
}
|
||||
let itemIndex = self.sections[itemPosition.sectionIndex].elements
|
||||
.index(after: itemPosition.itemRelativeIndex)
|
||||
let items = itemIDs.lazy.map({ Item(id: $0, stateTag: nextStateTag) })
|
||||
let items = itemIDs.lazy.map({ Item(id: $0) })
|
||||
self.sections[itemPosition.sectionIndex].elements
|
||||
.insert(contentsOf: items, at: itemIndex)
|
||||
}
|
||||
@@ -459,34 +398,34 @@ extension Internals {
|
||||
continue
|
||||
}
|
||||
self.sections[itemPosition.sectionIndex]
|
||||
.elements[itemPosition.itemRelativeIndex].stateTag = nextStateTag
|
||||
.elements[itemPosition.itemRelativeIndex].isReloaded = true
|
||||
}
|
||||
}
|
||||
|
||||
mutating func append(sectionIDs: [String], nextStateTag: UUID) {
|
||||
mutating func append(sectionIDs: [String]) {
|
||||
|
||||
let newSections = sectionIDs.lazy.map({ Section(id: $0, stateTag: nextStateTag) })
|
||||
let newSections = sectionIDs.lazy.map({ Section(id: $0) })
|
||||
self.sections.append(contentsOf: newSections)
|
||||
}
|
||||
|
||||
mutating func insert(sectionIDs: [String], before beforeSectionID: String, nextStateTag: UUID) {
|
||||
mutating func insert(sectionIDs: [String], before beforeSectionID: String) {
|
||||
|
||||
guard let sectionIndex = self.sectionIndex(of: beforeSectionID) else {
|
||||
|
||||
Internals.abort("Section \"\(beforeSectionID)\" does not exist")
|
||||
}
|
||||
let newSections = sectionIDs.lazy.map({ Section(id: $0, stateTag: nextStateTag) })
|
||||
let newSections = sectionIDs.lazy.map({ Section(id: $0) })
|
||||
self.sections.insert(contentsOf: newSections, at: sectionIndex)
|
||||
}
|
||||
|
||||
mutating func insert(sectionIDs: [String], after afterSectionID: String, nextStateTag: UUID) {
|
||||
mutating func insert(sectionIDs: [String], after afterSectionID: String) {
|
||||
|
||||
guard let beforeIndex = self.sectionIndex(of: afterSectionID) else {
|
||||
|
||||
Internals.abort("Section \"\(afterSectionID)\" does not exist")
|
||||
}
|
||||
let sectionIndex = self.sections.index(after: beforeIndex)
|
||||
let newSections = sectionIDs.lazy.map({ Section(id: $0, stateTag: nextStateTag) })
|
||||
let newSections = sectionIDs.lazy.map({ Section(id: $0) })
|
||||
self.sections.insert(contentsOf: newSections, at: sectionIndex)
|
||||
}
|
||||
|
||||
@@ -533,7 +472,7 @@ extension Internals {
|
||||
|
||||
continue
|
||||
}
|
||||
self.sections[sectionIndex].stateTag = nextStateTag
|
||||
self.sections[sectionIndex].isReloaded = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -589,22 +528,17 @@ extension Internals {
|
||||
|
||||
fileprivate struct Item: Identifiable, Equatable {
|
||||
|
||||
var stateTag: UUID
|
||||
var isReloaded: Bool
|
||||
|
||||
init(id: NSManagedObjectID, stateTag: UUID) {
|
||||
init(id: NSManagedObjectID, isReloaded: Bool = false) {
|
||||
|
||||
self.id = id
|
||||
self.stateTag = stateTag
|
||||
}
|
||||
|
||||
var stateID: ItemStateID {
|
||||
|
||||
return .init(id: self.id, stateTag: self.stateTag)
|
||||
self.isReloaded = isReloaded
|
||||
}
|
||||
|
||||
func isContentEqual(to source: Item) -> Bool {
|
||||
|
||||
return self.id == source.id && self.stateTag == source.stateTag
|
||||
return !self.isReloaded && self.id == source.id
|
||||
}
|
||||
|
||||
// MARK: Identifiable
|
||||
@@ -618,27 +552,22 @@ extension Internals {
|
||||
fileprivate struct Section: Identifiable, Equatable {
|
||||
|
||||
var elements: [Item] = []
|
||||
var stateTag: UUID
|
||||
var isReloaded: Bool
|
||||
|
||||
init(id: String, items: [Item] = [], stateTag: UUID) {
|
||||
init(id: String, items: [Item] = [], isReloaded: Bool = false) {
|
||||
self.id = id
|
||||
self.elements = items
|
||||
self.stateTag = stateTag
|
||||
self.isReloaded = isReloaded
|
||||
}
|
||||
|
||||
init<S: Sequence>(source: Section, elements: S) where S.Element == Item {
|
||||
|
||||
self.init(id: source.id, items: Array(elements), stateTag: source.stateTag)
|
||||
}
|
||||
|
||||
var stateID: SectionStateID {
|
||||
|
||||
return .init(id: self.id, stateTag: self.stateTag)
|
||||
self.init(id: source.id, items: Array(elements), isReloaded: source.isReloaded)
|
||||
}
|
||||
|
||||
func isContentEqual(to source: Section) -> Bool {
|
||||
|
||||
return self.id == source.id && self.stateTag == source.stateTag
|
||||
return !self.isReloaded && self.id == source.id
|
||||
}
|
||||
|
||||
// MARK: Identifiable
|
||||
|
||||
@@ -77,7 +77,7 @@ extension Internals {
|
||||
|
||||
// #if canImport(UIKit) || canImport(AppKit)
|
||||
//
|
||||
// if #available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 15.0, *) {
|
||||
// if #available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *) {
|
||||
//
|
||||
// return
|
||||
// }
|
||||
@@ -96,7 +96,7 @@ extension Internals {
|
||||
|
||||
// #if canImport(UIKit) || canImport(AppKit)
|
||||
//
|
||||
// @available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 15.0, *)
|
||||
// @available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *)
|
||||
// @objc
|
||||
// dynamic func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChangeContentWith snapshot: NSDiffableDataSourceSnapshotReference) {
|
||||
//
|
||||
@@ -111,48 +111,12 @@ extension Internals {
|
||||
@objc
|
||||
dynamic func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
|
||||
|
||||
let nextStateTag: UUID = .init()
|
||||
var dataSourceSnapshot = Internals.DiffableDataSourceSnapshot(
|
||||
sections: controller.sections ?? [],
|
||||
previousStateTag: self.previousStateTag,
|
||||
nextStateTag: nextStateTag
|
||||
)
|
||||
dataSourceSnapshot.reloadItems(self.reloadedItemIDs, nextStateTag: nextStateTag)
|
||||
dataSourceSnapshot.reloadSections(self.reloadedSectionIDs, nextStateTag: nextStateTag)
|
||||
|
||||
self.handler?.controller(
|
||||
controller,
|
||||
didChangContentWith: dataSourceSnapshot
|
||||
didChangContentWith: Internals.DiffableDataSourceSnapshot(
|
||||
sections: controller.sections ?? []
|
||||
)
|
||||
)
|
||||
self.previousStateTag = nextStateTag
|
||||
}
|
||||
|
||||
@objc
|
||||
dynamic func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
|
||||
|
||||
let managedObject = anObject as! NSManagedObject
|
||||
self.reloadedItemIDs.insert(managedObject.objectID)
|
||||
}
|
||||
|
||||
@objc
|
||||
dynamic func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange sectionInfo: NSFetchedResultsSectionInfo, atSectionIndex sectionIndex: Int, for type: NSFetchedResultsChangeType) {
|
||||
|
||||
self.reloadedSectionIDs.insert(sectionInfo.name)
|
||||
}
|
||||
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private var previousStateTag: UUID = .init() {
|
||||
|
||||
didSet {
|
||||
|
||||
self.reloadedItemIDs = []
|
||||
self.reloadedSectionIDs = []
|
||||
}
|
||||
}
|
||||
|
||||
private var reloadedItemIDs: Set<NSManagedObjectID> = []
|
||||
private var reloadedSectionIDs: Set<String> = []
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,17 +128,17 @@ public struct ListSnapshot<O: DynamicObject>: SnapshotResult, RandomAccessCollec
|
||||
|
||||
public mutating func appendItems(_ identifiers: [ItemID], toSection sectionIdentifier: SectionID? = nil) {
|
||||
|
||||
self.diffableSnapshot.appendItems(identifiers, toSection: sectionIdentifier, nextStateTag: .init())
|
||||
self.diffableSnapshot.appendItems(identifiers, toSection: sectionIdentifier)
|
||||
}
|
||||
|
||||
public mutating func insertItems(_ identifiers: [ItemID], beforeItem beforeIdentifier: ItemID) {
|
||||
|
||||
self.diffableSnapshot.insertItems(identifiers, beforeItem: beforeIdentifier, nextStateTag: .init())
|
||||
self.diffableSnapshot.insertItems(identifiers, beforeItem: beforeIdentifier)
|
||||
}
|
||||
|
||||
public mutating func insertItems(_ identifiers: [ItemID], afterItem afterIdentifier: ItemID) {
|
||||
|
||||
self.diffableSnapshot.insertItems(identifiers, afterItem: afterIdentifier, nextStateTag: .init())
|
||||
self.diffableSnapshot.insertItems(identifiers, afterItem: afterIdentifier)
|
||||
}
|
||||
|
||||
public mutating func deleteItems(_ identifiers: [ItemID]) {
|
||||
@@ -168,17 +168,17 @@ public struct ListSnapshot<O: DynamicObject>: SnapshotResult, RandomAccessCollec
|
||||
|
||||
public mutating func appendSections(_ identifiers: [SectionID]) {
|
||||
|
||||
self.diffableSnapshot.appendSections(identifiers, nextStateTag: .init())
|
||||
self.diffableSnapshot.appendSections(identifiers)
|
||||
}
|
||||
|
||||
public mutating func insertSections(_ identifiers: [SectionID], beforeSection toIdentifier: SectionID) {
|
||||
|
||||
self.diffableSnapshot.insertSections(identifiers, beforeSection: toIdentifier, nextStateTag: .init())
|
||||
self.diffableSnapshot.insertSections(identifiers, beforeSection: toIdentifier)
|
||||
}
|
||||
|
||||
public mutating func insertSections(_ identifiers: [SectionID], afterSection toIdentifier: SectionID) {
|
||||
|
||||
self.diffableSnapshot.insertSections(identifiers, afterSection: toIdentifier, nextStateTag: .init())
|
||||
self.diffableSnapshot.insertSections(identifiers, afterSection: toIdentifier)
|
||||
}
|
||||
|
||||
public mutating func deleteSections(_ identifiers: [SectionID]) {
|
||||
@@ -263,16 +263,6 @@ public struct ListSnapshot<O: DynamicObject>: SnapshotResult, RandomAccessCollec
|
||||
self.diffableSnapshot = diffableSnapshot
|
||||
self.context = context
|
||||
}
|
||||
|
||||
internal var nextStateTag: UUID {
|
||||
|
||||
return self.diffableSnapshot.nextStateTag
|
||||
}
|
||||
|
||||
internal func itemIDs(where stateCondition: @escaping (UUID) -> Bool) -> [ItemID] {
|
||||
|
||||
return self.diffableSnapshot.itemIDs(where: stateCondition)
|
||||
}
|
||||
|
||||
|
||||
// MARK: Private
|
||||
|
||||
@@ -49,10 +49,7 @@ public final class LiveList<O: DynamicObject>: Hashable {
|
||||
|
||||
willSet {
|
||||
|
||||
if #available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 15.0, *) {
|
||||
|
||||
self.willChange()
|
||||
}
|
||||
self.willChange()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -267,7 +264,7 @@ public final class LiveList<O: DynamicObject>: Hashable {
|
||||
applyFetchClauses: applyFetchClauses
|
||||
)
|
||||
|
||||
if #available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 15.0, *) {
|
||||
if #available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *) {
|
||||
|
||||
#if canImport(Combine)
|
||||
self.rawObjectWillChange = ObservableObjectPublisher()
|
||||
@@ -318,20 +315,33 @@ extension LiveList: FetchedDiffableDataSourceSnapshotHandler {
|
||||
#if canImport(Combine)
|
||||
import Combine
|
||||
|
||||
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *)
|
||||
extension LiveList: ObservableObject {}
|
||||
|
||||
#endif
|
||||
|
||||
// MARK: - LiveList: LiveResult
|
||||
|
||||
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 15.0, *)
|
||||
extension LiveList: LiveResult {
|
||||
|
||||
// MARK: ObservableObject
|
||||
|
||||
#if canImport(Combine)
|
||||
|
||||
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *)
|
||||
public var objectWillChange: ObservableObjectPublisher {
|
||||
|
||||
return self.rawObjectWillChange! as! ObservableObjectPublisher
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
public func willChange() {
|
||||
|
||||
guard #available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *) else {
|
||||
|
||||
return
|
||||
}
|
||||
#if canImport(Combine)
|
||||
|
||||
#if canImport(SwiftUI)
|
||||
@@ -340,11 +350,10 @@ extension LiveList: LiveResult {
|
||||
self.objectWillChange.send()
|
||||
}
|
||||
|
||||
#else
|
||||
self.objectWillChange.send()
|
||||
|
||||
#endif
|
||||
|
||||
self.objectWillChange.send()
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -353,5 +362,3 @@ extension LiveList: LiveResult {
|
||||
// TODO:
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -100,7 +100,7 @@ public final class LiveObject<O: DynamicObject>: Identifiable, Hashable {
|
||||
|
||||
self.id = id
|
||||
self.context = context
|
||||
if #available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 15.0, *) {
|
||||
if #available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *) {
|
||||
|
||||
#if canImport(Combine)
|
||||
self.rawObjectWillChange = ObservableObjectPublisher()
|
||||
@@ -132,10 +132,7 @@ public final class LiveObject<O: DynamicObject>: Identifiable, Hashable {
|
||||
return
|
||||
}
|
||||
self.$lazySnapshot.reset({ initializer(id, context) })
|
||||
if #available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 15.0, *) {
|
||||
|
||||
self.willChange()
|
||||
}
|
||||
self.willChange()
|
||||
}
|
||||
)
|
||||
|
||||
@@ -156,20 +153,33 @@ public final class LiveObject<O: DynamicObject>: Identifiable, Hashable {
|
||||
#if canImport(Combine)
|
||||
import Combine
|
||||
|
||||
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *)
|
||||
extension LiveObject: ObservableObject {}
|
||||
|
||||
#endif
|
||||
|
||||
// MARK: - LiveObject: LiveResult
|
||||
|
||||
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 15.0, *)
|
||||
extension LiveObject: LiveResult {
|
||||
|
||||
// MARK: ObservableObject
|
||||
|
||||
#if canImport(Combine)
|
||||
|
||||
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *)
|
||||
public var objectWillChange: ObservableObjectPublisher {
|
||||
|
||||
return self.rawObjectWillChange! as! ObservableObjectPublisher
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
public func willChange() {
|
||||
|
||||
guard #available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *) else {
|
||||
|
||||
return
|
||||
}
|
||||
#if canImport(Combine)
|
||||
|
||||
#if canImport(SwiftUI)
|
||||
@@ -178,11 +188,10 @@ extension LiveObject: LiveResult {
|
||||
self.objectWillChange.send()
|
||||
}
|
||||
|
||||
#else
|
||||
self.objectWillChange.send()
|
||||
|
||||
#endif
|
||||
|
||||
self.objectWillChange.send()
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -192,8 +201,6 @@ extension LiveObject: LiveResult {
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
// MARK: - LiveObject where O: NSManagedObject
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
//
|
||||
//
|
||||
//#warning("TODO: autoupdating doesn't work yet")
|
||||
//@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 15.0, *)
|
||||
//@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *)
|
||||
//@propertyWrapper
|
||||
//public struct LiveQuery<Result: LiveResult>: DynamicProperty {
|
||||
//
|
||||
@@ -143,7 +143,7 @@
|
||||
//
|
||||
//#if canImport(UIKit) || canImport(AppKit)
|
||||
//
|
||||
//@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 15.0, *)
|
||||
//@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *)
|
||||
//extension LiveQuery {
|
||||
//
|
||||
// public init<D: DynamicObject>(liveList: LiveList<D>) where Result == LiveList<D> {
|
||||
|
||||
@@ -36,8 +36,7 @@ import AppKit
|
||||
|
||||
// MARK: - LiveResult
|
||||
|
||||
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 15.0, *)
|
||||
public protocol LiveResult: ObservableObject {
|
||||
public protocol LiveResult: AnyObject {
|
||||
|
||||
associatedtype ObjectType
|
||||
associatedtype SnapshotType: SnapshotResult where SnapshotType.ObjectType == Self.ObjectType
|
||||
|
||||
9
Sources/ObjectRepresentation.swift
Normal file
9
Sources/ObjectRepresentation.swift
Normal file
@@ -0,0 +1,9 @@
|
||||
//
|
||||
// ObjectRepresentation.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Created by John Estropia on 2019/10/11.
|
||||
// Copyright © 2019 John Rommel Estropia. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
35
Sources/PropertyProtocol.swift
Normal file
35
Sources/PropertyProtocol.swift
Normal file
@@ -0,0 +1,35 @@
|
||||
//
|
||||
// PropertyProtocol.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright © 2018 John Rommel Estropia
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import CoreData
|
||||
|
||||
|
||||
// MARK: - PropertyProtocol
|
||||
|
||||
internal protocol PropertyProtocol: AnyObject {
|
||||
|
||||
var keyPath: KeyPathString { get }
|
||||
}
|
||||
@@ -249,11 +249,15 @@ public enum RelationshipContainer<O: CoreStoreObject> {
|
||||
// MARK: RelationshipKeyPathStringConvertible
|
||||
|
||||
public typealias ReturnValueType = DestinationValueType?
|
||||
|
||||
|
||||
// MARK: PropertyProtocol
|
||||
|
||||
internal let keyPath: KeyPathString
|
||||
|
||||
|
||||
// MARK: RelationshipProtocol
|
||||
|
||||
internal let keyPath: KeyPathString
|
||||
|
||||
internal let isToMany = false
|
||||
internal let isOrdered = false
|
||||
internal let deleteRule: NSDeleteRule
|
||||
@@ -540,11 +544,15 @@ public enum RelationshipContainer<O: CoreStoreObject> {
|
||||
// MARK: RelationshipKeyPathStringConvertible
|
||||
|
||||
public typealias ReturnValueType = [DestinationValueType]
|
||||
|
||||
|
||||
// MARK: PropertyProtocol
|
||||
|
||||
internal let keyPath: KeyPathString
|
||||
|
||||
|
||||
// MARK: RelationshipProtocol
|
||||
|
||||
internal let keyPath: KeyPathString
|
||||
|
||||
internal let isToMany = true
|
||||
internal let isOptional = true
|
||||
internal let isOrdered = true
|
||||
@@ -837,11 +845,15 @@ public enum RelationshipContainer<O: CoreStoreObject> {
|
||||
// MARK: RelationshipKeyPathStringConvertible
|
||||
|
||||
public typealias ReturnValueType = Set<DestinationValueType>
|
||||
|
||||
|
||||
// MARK: PropertyProtocol
|
||||
|
||||
internal let keyPath: KeyPathString
|
||||
|
||||
|
||||
// MARK: RelationshipProtocol
|
||||
|
||||
internal let keyPath: KeyPathString
|
||||
internal let isToMany = true
|
||||
internal let isOptional = true
|
||||
internal let isOrdered = false
|
||||
|
||||
@@ -29,9 +29,8 @@ import CoreData
|
||||
|
||||
// MARK: - RelationshipProtocol
|
||||
|
||||
internal protocol RelationshipProtocol: AnyObject {
|
||||
|
||||
var keyPath: KeyPathString { get }
|
||||
internal protocol RelationshipProtocol: PropertyProtocol {
|
||||
|
||||
var isToMany: Bool { get }
|
||||
var isOrdered: Bool { get }
|
||||
var deleteRule: NSDeleteRule { get }
|
||||
|
||||
@@ -36,7 +36,6 @@ import AppKit
|
||||
|
||||
// MARK: - SnapshotResult
|
||||
|
||||
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 15.0, *)
|
||||
public protocol SnapshotResult {
|
||||
|
||||
associatedtype ObjectType: DynamicObject
|
||||
|
||||
@@ -209,6 +209,11 @@ public enum TransformableContainer<O: CoreStoreObject> {
|
||||
public typealias ReturnValueType = DestinationValueType
|
||||
|
||||
|
||||
// MARK: PropertyProtocol
|
||||
|
||||
internal let keyPath: KeyPathString
|
||||
|
||||
|
||||
// MARK: AttributeProtocol
|
||||
|
||||
internal static var attributeType: NSAttributeType {
|
||||
@@ -216,7 +221,6 @@ public enum TransformableContainer<O: CoreStoreObject> {
|
||||
return .transformableAttributeType
|
||||
}
|
||||
|
||||
internal let keyPath: KeyPathString
|
||||
internal let isOptional = false
|
||||
internal let isTransient: Bool
|
||||
internal let allowsExternalBinaryDataStorage: Bool
|
||||
@@ -427,6 +431,11 @@ public enum TransformableContainer<O: CoreStoreObject> {
|
||||
public typealias ReturnValueType = DestinationValueType?
|
||||
|
||||
|
||||
// MARK: PropertyProtocol
|
||||
|
||||
internal let keyPath: KeyPathString
|
||||
|
||||
|
||||
// MARK: AttributeProtocol
|
||||
|
||||
internal static var attributeType: NSAttributeType {
|
||||
@@ -434,7 +443,6 @@ public enum TransformableContainer<O: CoreStoreObject> {
|
||||
return .transformableAttributeType
|
||||
}
|
||||
|
||||
internal let keyPath: KeyPathString
|
||||
internal let isOptional = true
|
||||
internal let isTransient: Bool
|
||||
internal let allowsExternalBinaryDataStorage: Bool
|
||||
|
||||
@@ -202,6 +202,11 @@ public enum ValueContainer<O: CoreStoreObject> {
|
||||
// MARK: AttributeKeyPathStringConvertible
|
||||
|
||||
public typealias ReturnValueType = DestinationValueType
|
||||
|
||||
|
||||
// MARK: PropertyProtocol
|
||||
|
||||
internal let keyPath: KeyPathString
|
||||
|
||||
|
||||
// MARK: AttributeProtocol
|
||||
@@ -210,8 +215,7 @@ public enum ValueContainer<O: CoreStoreObject> {
|
||||
|
||||
return V.cs_rawAttributeType
|
||||
}
|
||||
|
||||
internal let keyPath: KeyPathString
|
||||
|
||||
internal let isOptional = false
|
||||
internal let isTransient: Bool
|
||||
internal let allowsExternalBinaryDataStorage = false
|
||||
@@ -420,6 +424,11 @@ public enum ValueContainer<O: CoreStoreObject> {
|
||||
// MARK: AttributeKeyPathStringConvertible
|
||||
|
||||
public typealias ReturnValueType = DestinationValueType?
|
||||
|
||||
|
||||
// MARK: PropertyProtocol
|
||||
|
||||
internal let keyPath: KeyPathString
|
||||
|
||||
|
||||
// MARK: AttributeProtocol
|
||||
@@ -429,7 +438,6 @@ public enum ValueContainer<O: CoreStoreObject> {
|
||||
return V.cs_rawAttributeType
|
||||
}
|
||||
|
||||
internal let keyPath: KeyPathString
|
||||
internal let isOptional = true
|
||||
internal let isTransient: Bool
|
||||
internal let allowsExternalBinaryDataStorage = false
|
||||
|
||||
Reference in New Issue
Block a user