Skip to content

Instantly share code, notes, and snippets.

@skoirala
Created July 29, 2019 20:29
Show Gist options
  • Save skoirala/f336f2ff42afcb886567eb222a5426c8 to your computer and use it in GitHub Desktop.
Save skoirala/f336f2ff42afcb886567eb222a5426c8 to your computer and use it in GitHub Desktop.
Core data model with relationship
import CoreData
public class Address: NSManagedObject {
@NSManaged public var city: String
@NSManaged public var country: String
@NSManaged public var person: Person
}
import CoreData
public class CoreDataStack {
let persistentContainer: NSPersistentContainer
public var viewContext: NSManagedObjectContext {
return persistentContainer.viewContext
}
public init(directory: URL, model: NSManagedObjectModel) {
let storeURL = directory.appendingPathComponent("store.sqlite")
let persistentContainerDescription = NSPersistentStoreDescription(url: storeURL)
persistentContainer = NSPersistentContainer(name: "store", managedObjectModel: model)
persistentContainer.persistentStoreDescriptions = [persistentContainerDescription]
persistentContainer.loadPersistentStores { desc, error in
if let error = error {
print("Error occurred: \(error)")
}
print("Persistent store desciption: \(desc)")
}
}
}
import PlaygroundSupport
import CoreData
import Foundation
let model = createManagedObjectModel()
let coreDataStack = CoreDataStack(directory: playgroundSharedDataDirectory, model: model)
let repo = PersonRepository(managedObjectContext: coreDataStack.viewContext)
func insert() {
let person = repo.insertPerson(firstName: "Sandeep",
lastName: "Koirala",
age: 32)
repo.addAddress(city: "Kathmandu", country: "Nepal", toPerson: person)
repo.addAddress(city: "Helsinki", country: "Finland", toPerson: person)
}
func fetch() -> [Person] {
let person = NSFetchRequest<Person>(entityName: "Person")
return try! coreDataStack.viewContext.fetch(person)
}
PlaygroundPage.current.needsIndefiniteExecution = true
import CoreData
public func createManagedObjectModel() -> NSManagedObjectModel {
let person = createPersonEntity()
let address = createAddressEntity()
let personAddresses = connectPerson(toAddress: address)
let addressPerson = connectAddress(toPerson: person)
personAddresses.inverseRelationship = addressPerson
addressPerson.inverseRelationship = personAddresses
person.properties = createPersonAttributes() + [personAddresses]
address.properties = createAddressAttributes() + [addressPerson]
let model = NSManagedObjectModel()
model.entities = [person,
address]
return model
}
func createPersonEntity() -> NSEntityDescription {
let person = NSEntityDescription()
person.name = "Person"
person.managedObjectClassName = NSStringFromClass(Person.self)
return person
}
func createAddressEntity() -> NSEntityDescription {
let address = NSEntityDescription()
address.name = "Address"
address.managedObjectClassName = NSStringFromClass(Address.self)
return address
}
func createPersonAttributes() -> [NSAttributeDescription] {
let firstName = NSAttributeDescription()
firstName.attributeType = .stringAttributeType
firstName.name = "firstName"
let lastName = NSAttributeDescription()
lastName.attributeType = .stringAttributeType
lastName.name = "lastName"
let age = NSAttributeDescription()
age.attributeType = .integer16AttributeType
age.name = "age"
return [firstName, lastName, age]
}
func createAddressAttributes() -> [NSPropertyDescription] {
let city = NSAttributeDescription()
city.attributeType = .stringAttributeType
city.name = "city"
let country = NSAttributeDescription()
country.attributeType = .stringAttributeType
country.name = "country"
return [city, country]
}
func connectPerson(toAddress address: NSEntityDescription) -> NSRelationshipDescription {
let addressRelationship = NSRelationshipDescription()
addressRelationship.destinationEntity = address
addressRelationship.name = "addresses"
addressRelationship.minCount = 0 // to many
addressRelationship.maxCount = 0
return addressRelationship
}
func connectAddress(toPerson person: NSEntityDescription) -> NSRelationshipDescription {
let personRelationship = NSRelationshipDescription()
personRelationship.name = "person"
personRelationship.destinationEntity = person
personRelationship.minCount = 0
personRelationship.maxCount = 1
return personRelationship
}
import CoreData
public class Person: NSManagedObject {
@NSManaged public var firstName: String
@NSManaged public var lastName: String
@NSManaged public var age: NSNumber
@NSManaged public var addresses: Set<Address>
}
import CoreData
public class PersonRepository {
private let managedObjectContext: NSManagedObjectContext
public init(managedObjectContext: NSManagedObjectContext) {
self.managedObjectContext = managedObjectContext
}
private func insert<T: NSManagedObject>(entityName: String) -> T {
return NSEntityDescription.insertNewObject(forEntityName: entityName, into: managedObjectContext) as! T
}
public func insertPerson(firstName: String, lastName: String, age: Int) -> Person {
let person: Person = insert(entityName: "Person")
person.firstName = firstName
person.lastName = lastName
person.age = NSNumber(value: age)
save()
return person
}
public func addAddress(city: String, country: String, toPerson person: Person) {
let address: Address = insert(entityName: "Address")
address.city = city
address.country = country
let addresses = person.mutableSetValue(forKey: "addresses")
addresses.add(address)
save()
}
private func save() {
do {
try managedObjectContext.save()
} catch {
print("Could not save person \(error)")
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment