Coredata / SWIFT get records with relationship

2019-08-09 08:42发布

问题:

Still in trouble with core data relationships.

Example :

Entity User (idU, NameU = attributes) Entity Device (idD, NameD = attributes)

core data model Question : I have a Nsset issue when i create a new device linked to user. i think it is related to the many-many relationships

still not working UPDATE :

code :

 @IBAction func addDeviceBoutonAction(sender: AnyObject) {

        print("Creation Device debut")
        var nbCharacteres = Int((newDeviceNameTextField.text?.characters.count)!)
        if currentUserName == "" {
           print("Erreur creation device / currentUserName = Vide --> Abort")
          }
          else if nbCharacteres == 0 {
            print("Erreur creation device / newDeviceNameTextField = Vide --> Abort")
          }
          else
          {
          // init du MOC
          let MOC = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
        // creation de la requete sur l'entité User avec un predicat : on recupere que les infos du user selectionné dans le pickerViewUser (on 
        // travaille avec la variable globale currentUserName qui a été initialisée lors du  didSelectRow du pickerViewUser)
        let fetchRequestUser = NSFetchRequest(entityName: "User")
        print("Creation device / trace currentUserName = \(currentUserName)")
        let userPredicate = NSPredicate(format: "userName == %@", currentUserName)
        // On colle le predicat dans la requete
        fetchRequestUser.predicate = userPredicate

        var requestError: NSError?
        let existingUser = (try! MOC.executeFetchRequest(fetchRequestUser)) as! [User]
         print("Creation device / trace existingUser[0].userName = \(existingUser[0].userName)")
        // il faut passer par l'ID plutot que le nom
        // firstUserFound de type User
         let firstUserFound = existingUser[0]
                print("Creation device firstUserFound = \(firstUserFound)")    

        // Insertion d'un nouveau Device dans la base  (relationship n to n entre Device et User)
       let existingDevicesForThisUser = firstUserFound.mutableSetValueForKey("device")

       // Create Item Record
       let newDevice = NSEntityDescription.insertNewObjectForEntityForName("Device",inManagedObjectContext: MOC) as! Device
       //if let newDevice = createRecordForEntity("Device", inManagedObjectContext: MOC) {
        // Set Attributes and values
        newDevice.setValue(NSUUID().UUIDString, forKey: "deviceId")
        newDevice.setValue(newDeviceNameTextField.text, forKey: "deviceName")
        newDeviceNameTextField.text = ""
        self.view.endEditing(true)
        //newDevice.setValue("Device \(newDevice.count + 1)", forKey: "deviceId")
        // Set Relationship
        print("avant relationhips")
        newDevice.setValue(firstUserFound, forKey: "users")

Error : Creation Device debut

Creation device / trace currentUserName = toto

Creation device / trace existingUser[0].userName = Optional("toto")

Creation device firstUserFound = (entity: User; id: 0xd000000000080000 ; data: { devices = ""; userId = "8A32EAC6-87E2-4CF1-8265-5E7A32ABCEBB"; userName = toto; })

avant relationhips

2016-04-02 13:55:13.065 testcoredatarelationships[1568:370426] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unacceptable type of value for to-many relationship: property = "users"; desired type = NSSet; given type = testcoredatarelationships.User; value = (entity: User; id: 0xd000000000080000 ; data: { devices = ""; userId = "8A32EAC6-87E2-4CF1-8265-5E7A32ABCEBB"; userName = toto; }).' * First throw call stack:

line which is wrong : newDevice.setValue(firstUserFound, forKey: "users")

extension Device {

@NSManaged var deviceId: String?
@NSManaged var deviceName: String?
@NSManaged var cards: NSSet?
**@NSManaged var users: NSSet?**

}

回答1:

You're using a many to many relationship so the easiest way to get jacks devices is to get jack (with a fetch request) and then to ask it for its devices. This navigates the relationship so you don't need another fetch.

It's possible to directly fetch devices who have a relationship to a user with a specific name but it's more complicated to do that.