I have a one-to-many relationship that looks like so,
I've set up my model classes in a file to match:
import CoreData
import Foundation
class Board: NSManagedObject {
@NSManaged var boardColor: String
@NSManaged var boardCustomBackground: AnyObject?
@NSManaged var boardID: String
@NSManaged var boardName: String
@NSManaged var lists: NSSet
}
class List: NSManagedObject {
@NSManaged var listID: String
@NSManaged var listName: String
@NSManaged var board: Board
}
Because I'm fetching data from multiple JSON endpoints, I have to save my lists seperately from my boards. What I want to do is create/update a list for a board with a matching boardID.
Here's where I am after multiple attempts:
func saveList(boardID: String, listName: String, listID: String) {
let request = NSFetchRequest(entityName: "Board")
var error: NSError? = nil
request.predicate = NSPredicate(format: "boardID like %@", boardID)
let results: NSArray = context.executeFetchRequest(request, error: &error)
if results.count > 0 {
for result in results {
let board = result as Board
let list = NSEntityDescription.insertNewObjectForEntityForName("List", inManagedObjectContext: context) as List
println("💃 want to save \(listName) in \(board.boardName)")
board.lists.addListObject(lists)
list.listName = listName
list.listID = listID
}
}
}
Based on Defining CoreData Relationships in Swift and this, I tried to implement @Keenle's answer for define list objects inside a board:
import Foundation
extension Board {
func addListObject(value:List) {
var items = self.mutableSetValueForKey("lists");
items.addObject(value)
}
func removeListObject(value:List) {
var items = self.mutableSetValueForKey("lists");
items.removeObject(value)
}
}
However, I ran into the following error at board.lists.addListObject(lists)
:
'NSSet' does not have a member named 'addListObject'`
Instead of board.lists.addListObject(lists)
, I also tried board.lists.listName = listName
as implied in this Obj-C example, but that sadly didn't work either.
(Also, The println
output is correctly specifying the right board and list.)
Thanks in advance!
Right-click on your project's folder in the project navigator and then New File… In the new window, type “data” in the top right corner, select Data Model, and press Next. Give it a name, and save it. Now, let's add all the necessary code to connect Core Data with our project.
A relationship's delete rule specifies how changes propagate across relationships when Core Data deletes a source instance. Select No Action to delete the source object instance, but leave references to it in any destination object instances, which you update manually.
Core Data is designed to work in a multithreaded environment. However, not every object under the Core Data framework is thread safe. To use Core Data in a multithreaded environment, ensure that: Managed object contexts are bound to the thread (queue) that they are associated with upon initialization.
In a one-to-many relationship, it is easier to set the "to-one" direction of the inverse relationships, in your case just
list.board = board
so that the extension methods are actually not needed here.
You should invoke addListObject(...)
on board
object:
board.addListObject(list) // notice that we pass just one object
Additionaly, if you want to be able to add a set of lists to particular board
object, you can enhance you Board
class extension with methods that accept set of objects:
func addList(values: NSSet) {
var items = self.mutableSetValueForKey("lists");
for value in values {
items.addObject(value)
}
}
func removeList(values: NSSet) {
var items = self.mutableSetValueForKey("lists");
for value in values {
items.removeObject(value)
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With