CoreData:Relationship:Save:Query - core-data

I have EmployeeExample and Deptt as entities.
EmployeeExample one to one relationship with Dept
Dept has more than one relationship with EmployeeExample
I want to save data through relationship. I have dept entity object, with that I want to save employeeexample entity
I achieved this, but I want to know whether it is the optimal way. Any optimal way? I would like to know how the relationship works.
My code :
import UIKit
import CoreData
class ViewController: UIViewController {
var container: NSPersistentContainer? = (UIApplication.shared.delegate as? AppDelegate)?.persistentContainer
let appDelegate = UIApplication.shared.delegate as! AppDelegate
var empSet = NSSet()
var empS = Set<EmployeeExample>()
override func viewDidLoad() {
super.viewDidLoad()
var context:NSManagedObjectContext = (container?.viewContext)!
let dept = NSEntityDescription.insertNewObject(forEntityName: "Deptt", into: context) as! Deptt
let emp = NSEntityDescription.insertNewObject(forEntityName: "EmployeeExample", into: (container?.viewContext)!) as! EmployeeExample
emp.firstName = "YYYY"
emp.lastName = "HHHHHHH"
empS.insert(emp)
print("Count of Emp SSSS Set == \(empS.count)")
let emp1 = NSEntityDescription.insertNewObject(forEntityName: "EmployeeExample", into: (container?.viewContext)!) as! EmployeeExample
emp1.firstName = "RRRRR"
emp1.lastName = "YYYYY"
empS.insert(emp1)
empSet.addingObjects(from: empS)
dept.deptName = "CCC"
print("Count of Emp SSSS Set == \(empS.count)")
print("Count of Emp Set == \(empSet.count)")
dept.addToEmp(empSet)
do {
try appDelegate.saveContext()
print("Saved -------------")
}catch {}
}
}
Do I have to create an Employee instance each time?

Do I have to create an Employee instance each time?
Well, do you have a new employee each time? If you have new information, you need to create a new Employee record. If you're using existing information, you look up an existing Employee from your persistent store by using NSFetchRequest. You create new instances when you have new data to save. Whether you need to do that is something only you can answer. If you have new data, yes. Otherwise, no.

Related

Swiftui CoreData one to many relationship

For example two models Person and Car. Person has many cars. My question is how to add car to already created Person. If I tray in AddNewCarView:
var person: Person
...
var newCar = Car(context: viewContext)
newCar.name = name
newCar.model = model
And now, what...?
newCar.person = person (gives newCar to all persons)
Or.
person.addToCars(newCar)
Is that something I have to add in predicate? In Car I have:
static func fetchCars() -> NSFetchRequest<Car> {
let request: NSFetchRequest<Car> = Car.fetchRequest()
reqest.predicate = NSPredicate(format: "", ) ..?
request.sortDescriptors = [NSSortDescriptor(keyPath: \Car.timestamp, ascending: true)]
return request
}

Swift 4 Core Data - Fetching Relationships

I have entities as so:
Entity 1
Entity 2
I am saving data as so:
#IBAction func saveButton(_ sender: UIButton) {
print("save")
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {
return
}
let context = appDelegate.persistentContainer.viewContext
let workout = Workout(context: context)
workout.name = workoutName.text
workout.noOfSets = Int16(setsStepper.value)
for index in 0..<setsVal {
let sets = Sets(context: context)
let test = IndexPath(row: index, section: 0)
let cell = tableView.cellForRow(at: test) as! RepsTableViewCell
sets.repAmount = Int16(cell.repsStepper.value)
// Does this line not create the relationship between Workout and Set Entities?
workout.addToSets(sets)
}
try! context.save()
}
And I am fetching data as so:
func fetch() {
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {
return
}
let context = appDelegate.persistentContainer.viewContext
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Workout")
request.relationshipKeyPathsForPrefetching = ["Sets"]
do {
let result = try context.fetch(request)
for data in result as! [NSManagedObject] {
print(data.value(forKey: "name") as! String)
print(data.value(forKey: "noOfSets") as! Int16)
}
}
catch {
print("failed")
}
}
I've set up the relationship between entities Workout and Sets as one-many, yet cannot retrieve Set's attributes from Workout.
How can I retrieve an entities relationship attributes?
Do I need to specify the relationship programmatically despite the relationship being setup in the xcdatamodel file?
Does Workout.addToSets(sets) create the relationship between the entities?
You should be able to access your relationship entities as an attribute so for instance
for workout in result as! [Workout] {
print(workout.name)
if let sets = workout.sets { //assuming you have name your to-many relationship 'sets'
print(sets.count)
}
}

Core Data - Relationship

Please let me know how to save objects through relationship.
If I have two entities like Notes , Category entity
Note is one to one for Category.
Category Many to one for Notes.
How to save , if we have Category context to Notes..
Please provide me some inputs.
How to save through sets. It would be greatful
I have Employee and Department entities. Department has one to many relationship with Employee. Employee has one to one relationship with Department. I want save object of employee entity using department entity.
Each time I have create new Object for Employee –
import UIKit
import CoreData
class ViewController: UIViewController {
var container: NSPersistentContainer? = (UIApplication.shared.delegate as? AppDelegate)?.persistentContainer
let appDelegate = UIApplication.shared.delegate as! AppDelegate
var empSet = NSSet()
var empS = Set<EmployeeExample>()
override func viewDidLoad() {
super.viewDidLoad()
var context:NSManagedObjectContext = (container?.viewContext)!
let dept = NSEntityDescription.insertNewObject(forEntityName: "Department", into: context) as! Department
let emp = NSEntityDescription.insertNewObject(forEntityName: "Employee", into: (container?.viewContext)!) as! Employee
emp.firstName = "YYYY"
emp.lastName = "HHHHHHH"
empS.insert(emp)
print("Count of Emp SSSS Set == \(empS.count)")
let emp1 = NSEntityDescription.insertNewObject(forEntityName: "Employee", into: (container?.viewContext)!) as! Employee
emp1.firstName = "RRRRR"
emp1.lastName = "YYYYY"
empS.insert(emp1)
empSet.addingObjects(from: empS)
dept.deptName = "CCC"
print("Count of Emp SSSS Set == \(empS.count)")
print("Count of Emp Set == \(empSet.count)")
dept.addToEmp(empSet)
do {
try appDelegate.saveContext()
print("Saved -------------")
}catch {
print("Error")
}
}
}
I have doubt in these lines anEmployee.department = newDepartment How to get the newDepartment value. Whether i have to declare let newDepartment = NSEntityDescription.insertNewObject(forEntityName: "Department", into: (container?.viewContext)!) as! Department.
The Department object here is whatever object should be related to that specific Employee object. How you get it depends on how your app works, but you probably want to do one of these:
If the employee belongs to a new department that doesn't already exist in your app, you create a new instance of Department and assign that object as anEmployee.department.
If the employee belongs to a department that already exists in your app, you use an already existing Department. You probably get that by fetching Department objects from Core Data-- either with NSFetchRequest or by using an NSFetchedResultsController.

Fetching the most recent item from CoreData in Swift

I'm new to CoreData, have read a few tutorials but have come up empty-handed. Most tutorials have centered around fetching from CoreData to populate a tableview, which is not what I'm doing at the moment.
Here's how I'm setting the data in CoreData. All types are Double except for date which is an NSDate
let appDelegate = (UIApplication.sharedApplication().delegate as AppDelegate)
let managedObjectContext = appDelegate.managedObjectContext
let entityDescription = NSEntityDescription.entityForName("Meditation", inManagedObjectContext: managedObjectContext!)
let meditation = NSManagedObject(entity: entityDescription!, insertIntoManagedObjectContext: managedObjectContext!)
meditation.setValue(settings.minutes, forKey: "length")
meditation.setValue(settings.warmup, forKey: "warmup")
meditation.setValue(settings.cooldown, forKey: "cooldown")
meditation.setValue(NSDate(), forKey: "date")
// fetch stuff from CoreData
var request = NSFetchRequest(entityName: "Meditation")
var error:NSError? = nil
var results:NSArray = managedObjectContext!.executeFetchRequest(request, error: &error)!
for res in results {
println(res)
}
Here's what I'm trying to do to get the results, but I'm not able to access things like .minutes, .date, etc. I know I'm also not properly getting the last item either, I was just trying to print out attributes on the object first.
I'd love help on how to fetch only the most recent object as well as show it's attributes
Thanks!
First, create a "Meditation.swift" file in Xcode with "Editor -> Create NSManagedObject
Subclass ...". The generated file should look like
import Foundation
import CoreData
class Meditation: NSManagedObject {
#NSManaged var length: NSNumber
#NSManaged var warmup: NSNumber
#NSManaged var cooldown: NSNumber
#NSManaged var date: NSDate
}
Now you can use the properties directly instead of Key-Value Coding
and create the object as
let meditation = NSEntityDescription.insertNewObjectForEntityForName("Meditation", inManagedObjectContext: managedObjectContext) as Meditation
meditation.length = ...
meditation.warmup = ...
meditation.cooldown = ...
meditation.date = NSDate()
var error : NSError?
if !managedObjectContext.save(&error) {
println("save failed: \(error?.localizedDescription)")
}
When fetching the object, cast the result of
executeFetchRequest() to [Meditation]:
let request = NSFetchRequest(entityName: "Meditation")
var error : NSError?
let result = managedObjectContext.executeFetchRequest(request, error: &error)
if let objects = result as? [Meditation] {
for meditation in objects {
println(meditation.length)
println(meditation.date)
// ...
}
} else {
println("fetch failed: \(error?.localizedDescription)")
}
Finally, to fetch only the latest object, add a sort descriptor to
sort the results by date in descending order, and limit the number of results to one:
let request = NSFetchRequest(entityName: "Meditation")
request.sortDescriptors = [NSSortDescriptor(key: "date", ascending: false)]
request.fetchLimit = 1
// ...
Then the objects array contains at most one object, which is the most recent one.

swift core data fetching relationship

I'm a little bit confused try to fetch relation data from coredata in swift
Person Entity
contains the name of person and Unique Id. The relation with Books is ONE to Many
For example
Person Entity:
idPerson = 25 - namePerson = John
idPerson = 26 - namePerson = Steve
Books Entity contains the title of books, Unique Id for the book and a relation ID with person (personBook). The relation with Person is ONE to ONE
For example
Books Entity:
idBook = 2543 - titleBook = title one - personBook = 25
idBook = 2544 - titleBook = title two - personBook = 25
idBook = 2545 - titleBook = title three - personBook = 26
here my data model screenshot: (no image because i have no reputation)
Person class
#objc(Person)
class Person: NSManagedObject {
#NSManaged var idPerson: String
#NSManaged var namePerson: String
#NSManaged var booksRel: NSSet
}
Books class
#objc(Books)
class Books: NSManagedObject {
#NSManaged var bookTitle: String
#NSManaged var idBook: String
#NSManaged var personBook: String
#NSManaged var personRel: Person
}
Fetch code
let appDel:AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate
let context:NSManagedObjectContext = appDel.managedObjectContext!
let request = NSFetchRequest(entityName: "Books")
request.returnsObjectsAsFaults = false
request.fetchLimit = 30
////////////////////////////
// CODE TO JOIN Person entity WHERE personBook = idPerson
////////////////////////////
var results:NSArray = context.executeFetchRequest(request, error: nil)!
for temp in results {
var data = temp as Books
///////////////////////////////////////
//println(data.namePerson) ----> not working
///////////////////////////////////////
}
is possibile to fetch for every book the related namePerson based on namePerson = personBook ?
Thank you very much!
You don't need a property personBook for your Books entity.
Let's create a Person managedObject (using Swift 1.0):
let person = NSEntityDescription.insertNewObjectForEntityForName("Person", inManagedObjectContext: context) as Person
person.idPerson = 23
person.namePerson = "John"
var error: NSError?
if !context.save(&error) {
println("Unresolved error \(error), \(error!.userInfo)")
abort()
}
When you create a Books managedObject, you can link it to person like this:
let book = NSEntityDescription.insertNewObjectForEntityForName("Books", inManagedObjectContext: context) as Books
book.bookTitle = "My book Title"
book.idBook = 2547
book.personRel = person
var error: NSError?
if !context.save(&error) {
println("Unresolved error \(error), \(error!.userInfo)")
abort()
}
Now, when you want to make a fetch on Books, you can do like this:
let fetchRequest = NSFetchRequest(entityName: "Books")
var error: NSError?
var booksArray = context.executeFetchRequest(fetchRequest, error:&error)
if let error = error {
println("Unresolved error \(error), \(error.userInfo)")
abort()
}
for book in booksArray as [Books] {
let person = book.personRel as Person
println(person.namePerson)
println(person.idPerson)
}
If I have understood your question / data structure correctly, you will want to do something like:
let fetchRequest = NSFetchRequest(entityName: "Books")
let bookPersonPredicate = NSPredicate(format: "personRel.idPerson == %#", person.idPerson)
fetchRequest.predicate = bookPersonPredicate

Resources