swift code core data fetchrequest - swift

I'm going crazy trying to retrieve a fact for a given question in Core data. The code I'm using is below and what I'd like to do is let the user select a "question" and see the related "facts" for it.
I'm going around in circles trying to do this. Can anyone explain to me what I'm missing? Thank you
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let managedContext = appDelegate.persistentContainer.viewContext
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "BadHusband")
request.predicate = NSPredicate(format: "question= %#", itemSelected)
request.returnsObjectsAsFaults = false
do {
let results = try managedContext.fetch(request)
stuff = results as! [NSManagedObject]
if results.count > 0 {
for result in results as! [NSManagedObject] {
if let question = result.value(forKey: "question"), let facts = result.value(forKey: "facts") {
print(question)
print(facts)
}
}
}

Related

core data fetch with filter

I'm trying to add a filter (boolean value) to a fetch in core data, but I'm not sure how.
The entity name is Vinyl and the attribute that I want to use to filter is called wishlist (true or false)
if let context = (UIApplication.shared.delegate as? AppDelegate)?.persistentContainer.viewContext {
if let vinyls = try? context.fetch(Vinyl.fetchRequest()) {
if let theVinyls = vinyls as? [Vinyl] {
self.allVinyls = theVinyls
totalVinyls = theVinyls.count
}
}
}
How can I filter for wishlist == true ?
Add an appropriate predicate.
All if lets are not necessary, the viewContext is supposed to be non-optional.
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let request : NSFetchRequest<Vinyl> = Vinyl.fetchRequest()
let predicate = NSPredicate(format: "wishlist == TRUE")
request.predicate = predicate
do {
self.allVinyls = try context.fetch(request)
totalVinyls = self.allVinyls.count
} catch { print(error) }

Edit value for core data key for certain id

I have a Core data entity that is made of id and detailText. The idea is that my textfield stores it's content alongside certain id that is a timestamp in my case. Now when the user stores the detailText for the first time it works as it should, but if the user edits the detailText for the specific id, I want to remove the old detailText and put the new detailText.
Basically I need help with writing the query below in Swift/Core data.
UPDATE myEntity SET detailText = theNewDetailText WHERE ID = myID;
These are my current save and replace function, I use predicate to find select my id but I'm having trouble updating the corresponding detailText field for the certain ID.
func saveTextFromTextFieldToCoreData(textToSave: String){
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
let entityDescription = NSEntityDescription.entityForName("GoalDetail", inManagedObjectContext:managedContext)
let thingToSaveToCD = NSManagedObject(entity: entityDescription!, insertIntoManagedObjectContext: managedContext)
print("received text to store and it's \(textToSave)")
if entityIsEmpty("GoalDetail") == true {
thingToSaveToCD.setValue(data.timeStamp, forKey: "id")
thingToSaveToCD.setValue(textToSave, forKey: "detailText")
print("succesfully saved \(data.timeStamp) and \(textToSave)")
} else {
replaceTheValueFromCoreData()
}
}
func replaceTheValueFromCoreData(){
print("i have entered the delete core data item")
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
let fetchRequest = NSFetchRequest(entityName: "GoalDetail")
let predicate = NSPredicate(format: "id == %#", data.timeStamp)
fetchRequest.predicate = predicate
//let entityDescription = NSEntityDescription.entityForName("GoalDetail", inManagedObjectContext:managedContext)
//let thingToSaveToCD = NSManagedObject(entity: entityDescription!, insertIntoManagedObjectContext: managedContext)
do{
let goal = try appDelegate.managedObjectContext.executeFetchRequest(fetchRequest)
try managedContext.save()
}
catch{
//error
}
I've been through google and stack overflow but so far haven't managed to execute this so any help is greatly appreciated.
I've solved it
func saveTextFromTextFieldToCoreData(textToSave: String){
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
let entityDescription = NSEntityDescription.entityForName("GoalDetail", inManagedObjectContext:managedContext)
let thingToSaveToCD = NSManagedObject(entity: entityDescription!, insertIntoManagedObjectContext: managedContext)
//clumsy named entity is empty returns if there is already
// an ID / data.timeStamp in that entity so that I can
// either save or replace the data
print("received text to store and it's \(textToSave)")
if entityIsEmpty("GoalDetail") == true {
thingToSaveToCD.setValue(data.timeStamp, forKey: "id")
thingToSaveToCD.setValue(textToSave, forKey: "detailText")
print("succesfully saved \(data.timeStamp) and \(textToSave)")
} else {
replaceTheValueFromCoreData()
print("ovo tribq prominiti")
}
}
func replaceTheValueFromCoreData(){
print("i have entered the delete core data item")
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
let fetchRequest = NSFetchRequest(entityName: "GoalDetail")
let predicate = NSPredicate(format: "id == %#", self.data.timeStamp)
fetchRequest.predicate = predicate
do {
if let fetchResults = try appDelegate.managedObjectContext.executeFetchRequest(fetchRequest) as? [NSManagedObject] {
if fetchResults.count != 0{
var managedObject = fetchResults[0]
managedObject.setValue(self.trextViewForGoal.text, forKey: "detailText")
try managedContext.save()
}
}}
catch let error as NSError {
// failure
print("Fetch failed: \(error.localizedDescription)")
}
}

iOS Core Data: Convert result of fetch request to an array

I'm trying to put the results of a fetch request into an array. My code:
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
let fetchRequest = NSFetchRequest(entityName: "CLIENTS")
var mobClients = [NSManagedObject]()
var arrayAllPhoneNumbers = [String]()
do {
let results = try managedContext.executeFetchRequest(fetchRequest)
mobClients = results as! [NSManagedObject]
for clientPhoneNumber in mobClients {
let myClientPhoneNumber = clientPhoneNumber.valueForKey("clientsMobilePhoneNumber") as! String
print(myClientPhoneNumber)
//The numbers print out just fine, one below the other
//
//Now the results need to go into the array I've declared above ---> arrayAllPhoneNumbers
messageVC.recipients = arrayAllPhoneNumbers // Optionally add some tel numbers
}
} catch
let error as NSError {
print("Could not fetch \(error), \(error.userInfo)")
}
As illustrated, all the phone numbers needs to be captured in an array. How do I accomplish that?
Instead of your for-loop and the code inside it, use this:
arrayAllPhoneNumbers = mobClients.map({ clientPhoneNumber in
clientPhoneNumber.valueForKey("clientsMobilePhoneNumber") as! String
})
messageVC.recipients = arrayAllPhoneNumbers
let request = NSFetchRequest(entityName: "CLIENTS")
let results = (try? managedContext.executeFetchRequest(request)) as? [NSManagedObject] ?? []
let numbers = results.flatMap { $0.valueForKey("clientsMobilePhoneNumber" as? String }
numbers is now an array of your phone numbers.
But like thefredelement said, it's better to subclass it so you can just cast it to that subclass and access the phone numbers directly.
Swift 5 : flatMap is deprecated, use compactMap
let request = NSFetchRequest(entityName: "CLIENTS")
let results = (try? managedContext.executeFetchRequest(request)) as? [NSManagedObject] ?? []
let numbers = compactMap { $0.valueForKey("clientsMobilePhoneNumber" as? String }

How to test if ManagedObject is nil

I have a question, I would like to test is my managedObject is empty then generate my CoreData.
let fetchRequest = NSFetchRequest(entityName: "Adresses")
let results = try managedContext.executeFetchRequest(fetchRequest)
AdressesProjecteurs = results as! [NSManagedObject]
print(AdressesProjecteurs)
if (AdressesProjecteurs.managedContextTmp == nil) {
saveName()
}
My if condition is generating a error, so, how to test if my AdressesProjecteurs is empty ?
Thank you
just don't save empty objects and then check if there IS an object saved after all
//check if it was NEVER saved
let fetchRequest = NSFetchRequest(entityName: "Adresses")
let results = try managedContext.executeFetchRequest(fetchRequest)
AdressesProjecteurs = results as! [NSManagedObject]
print(AdressesProjecteurs)
if (AdressesProjecteurs.count == 0) {
saveName()
}

Swift: How to filter in Core Data

I'm using the following code to fetch all the data in "category".
let appDelegate = UIApplication.sharedApplication().delegate as AppDelegate
let managedContext = appDelegate.managedObjectContext!
let fetchRequest = NSFetchRequest(entityName:"category")
let fetchedResults = managedContext.executeFetchRequest(fetchRequest, error: &error) as [NSManagedObject]?
How do I only brings categories where the "type" is equal to "products"?
To "filter" results in Core Data, use NSPredicate like so:
let filter = "products"
let predicate = NSPredicate(format: "type = %#", filter)
fetchRequest.predicate = predicate
So, in the below example
In the first step, we will add give the value we want to filter.
In the second step, we will add a predicate in which we will give the DB key we want to get the value in my case is "id" and besides this a value, we want to filter.
In the Third step assign the entity name where your all data has saved in the NSFetchRequest.
After that assign the predicate.
Use context object to fetch the object.
private let context = (NSApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let filter = id
let predicate = NSPredicate(format: "id = %#", filter)
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName:"TodoListItem")
fetchRequest.predicate = predicate
do{
let fetchedResults = try context.fetch(fetchRequest) as! [NSManagedObject]
print("Fetch results")
if let task = fetchedResults.first as? TodoListItem{
print(task)
}
// try context.save()
}catch let err{
print("Error in updating",err)
}
You can use .filter on the fetchedResults.