Skip to content

Commit 85ac09a

Browse files
committedFeb 16, 2024··
Merge branch 'feature/no-codable-box-1' into develop
2 parents c1a963c + 28d5984 commit 85ac09a

File tree

5 files changed

+70
-113
lines changed

5 files changed

+70
-113
lines changed
 

‎Sources/ManagedModels/PersistentModel/PersistentModel+KVC.swift

+7-14
Original file line numberDiff line numberDiff line change
@@ -254,14 +254,14 @@ public extension PersistentModel {
254254

255255
func setValue<T>(forKey key: String, to value: T) where T: Codable {
256256
willChangeValue(forKey: key); defer { didChangeValue(forKey: key) }
257-
setPrimitiveValue(CodableBox<T>(value), forKey: key)
257+
setPrimitiveValue(value, forKey: key)
258258
}
259259

260260
func setValue<T>(forKey key: String, to value: T)
261261
where T: Codable & AnyOptional
262262
{
263263
willChangeValue(forKey: key); defer { didChangeValue(forKey: key) }
264-
if value.isSome { setPrimitiveValue(CodableBox<T>(value), forKey: key) }
264+
if value.isSome { setPrimitiveValue(value, forKey: key) }
265265
else { setPrimitiveValue(nil, forKey: key) }
266266
}
267267

@@ -271,10 +271,7 @@ public extension PersistentModel {
271271
fatalError("No box found for non-optional Codable value for key \(key)?")
272272
}
273273

274-
if let box = value as? CodableBox<T> {
275-
guard let value = box.value else {
276-
fatalError("Box has no value for non-optional Codable for key \(key)?")
277-
}
274+
if let value = value as? T {
278275
return value
279276
}
280277

@@ -288,17 +285,13 @@ public extension PersistentModel {
288285
}
289286
}
290287

291-
guard let value = value as? T else {
292-
fatalError("Unexpected value for key \(key)? \(value)")
293-
}
294-
assertionFailure("Codable value is directly stored? \(value)")
295-
return value
288+
fatalError("Codable value type doesn't match? \(value)")
296289
}
297290

298291
func getValue<T>(forKey key: String) -> T where T: Codable & AnyOptional {
299292
willAccessValue(forKey: key); defer { didAccessValue(forKey: key) }
300293
guard let value = primitiveValue(forKey: key) else { return .noneValue }
301-
if let box = value as? CodableBox<T> { return box.value ?? .noneValue }
294+
if let value = value as? T { return value }
302295

303296
if let data = value as? Data {
304297
assertionFailure("Unexpected Data as primitive!")
@@ -313,7 +306,7 @@ public extension PersistentModel {
313306
guard let value = value as? T else {
314307
fatalError("Unexpected value for key \(key)? \(value)")
315308
}
316-
assertionFailure("Codable value is directly stored? \(value)")
317-
return value
309+
assertionFailure("Codable value type doesn't match? \(value)")
310+
return .noneValue
318311
}
319312
}

‎Sources/ManagedModels/SchemaCompatibility/CodableBox.swift

-86
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
//
2+
// Created by Helge Heß.
3+
// Copyright © 2023 ZeeZide GmbH.
4+
//
5+
6+
import Foundation
7+
import CoreData
8+
9+
final class CodableTransformer<T: Codable>: ValueTransformer {
10+
11+
#if false
12+
override class func transformedValueClass() -> AnyClass {
13+
T.self // doesn't work
14+
}
15+
#endif
16+
override class func allowsReverseTransformation() -> Bool { true }
17+
18+
override func transformedValue(_ value: Any?) -> Any? {
19+
// value is the box
20+
guard let value else { return nil }
21+
guard let typed = value as? T else {
22+
assertionFailure("Value to be transformed is not the right type? \(value)")
23+
return nil
24+
}
25+
do {
26+
return try JSONEncoder().encode(typed)
27+
}
28+
catch {
29+
assertionFailure("Could not encode JSON value of property? \(error)")
30+
return nil
31+
}
32+
}
33+
34+
override func reverseTransformedValue(_ value: Any?) -> Any? {
35+
guard let value else { return nil }
36+
guard let data = value as? Data else {
37+
assert(value is Data, "Reverse value is not `Data`?")
38+
return nil
39+
}
40+
do {
41+
return try JSONDecoder().decode(T.self, from: data)
42+
}
43+
catch {
44+
assertionFailure("Could not decode JSON value of property? \(error)")
45+
return nil
46+
}
47+
}
48+
}

‎Sources/ManagedModels/SchemaCompatibility/NSAttributeDescription+Data.swift

+9-7
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ extension CoreData.NSAttributeDescription: SchemaProperty {
4040

4141
if let primitiveType = newValue as? CoreDataPrimitiveValue.Type {
4242
let config = primitiveType.coreDataValue
43-
self.attributeType = config.attributeType
44-
self.isOptional = config.isOptional
43+
self.attributeType = config.attributeType
44+
self.isOptional = config.isOptional
4545
if let newClassName = config.attributeValueClassName {
4646
self.attributeValueClassName = newClassName
4747
}
@@ -55,8 +55,8 @@ extension CoreData.NSAttributeDescription: SchemaProperty {
5555
let rawType = type.RawValue.self
5656
if let primitiveType = rawType as? CoreDataPrimitiveValue.Type {
5757
let config = primitiveType.coreDataValue
58-
self.attributeType = config.attributeType
59-
self.isOptional = config.isOptional
58+
self.attributeType = config.attributeType
59+
self.isOptional = config.isOptional
6060
if let newClassName = config.attributeValueClassName {
6161
self.attributeValueClassName = newClassName
6262
}
@@ -75,12 +75,14 @@ extension CoreData.NSAttributeDescription: SchemaProperty {
7575
self.isOptional = newValue is any AnyOptional.Type
7676

7777
func setValueClassName<T: Codable>(for type: T.Type) {
78-
self.attributeValueClassName = NSStringFromClass(CodableBox<T>.self)
78+
#if false // doesn't work
79+
self.attributeValueClassName = NSStringFromClass(T.self)
80+
#endif
7981

80-
let name = NSStringFromClass(CodableBox<T>.Transformer.self)
82+
let name = NSStringFromClass(CodableTransformer<T>.self)
8183
if !ValueTransformer.valueTransformerNames().contains(.init(name)) {
8284
// no access to valueTransformerForName?
83-
let transformer = CodableBox<T>.Transformer()
85+
let transformer = CodableTransformer<T>()
8486
ValueTransformer
8587
.setValueTransformer(transformer, forName: .init(name))
8688
}

‎Tests/ManagedModelTests/CodablePropertiesTests.swift

+6-6
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,15 @@ final class CodablePropertiesTests: XCTestCase {
3333

3434
let transformerName = try XCTUnwrap(
3535
ValueTransformer.valueTransformerNames().first(where: {
36-
$0.rawValue.range(of: "CodableBox11TransformerVOO17ManagedModelTests8")
36+
$0.rawValue.range(of: "CodableTransformerVOO17ManagedModelTests8")
3737
!= nil
3838
})
3939
)
4040
let transformer = try XCTUnwrap(ValueTransformer(forName: transformerName))
4141
_ = transformer // to clear unused-wraning
4242

43-
XCTAssertTrue(attribute.valueType ==
44-
CodableBox<Fixtures.CodablePropertiesSchema.AccessSIP>.self)
43+
XCTAssertTrue(attribute.valueType == Any.self)
44+
// Fixtures.CodablePropertiesSchema.AccessSIP.self
4545
XCTAssertNotNil(attribute.valueTransformerName)
4646
XCTAssertEqual(attribute.valueTransformerName, transformerName.rawValue)
4747
}
@@ -55,7 +55,7 @@ final class CodablePropertiesTests: XCTestCase {
5555
// CodableBox.
5656
let transformerName = try XCTUnwrap(
5757
ValueTransformer.valueTransformerNames().first(where: {
58-
$0.rawValue.range(of: "CodableBox11TransformerVOO17ManagedModelTests8")
58+
$0.rawValue.range(of: "CodableTransformerVOO17ManagedModelTests8")
5959
!= nil
6060
})
6161
)
@@ -64,8 +64,8 @@ final class CodablePropertiesTests: XCTestCase {
6464

6565
let attribute = try XCTUnwrap(entity.attributesByName["sip"])
6666
XCTAssertEqual(attribute.name, "sip")
67-
XCTAssertTrue(attribute.valueType ==
68-
CodableBox<Fixtures.CodablePropertiesSchema.AccessSIP>.self)
67+
XCTAssertTrue(attribute.valueType == Any.self)
68+
// Fixtures.CodablePropertiesSchema.AccessSIP.self)
6969
XCTAssertNotNil(attribute.valueTransformerName)
7070
XCTAssertEqual(attribute.valueTransformerName, transformerName.rawValue)
7171
}

0 commit comments

Comments
 (0)
Please sign in to comment.