4

My question can be applied to any type of relationship but in my case I have a one to many.

Let's say I have an Entity Person which has 3 objects:

Brian

Peter

Scott

And each person can have many Jobs. So I have a Job entity that is currently empty. The inverse relationships for both entities are already created and they work great. Just to be clear my problem is not inserting an object(I know how to do that), is the specific way of insertion.

So the more specific question is:

How can I insert one or more job objects into the Job Entity and assign each of them to one of the Person objects that currently exist in Core Data?

Fidel
  • 1,173
  • 11
  • 21

4 Answers4

8

After trying a lot of things I finally found a solution. Thanks to Jimmy who game an idea on how to approach this. The key is to realize that you cannot assign a many to one that already exist (Or at least I could not find a way to do it) but you could add many objects to an existing one. In other words you cannot assign an Entity to a Set nor the other way around.

SWIFT 3

So the First Step is to get the one object (in this case the Person) you want to assign many(In this case Jobs) to. This will get you there:

  var person = try MOC.fetch(Person.fetchRequest()).filter { $0.name == "Brian" }

The Second Step is to create a managed object of the Jobs:

 let job = Jobs(context: MOC)
 job.title = "Computers"

And the Third Step is to add the object trough the Person you fetch:

  person[0].addToJobs(job)

If you would like to add more than one Job then you can create a for loop and create as many managed objects you want and add them whenever they are are ready to save. for example:

 for title in jobsTitles {

    let job = Jobs(context: MOC)
    job.title = title

    person[0].addToJobs(job)

 }
Fidel
  • 1,173
  • 11
  • 21
  • Glad to hear you found a solution! Don't forget to vote for my answer to help people is the future!! – Jimmy James Dec 09 '16 at 21:24
  • I would give you a vote but i can't because I need more than 15 points of reputation and I have only 13. – Fidel Dec 12 '16 at 14:09
3

First:

Create some jobs :

let job1 = NSEntityDescription.insertNewObjectForEntityForName("Job", inManagedObjectContext: managedObjectContext) as! Job
...

Second:

Retrieve those job:

// Request
let moc = managedObjectContext
let jobFetch = NSFetchRequest(entityName: "Job")
// Filtring
let jobTitle1 = "job1"
jobFetch.predicate = NSPredicate(format: "jobTitle == %@", jobTitle)
do {
    let fetchedJobs = try moc.executeFetchRequest(jobFetch) as! [Job] // JOBS
} catch {
    fatalError("Failed to fetch jobs: \(error)")
}

Third:

Retrieve person:

// Request
let moc = managedObjectContext
let personFetch = NSFetchRequest(entityName: "Person")
// Filtring
let firstName = "Person1"
personFetch.predicate = NSPredicate(format: "firstname == %@", firstName)
do {
    let fetchedJobs = try moc.executeFetchRequest(personFetch) as! [Person] // PERSONS
} catch {
    fatalError("Failed to fetch persons: \(error)")
}

FOURTH:

Assert job to person:

let person1 = (personFetch as! [Person])[0]
let job1 = (fetchedJobs as! [Job])[0]
person1.job = job1

PS: coded but not tested

Jimmy James
  • 825
  • 12
  • 28
  • Hi Jimmy, thanks for the answer. This code looks like it should take me into the right path. I will go ahead and test this and make sure it works and let you know if it does. thanks again – Fidel Dec 09 '16 at 17:09
  • Hi Jimmy, from what I have tested so far , this code won't work because of this line of code: person1.job = job1. Job 1 is a set and you cannot assign a set type to an entity type – Fidel Dec 09 '16 at 18:29
0
 let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
func fetchData()
{
    do
    {
    task1 = try context.fetch(Contact.fetchRequest())


    }
catch
{
print("Error fetching data from CoreData")
}

}

func filtering()
{

    do {
        let contactIdentifier : String = searchVariable.text!
        let formatRequest : NSFetchRequest<Contact> = Contact.fetchRequest()
        formatRequest.predicate = NSPredicate(format: "first_name CONTAINS[c] '\(contactIdentifier)'")
        let fetchedResults = try context.fetch(formatRequest)
        if let aContact = fetchedResults.first
        {
            searchResult = fetchedResults

        }
        contactListngTable.reloadData()
    }
    catch {
        print ("fetch task failed", error)
    }


}

@IBAction func saveButton(_ sender: Any)
{
    let task = Contact(context:context)
    task.first_name = firstNameTextbox.text
    task.last_name = lastNameTextbox.text
    task.phone_number = phoneNumberTextbox.text
    (UIApplication.shared.delegate as! AppDelegate).saveContext()
    _ = navigationController?.popViewController(animated: true)     
}

@IBAction func loguotButton(_ sender: Any)
{
    let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
    let newViewController = storyBoard.instantiateViewController(withIdentifier: "logout") as! ViewController
    self.present(newViewController, animated: true, completion: nil)

}

func authinication()
{
    let username : String = usernameTextbox.text!
    let pasword : String = passwordTextbox.text!
    let parameter : Parameters = ["email": "\(username)" , "password": "\(pasword)" ]

    Alamofire.request("https://reqres.in/api/login", method:.post, parameters:parameter
        ).responseJSON { response in
        switch response.result {
        case .success(let value):
            //print(response)
            let forToken = JSON(value)
            let token = forToken["token"]
            let error = forToken["error"]
            if(token.type == SwiftyJSON.Type.null)
            {
                self.errorMessageLabel.text = error[].stringValue
            }
            else
            {
                self.performSegue(withIdentifier: "loginSuccess", sender: nil)
            }




        case .failure(let error):
            print(error)
        }

        }






}
  • 1
    While this code snippet may be the solution, including an explanation really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion – Rahul Gupta Jan 04 '18 at 05:26
-1

If you are using CoreData, then your objects have generated class. In this generated class you will see generated methods like this:

- (void)addJobsObject:(CDJob*)value;
- (void)removeJobsObject:(CDAdvert*)value;
- (void)addJobs:(NSSet*)values;

Use them to set relations.

Adamsor
  • 730
  • 1
  • 6
  • 14
  • Hi Adamsor, thanks for the answer. But I already knew that. Like I said in my questions my problem is not just inserting. My issue is inserting and connecting those objects to their relationships (in this case an existing Person). – Fidel Dec 09 '16 at 16:55