core data simple fetch request template in swift - swift

Hi guys I fetched the data from core data using fetch request by programmatically ? my question is how to fetch data by using
fetchRequestTemplateForName ?

What you need to do is declare both managedObjectContext and managedObjectModel :
let context: NSManagedObjectContext = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
let model: NSManagedObjectModel = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectModel
Then you can simply use fetch request template that you created. If template name is "olderThen35" code looks like this:
let request = model.fetchRequestTemplateForName("olderThen35")!

Related

Fetching data from Core Data on application launch

I need to check for items in my Core Data when the app launches. this is what I wrote so far, but I don't think this is the best practice (although it is seems to be working) is there any other way? better way to acheive what I need?
func getMealsFromCoreData() -> [Meal]{
var retrivedMeals = [Meal]()
let appDelegate = UIApplication.shared.delegate as? AppDelegate
let managedContext = appDelegate?.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Meal")
do {
let result = try managedContext?.fetch(fetchRequest)
for data in result as! [NSManagedObject]{
retrivedMeals.append(data as! Meal)
}
}catch{
print("Failed to fetch.")
}
return retrivedMeals
}
func uploadMeals(){
var mealsToUpload = [Meal]()
let dispatchQueue = DispatchQueue(label: "mealQueue", qos: .background)
dispatchQueue.async {
mealsToUpload = self.getMealsFromCoreData()
for meal in mealsToUpload {
print(meal)
}
}
}
Upload meal should upload to meals to the screen after fetching everything (maybe not the best function name).
This is what I wrote in the AppDelegate in didFinishLaunchingWithOptions:
DataManager.manager.uploadReports()
I get in getMealsFromCoreData a purple warnning that says appDelegate should run on the main queue.
I'm really confused with this CoreData + Moving CoreData fetch from the main thread to the background.
Would really appericiate your help guys.
Am I doing something wrong? What is the best practice for this?
Well, the warning says what you are doing wrong.
The best practice depends on the use case. But it is certainly not fetching all data on application start. Fetch the data when you need it, as much data as you need (to display).
Maybe have a NSFetchedResultsController to maintain the data for your view if that is an option for you.

App delegate has no member persistentStoreCoordinator (remove from core data, swift)

Hi I want to remove a row from core data. I was able to remove the item from the table, but not from core data. A lot of places give the same answer to this question. But after struggling for hours and seeing all links from the first 20 pages of google search results, it is still not working.
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == UITableViewCellEditingStyle.delete {
foodItems.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: UITableViewRowAnimation.automatic)
}
let delegate = UIApplication.shared.delegate as! AppDelegate
let managedObjectContext = delegate.persistentContainer.viewContext
let coord = delegate.persistentStoreCoordinator // App delegate has no member persistentStoreCoordinator
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "ProductName")
let deleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
do {
try coord.executeRequest(deleteRequest, withContext: managedObjectContext)
} catch let error as NSError {
debugPrint(error)
}
}
I hope someone can help me. Thanks in advance.
The docs tell you how to update your in-memory objects: https://developer.apple.com/library/content/featuredarticles/CoreData_Batch_Guide/BatchDeletes/BatchDeletes.html
make sure the resultType of the NSBatchDeleteRequest is set to NSBatchDeleteRequestResultType.resultTypeObjectIDs before the request is executed.
do {
let result = try moc.execute(request) as? NSBatchDeleteResult
let objectIDArray = result?.result as? [NSManagedObjectID]
let changes = [NSDeletedObjectsKey : objectIDArray]
NSManagedObjectContext.mergeChangesFromRemoteContextSave(changes, [moc])
} catch {
fatalError("Failed to perform batch update: \(error)")
}
There are a few things going on here. You want to delete an entry. You need the managed object context, which you are already getting:
let managedObjectContext = delegate.persistentContainer.viewContext
You then appear to be trying to get an NSPersistentStoreCoordinator, which you don't need, and which causes your error message:
let coord = delegate.persistentStoreCoordinator // App delegate has no member persistentStoreCoordinator
You're getting this error message because your app delegate doesn't have a property called persistentStoreCoordinator. It's exactly as obvious as the error message sounds.
I'm not completely sure why you're trying to get a persistent store coordinator-- possibly because you're also trying to use a batch delete request even though you say you just want to delete a single row:
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "ProductName")
let deleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
If you run that request and it succeeds, you will delete every instance of ProductName, not just the one row. You're not telling the request to filter the objects and find only one (or a few). Instead you've set up a batch request that will hit every single instance instead of the selected row.
You could fix the batch request by adding a predicate, but that would be a very unusual way to delete a single row. Generally, you fetch a bunch of managed objects, and if you want to delete one, you tell the managed object to delete that object. There's no need for a batch request on a single object.
If your foodItems array contains instances of NSManagedObject (or subclasses of NSManagedObject), a better approach would be to use the managed object context, which has a delete method. Get the object at foodItems[indexPath.row] and pass it directly to the delete method.

Swift and Firebase 3.x saving and retrieving data

I'm saving data in one view with the following code:
let item1:String = textfield.text!
if TextField1.text != "" {
self.ref.child("userProfile").child((user!.uid)/value1Total").setValue(Double(item1)!)
}
What would be my code in a different view to set that saved value to a label?
You can try like below example:
let name = nameTextField.text
let user: NSDictionary = ["name":name!,"dob":dateOfBirthTimeInterval]
//add firebase child node
let profile = firebase.ref.childByAppendingPath(name!)
// Write data to Firebase
profile.setValue(user)
Have a look on it this link for more info

Request just one attribute of a entity

So I am using one core data file with a single one entity named BookArray, inside that entity I have four different attributes, what I want to do is to request just one of those attributes from the entity not all. Is it possible?
var appDel: AppDelegate = (UIApplication.sharedApplication().delegate as! AppDelegate)
var context:NSManagedObjectContext = appDel.managedObjectContext!
var request = NSFetchRequest(entityName: "BookArray")
request.returnsObjectsAsFaults = false
bookArray = context.executeFetchRequest(request, error: nil)!
Suppose I have an attribute called sciFi and another named drama, how would I request just the drama attribute?
You can, by adding:
request.propertiesToFetch = ["drama"]
request.resultType = .DictionaryResultType
but, unless your other properties are big, it's unlikely to be worthwhile: your bookArray will then contain an array of dictionaries, from which you will need to unpack the relevant values: you might just as well do that directly from the array of NSManagedObjects returned by a normal fetch.

Using a boolean attribute in Core Data Swift

I am new to core Data and I want to create a boolean atribute to my App. My entity is RemoveAds and the atribute is isAdRemoved. I want it to inicialize it to false if the ad was not removed yet, but when he press a button to remove the ad it turns into true, any suggestions?
Obs: I have all my IAP setup, this is not the issue here
Update 1:
func removeallAds() {
var appDel: AppDelegate = (UIApplication.sharedApplication().delegate as AppDelegate)
var context:NSManagedObjectContext = appDel.managedObjectContext!
let entity = NSEntityDescription.entityForName("RemoveAds", inManagedObjectContext: context)
let newObject = NSManagedObject(entity: entity!, insertIntoManagedObjectContext: context) as RemoveAds
newObject.isAdRemoved = false
}
When you add a new object to CoreData, then you also initialize the attributes, e.g. to set your attribute default-wise to false use:
let entity = NSEntityDescription.entityForName("RemoveAds", inManagedObjectContext: managedContext)
let newObject = NSManagedObject(entity: entity, insertIntoManagedObjectContext:managedContext)
newObject.setValue(false, forKey: "isAdRemoved")
Once you received a button press, search for the corresponding object and set its property to true, again with setValue.
There is also a some tutorials for CoreData and Swift e.g. Your First Core Data App Using Swift.
Are you just trying to save a global app preference? If so, NSUserDefaults is likely a far better choice than Core Data.
http://ios-blog.co.uk/tutorials/quick-tips/storing-data-with-nsuserdefaults/ https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSUserDefaults_Class/index.html