Request just one attribute of a entity - swift

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.

Related

Core Data - Adding Multiple Child Entities To An Array

I am trying to build a to-do list app.
So far I have an entity for storing categories. Within the category entity, it has 3 relationships. One to a task entity, one to an event entity and one to a reminder entity.
In my app, I would like to be able to go into a category and see a tableView filled with tasks, reminders, and events.
So far, my tableView works with just have one child entity. This so done through the following code:
func loadEvents(with request: NSFetchRequest<Event> = Event.fetchRequest()) {
let predicate = NSPredicate(format: "parentCategory.name MATCHES %#", selectedCategory!.name!)
request.predicate = predicate
do {
itemsArray = try context.fetch(request)
} catch {
print(error)
}
print(itemsArray)
tableView.reloadData()
}
The problem happens when I try to add all 3 child types to the same array. Nothing shows up in the table view. (I have support for multiple cell types in my table view too.)
I have tried this code:
func loadItems(with request: NSFetchRequest<Task> = Task.fetchRequest()) {
itemsArray = []
let taskRequest: NSFetchRequest<Task> = Task.fetchRequest()
let predicate = NSPredicate(format: "parentCategory.name MATCHES %#", selectedCategory!.name!)
taskRequest.predicate = predicate
let eventRequest: NSFetchRequest<Event> = Event.fetchRequest()
eventRequest.predicate = predicate
do {
itemsArray.append(try context.fetch(taskRequest))
itemsArray.append(try context.fetch(eventRequest))
} catch {
print(error)
}
print(itemsArray)
tableView.reloadData()
}
But my table view just appears empty. My array is also an array of Any.
Any help on how to add the different child entities to the same array would be greatly appreciated. :)

Calling a Core Data attribute through a relationship

I have two Entities as depicted in the image below:
Food and Restaurant.
I know the naming is a bit off for now, but basically, I'm building up a list of Food items. A user will add in a new entry with the name of the food and the name of the restaurant. I'm at the very early stages of development.
So in the AddViewController, and in the save method, I have:
if let appDelegate = (UIApplication.shared.delegate as? AppDelegate) {
foodEntry = FoodManagedObject(context: appDelegate.persistentContainer.viewContext)
foodEntry.nameOfFood = foodNameTextField.text
foodEntry.restaurantName?.nameOfRestaurant = restaurantNameTextField.text
With a variable declared:
var foodEntry:FoodManagedObject!
In the TimelineView, using NSFetchedResultsController, I'm fetching for the FoodManagedObject and able to display the name of the food in the label. However, the name of the restaurant doesn't display.
So, I'm fetching appropriately:
let fetchRequest: NSFetchRequest<FoodManagedObject> = FoodManagedObject.fetchRequest()
let sortDescriptor = NSSortDescriptor(key: "nameOfFood", ascending: true)
fetchRequest.sortDescriptors = [sortDescriptor]
if let appDelegate = (UIApplication.shared.delegate as? AppDelegate) {
let context = appDelegate.persistentContainer.viewContext
fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
fetchedResultsController.delegate = self
do {
try fetchedResultsController.performFetch()
if let fetchedObjects = fetchedResultsController.fetchedObjects {
foods = fetchedObjects
}
} catch {
print(error)
}
}
and in the cellForRow:
cell.foodNameLabel.text = foods[indexPath.row].nameOfFood
cell.restaurantLabel.text = foods[indexPath.row].restaurantName?.nameOfRestaurant
I get no errors, but the name of the restaurant never displays.
Foods is:
var foods:[FoodManagedObject] = []
So I've tried adding in an attribute called theRestaurant into the Food Entity and that works, but calling through a relationship never seems to work.
Am I missing something obvious here?
You're creating relations between the objects, not of their values
It means, that you must assign already existing restaurant entity object or create the new one when you're saving the new food object.
You can't just assign object values without an initialisation of the restaurant object.
E.g.
foodEntry = FoodManagedObject(context: appDelegate.persistentContainer.viewContext)
foodEntry.nameOfFood = foodNameTextField.text
// Here you must to load existing Restaurant entity object from database or create the new one
let restaurant = RestaurantManagedObject(context: appDelegate.persistentContainer.viewContext)
restaurant.nameOfRestaurant = restaurantNameTextField.text
foodEntry.restaurantName = restaurant // Object instead of value
Or if you already have some list of restaurants, than just add the new food object to one of them

core data simple fetch request template in 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")!

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

how would i skip displaying certain entries when populating cell rows from core data in a tableviewcontroller?

For an app I'm working on, i have saved several items to my coredata model.
My intention is to selectively print them out to a tableview based on whether certain attributes are true.
Example given the items in CoreData:
/////////////////////
1--name: Joe, display: true
2--name: Sally, display:false
3--name: Bob, display:false
4--name: Jess, display:true
/////////////////////
i would only want my table view to display to cells where display is true
so out of the 4 entries only Joe and Jess would be listed in my tableview
So far, I only know how to print out every single item. with the table view datasource protocol
thanks for helping out a noob!
I would do something like this:
// Your Entity here is called "Users"
var myUsers = [Users]()
var fetchRequest = NSFetchRequest(entityName: "Users")
let Predicate = NSPredicate(format: "display = %#", true)
fetchRequest.predicate = Predicate
// maybe Sort?
var sortDescriptor = NSSortDescriptor(key: "UserID", ascending: true)
var sortDescriptors = [sortDescriptor]
fetchRequest.sortDescriptors = sortDescriptors
myUsers = context!.executeFetchRequest(fetchRequest, error: nil) as [Users]
// use them in your TableView (cellForRowAtIndexPath)
var myuser = myUsers[indexPath.row] as Users
You should use a NSFetchedResultsController to display the Core Data objects in a
table view.
Restricting the displayed items is then simply done by setting a predicate
NSPredicate(format: "display == YES")
on the fetched results controller.