Rolandas
Rolandas

Reputation: 47

SQL type fetch request from core data

Although there are similar topics to this, but in stack overflow there is no clear answer to issue I will describe below. For simplicity I will simplify entities. So: there are two entities in core data:

First entity called Person with attributes:
FirstName
LastName
City

Second entity: Country with attributes:
City
Capital

The idea is that in one view controller, user adds values by form for second entity - fills in city and capital information for country. In other view controller, user fills first and last names but selects city from picker view that is already filled from data added in other view controller.

In third view controller, I want to fetch first entity adding capital to it (all info in table view controller), e.g. if first entity contains data:
John | Jones | Chicago
the second one by default should have a line with this data:
Chicago | Washington

How can I get "Washington" assigned to "John"?

Similar to this problem, but no clear answer there: Selecting columns from different entities

Upvotes: 0

Views: 194

Answers (1)

Modo Ltunzher
Modo Ltunzher

Reputation: 668

I came up with next db scheme:

Entity:
    City
      Attributes:
        id: Integer 16
        name: String
      Relationships:
        [o] capitalOfCountryOptional: Country, inverse: capital
        [o] country: Country, inverse: cities
        [m] people: Person, inverse: city

    Country
      Attributes:
        id: Integer 16
        name: String
      Relationships:
        [o] capital: City, inverse: capitalOfCountryOptional
        [m] cities: Person, inverse: city

    Person
      Attributes:
        id: Integer 16
        firstName: String
        flastName: String
      Relationships:
        [o] city: City, inverse: people

Xcode screenshot

Once you need some person info and you know id:

Now you can create all needed obects and set as relationships:

let country = ... Ukraine
let city = ... Lviv
let capital = ... Kyiv
let person = ... John Doe

country.capital = capital
city.country = country
person.city = city

Then you need to save yuor context and you can retrieve person info:

import CoreData
public class MOPerson: NSManagedObject {    
    static func getPerson(id: Int16) -> MOPerson? {
        let request: NSFetchRequest<MOPerson> = MOPerson.fetchRequest()
        request.predicate = NSPredicate(format: "\(#keyPath(MOPerson.id)) = %@", NSNumber(int16: id))
        request.fetchLimit = 1
        let result: MOPerson? = (try? CoreDataController.shared.managedContext.fetch(request))?.first
        return result
    }
}

Example:

if let person = MOPerson.getPerson(id: 1) {
    print("Person: \(person.firstName), capital: \(person.city?.country?.capital?.name ?? "not defined")")
}

Upvotes: 1

Related Questions