Skip to content

Commit 16f5c27

Browse files
committed
Allow relationships to be marked as required
Mark many existing relationships as required
1 parent 334cfe0 commit 16f5c27

File tree

2 files changed

+62
-39
lines changed

2 files changed

+62
-39
lines changed

Character Tracker/Character Tracker/Model Controllers/JSONController.swift

Lines changed: 45 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,11 @@ import SwiftyJSON
1212
protocol RelationshipProtocol {
1313
var key: String { get }
1414

15-
func addRelationship<ObjectType: NSManagedObject>(to object: ObjectType, json: JSON, context: NSManagedObjectContext) throws
15+
@discardableResult
16+
func addRelationship<ObjectType: NSManagedObject>(to object: ObjectType, json: JSON, context: NSManagedObjectContext) throws -> Bool
1617
func addRelationship<ObjectType: NSManagedObject>(to object: ObjectType, from string: String, context: NSManagedObjectContext) throws
1718
func addRelationship<ObjectType: NSManagedObject, RelationshipType: NSManagedObject>(to object: ObjectType, relationshipObject: RelationshipType, context: NSManagedObjectContext)
18-
func addRelationships<ObjectType: NSManagedObject>(to object: ObjectType, json: JSON, context: NSManagedObjectContext) throws
19+
func addRelationships<ObjectType: NSManagedObject>(to object: ObjectType, json: JSON, context: NSManagedObjectContext) throws -> Bool
1920
func object<ObjectType: NSManagedObject>(_ object: ObjectType, matches json: JSON) -> Bool
2021
func object<ObjectType: NSManagedObject>(_ object: ObjectType, matches string: String) -> Bool
2122
func object<ObjectType: NSManagedObject, RelationshipType: NSManagedObject>(_ object: ObjectType, isRelatedTo relative: RelationshipType) -> Bool
@@ -28,7 +29,7 @@ struct Relationship<ObjectType: NSManagedObject>: RelationshipProtocol {
2829
var createIfNotFound: Bool = false
2930
let jsonRepresentation: JSONRepresentation<ObjectType>
3031

31-
func addRelationship<ObjectType: NSManagedObject>(to object: ObjectType, json: JSON, context: NSManagedObjectContext) throws {
32+
func addRelationship<ObjectType: NSManagedObject>(to object: ObjectType, json: JSON, context: NSManagedObjectContext) throws -> Bool {
3233
try JSONController.addRelationship(to: object, json: json, with: self, context: context)
3334
}
3435

@@ -42,7 +43,7 @@ struct Relationship<ObjectType: NSManagedObject>: RelationshipProtocol {
4243
object.setValue(relationshipObject, forKey: key)
4344
}
4445

45-
func addRelationships<ObjectType: NSManagedObject>(to object: ObjectType, json: JSON, context: NSManagedObjectContext) throws {
46+
func addRelationships<ObjectType: NSManagedObject>(to object: ObjectType, json: JSON, context: NSManagedObjectContext) throws -> Bool {
4647
try JSONController.addRelationships(to: object, json: json, with: self, context: context)
4748
}
4849

@@ -106,6 +107,18 @@ struct Relationship<ObjectType: NSManagedObject>: RelationshipProtocol {
106107
}
107108
}
108109

110+
struct RelationshipContainer {
111+
var relationship: RelationshipProtocol
112+
var exportObjects: Bool
113+
var required: Bool
114+
115+
init(_ relationship: RelationshipProtocol, exportObjects: Bool = false, required: Bool = false) {
116+
self.relationship = relationship
117+
self.exportObjects = exportObjects
118+
self.required = required
119+
}
120+
}
121+
109122
class JSONController {
110123
private init() {}
111124

@@ -129,7 +142,7 @@ class JSONController {
129142
objects.count > 0 {
130143
var allObjects = try self.allObjects(for: rep, context: context)
131144

132-
for objectJSON in objects {
145+
objectsLoop: for objectJSON in objects {
133146
guard let object = getOrCreateObject(json: objectJSON, from: allObjects, idIsUUID: rep.idIsUUID, context: context) else { continue }
134147

135148
importAttributes(with: rep.attributes, for: object, from: objectJSON)
@@ -138,12 +151,24 @@ class JSONController {
138151
output.append(name)
139152
}
140153

141-
for relationship in rep.toOneRelationships {
142-
try relationship.relationship.addRelationship(to: object, json: objectJSON, context: context)
154+
for container in rep.toOneRelationships {
155+
let objectFound = try container.relationship.addRelationship(to: object, json: objectJSON, context: context)
156+
// Delete if a required relationship is not present
157+
if container.required,
158+
!objectFound {
159+
context.delete(object)
160+
continue objectsLoop
161+
}
143162
}
144163

145-
for relationship in rep.toManyRelationships {
146-
try relationship.relationship.addRelationships(to: object, json: objectJSON, context: context)
164+
for container in rep.toManyRelationships {
165+
let objectFound = try container.relationship.addRelationships(to: object, json: objectJSON, context: context)
166+
// Delete if a required relationship is not present
167+
if container.required,
168+
!objectFound {
169+
context.delete(object)
170+
continue objectsLoop
171+
}
147172
}
148173

149174
for relationship in rep.relationshipObjects {
@@ -198,7 +223,8 @@ class JSONController {
198223
}
199224
}
200225

201-
static func addRelationship<ObjectType: NSManagedObject, RelationshipType: NSManagedObject>(to object: ObjectType, json: JSON, with relationship: Relationship<RelationshipType>, context: NSManagedObjectContext) throws {
226+
@discardableResult
227+
static func addRelationship<ObjectType: NSManagedObject, RelationshipType: NSManagedObject>(to object: ObjectType, json: JSON, with relationship: Relationship<RelationshipType>, context: NSManagedObjectContext) throws -> Bool{
202228

203229
let relationshipObjects = try allObjects(for: relationship.jsonRepresentation, context: context)
204230

@@ -213,17 +239,20 @@ class JSONController {
213239
}
214240

215241
return false
216-
}) else { return }
242+
}) else { return false }
217243

218244
object.setValue(relationshipObject, forKey: relationship.key)
245+
return true
219246
}
220247

221-
static func addRelationships<ObjectType: NSManagedObject, RelationshipType: NSManagedObject>(to object: ObjectType, json: JSON, with relationship: Relationship<RelationshipType>, context: NSManagedObjectContext) throws {
248+
static func addRelationships<ObjectType: NSManagedObject, RelationshipType: NSManagedObject>(to object: ObjectType, json: JSON, with relationship: Relationship<RelationshipType>, context: NSManagedObjectContext) throws -> Bool {
222249
guard let idArray = json[relationship.key].array,
223-
idArray.count > 0 || relationship.createIfNotFound else { return }
250+
idArray.count > 0 || relationship.createIfNotFound else { return false }
224251

225252
let relationshipObjects = try allObjects(for: relationship.jsonRepresentation, context: context)
226253

254+
var notEmpty = false
255+
227256
for idJSON in idArray {
228257
guard let id = idJSON.string else { continue }
229258
let relationshipObject: RelationshipType
@@ -265,7 +294,10 @@ class JSONController {
265294
} else {
266295
object.mutableSetValue(forKey: relationship.key).add(relationshipObject)
267296
}
297+
notEmpty = true
268298
}
299+
300+
return notEmpty
269301
}
270302

271303
static func object<ObjectType: NSManagedObject>(_ object: ObjectType, hasID id: String) -> Bool {

Character Tracker/Character Tracker/Model Controllers/PortController.swift

Lines changed: 17 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -41,29 +41,19 @@ protocol JSONRepresentationProtocol {
4141
class JSONRepresentation<ObjectType: NSManagedObject>: JSONEntity<ObjectType>, JSONRepresentationProtocol {
4242
var arrayKey: String
4343
var attributes: [String]
44-
var toOneRelationships: [(relationship: RelationshipProtocol, exportObjects: Bool)]
45-
var toManyRelationships: [(relationship: RelationshipProtocol, exportObjects: Bool)]
44+
var toOneRelationships: [RelationshipContainer]
45+
var toManyRelationships: [RelationshipContainer]
4646
var relationshipObjects: [JSONRelationshipProtocol] = []
4747
var idIsUUID: Bool = true
4848

49-
init(arrayKey: String, attributes: [String], toOneRelationships: [(relationship: RelationshipProtocol, exportObjects: Bool)], toManyRelationships: [(relationship: RelationshipProtocol, exportObjects: Bool)], idIsUUID: Bool = true) {
49+
init(arrayKey: String, attributes: [String], toOneRelationships: [RelationshipContainer] = [], toManyRelationships: [RelationshipContainer] = [], idIsUUID: Bool = true) {
5050
self.arrayKey = arrayKey
5151
self.attributes = attributes
5252
self.toOneRelationships = toOneRelationships
5353
self.toManyRelationships = toManyRelationships
5454
self.idIsUUID = idIsUUID
5555
}
5656

57-
convenience init(arrayKey: String, attributes: [String], toOneRelationships: [RelationshipProtocol] = [], toManyRelationships: [RelationshipProtocol] = [], idIsUUID: Bool = true) {
58-
self.init(
59-
arrayKey: arrayKey,
60-
attributes: attributes,
61-
toOneRelationships: toOneRelationships.map { ($0, false) },
62-
toManyRelationships: toManyRelationships.map { ($0, false) },
63-
idIsUUID: idIsUUID
64-
)
65-
}
66-
6757
func json(_ object: ObjectType) -> (objectJSON: JSON, relationshipsJSON: JSON) {
6858
var json = JSON([:])
6959
var relationships = JSON()
@@ -263,16 +253,16 @@ class PortController {
263253
let attributeTypeSections = JSONRepresentation<AttributeTypeSection>(
264254
arrayKey: "attribute_type_sections",
265255
attributes: ["name", "maxPriority", "minPriority"],
266-
toOneRelationships: [attributeTypesRelationship])
256+
toOneRelationships: [.init(attributeTypesRelationship, required: true)])
267257
setRep(attributeTypeSections)
268258

269259
// Attributes
270260
let gamesRelationship = Relationship(key: "games", jsonRepresentation: games)
271261
let attributes = JSONRepresentation<Attribute>(
272262
arrayKey: "attributes",
273263
attributes: ["name"],
274-
toOneRelationships: [attributeTypesRelationship],
275-
toManyRelationships: [gamesRelationship])
264+
toOneRelationships: [.init(attributeTypesRelationship, required: true)],
265+
toManyRelationships: [.init(gamesRelationship, required: true)])
276266
setRep(attributes)
277267

278268
// Module Types
@@ -285,7 +275,7 @@ class PortController {
285275
let ingredients = JSONRepresentation<Ingredient>(
286276
arrayKey: "ingredients",
287277
attributes: ["name"],
288-
toManyRelationships: [gamesRelationship],
278+
toManyRelationships: [.init(gamesRelationship, required: true)],
289279
idIsUUID: false)
290280
setRep(ingredients)
291281

@@ -294,8 +284,9 @@ class PortController {
294284
let modules = JSONRepresentation<Module>(
295285
arrayKey: "modules",
296286
attributes: ["name", "level", "notes"],
297-
toOneRelationships: [moduleTypesRelationship],
298-
toManyRelationships: [gamesRelationship, imagesRelationship])
287+
toOneRelationships: [.init(moduleTypesRelationship, required: true)],
288+
toManyRelationships: [.init(gamesRelationship, required: true),
289+
.init(imagesRelationship)])
299290
setRep(modules)
300291

301292
// Module Ingredients
@@ -319,7 +310,7 @@ class PortController {
319310
let races = JSONRepresentation<Race>(
320311
arrayKey: "races",
321312
attributes: ["name"],
322-
toManyRelationships: [gamesRelationship])
313+
toManyRelationships: [.init(gamesRelationship, required: true)])
323314
setRep(races)
324315

325316
// Characters
@@ -328,7 +319,8 @@ class PortController {
328319
let characters = JSONRepresentation<Character>(
329320
arrayKey: "characters",
330321
attributes: ["female", "name"],
331-
toOneRelationships: [raceRelationship, gameRelationship])
322+
toOneRelationships: [.init(raceRelationship, required: true),
323+
.init(gameRelationship, required: true)])
332324
setRep(characters)
333325

334326
// Character Modules
@@ -343,12 +335,11 @@ class PortController {
343335
let mods = JSONRepresentation<Mod>(
344336
arrayKey: "mods",
345337
attributes: ["name"],
346-
toOneRelationships: [],
347338
toManyRelationships: [
348-
(gamesRelationship, false),
349-
(modulesRelationship, true),
350-
(ingredientsRelationship, true),
351-
(imagesRelationship, true)
339+
.init(gamesRelationship, exportObjects: false, required: true),
340+
.init(modulesRelationship, exportObjects: true),
341+
.init(ingredientsRelationship, exportObjects: true),
342+
.init(imagesRelationship, exportObjects: true)
352343
])
353344
setRep(mods)
354345
}

0 commit comments

Comments
 (0)