Get fields from NSArray with CoreData content - ios

I have a table in core data with some fields, I can get the count of records, but I canĀ“t get the values from each field, now I have this code:
var request:NSFetchRequest = NSFetchRequest(entityName: "Radar") //my table in core data
let appDelegate:AppDelegate = (UIApplication.sharedApplication().delegate as! AppDelegate)
let context:NSManagedObjectContext = appDelegate.managedObjectContext!
request.returnsObjectsAsFaults = false
var results:NSArray = context.executeFetchRequest(request, error: nil)!
println(results.count) //this is the count that i can do
I need some more,
Radar have this fields: Descr,Latit,Long
I need get this fields to create an annotation
some like this: results.Descr

You will need to loop your array of results and cast each result as the NSManagedObject you retrieved, in you case Radar
if results.count > 0
{
for result in results
{
if let r = result as? Radar{
//now you can access the properties of Radar in r
println(r.descr)
} else{
println("Could not cast fetch result to Radar")
}
}
}

Related

Getting objects from NSSet and populating TableView

I have this piece of code as shown below
func getItemsOnList(){
let app = UIApplication.shared.delegate as! AppDelegate
let context = app.persistentContainer.viewContext
//fetchRequest to get the List
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "List")
let predicate = NSPredicate(format: "title == %#", listName)
fetchRequest.returnsObjectsAsFaults = false
fetchRequest.predicate = predicate
if let fetchResults = try? context.fetch(fetchRequest){
if fetchResults.count > 0 {
for listEntity in fetchResults {
let list = listEntity as! List
print(list.title as Any)
itemsOnListSet = list.contains!
What this does is it gets the Items from the specified List using the .contains relationship between the two entities, and saves all the items in to an NSSet.
What i want to do is to populate a TableView with the objects that are in the NSSet.
Is there a function related to NSSet which allows me to get the items from the set? Or should i save the items in an Array instead of an NSSet.
P.S. the .contains relationship is of type NSSet
#NSManaged public var contains: NSSet?
why don't you convert the Set to Array using,
if let _ = list.contains {
let itemsOnListArray = list.contains!.allObjects
}
else
if let unwrappedList = list.contains {
let itemsOnListArray = unwrappedList.allObjects
}
Now use your itemsOnListArray as your tableView's data source :)
EDIT:
Your code
let item = itemsOnListArray[indexPath.row]
cell.textLabel?.text = item as? String
Assumes itemsOnListArray is a array of strings!!! Which is absolutely impossible because list.contains! is a set of NSManagedObjects or if you created mapped subclasses of ManagedObjects than it will contain a set of your managed objects like items.
What you should be doing is (because you have not provided the description of item am assuming item has a name property in it)
let item = itemsOnListArray[indexPath.row] as! Item
cell.textLabel?.text = item.name

How to make simple join in relationship of Core Data Swift

I have Core Data with relationship:
extension Rating {
#NSManaged var date: NSString?
#NSManaged var rating: NSNumber?
#NSManaged var ratenames: RateNames?
}
extension RateNames {
#NSManaged var name: String?
#NSManaged var rating: NSSet?
}
And I need to select all values from RateNames with all data from Rating linked to RateNames from a selected date.
For example RateNames data:
name=a; name=b;
For example RateNames data:
date=10-02-2016; rating=5; linked to a
date=10-02-2016; rating=3; linked to b
date=09-02-2016; rating=2; linked to a
date=08-02-2016; rating=3; linked to a
date=08-02-2016; rating=1; linked to b
For example I need result for 08-02-2016
Result should be:
{(name:a, date:08-02-2016, rating=3), (name:b, date:08-02-2016, rating=1)}
result for 09-02-2016 date should be the following:
{(name:a, date:09-02-2016, rating=2), (name:b, date:nil, rating=nil)}
I also do need b in results because I need to see whether it is null or not.
I am trying to do something like:
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
let fetchRequest = NSFetchRequest(entityName: "RateNames")
do {
let results = try managedContext.executeFetchRequest(fetchRequest)
for result in results {
let child = result. ..some var here.. as! Rating
But cannot get how to implement this
It's easier to get what you want by fetching the Rating objects, and using the relationship to get the name of the related RateName objects:
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
let fetchRequest = NSFetchRequest(entityName: "Rating")
do {
let results = try managedContext.executeFetchRequest(fetchRequest) as! [Rating]
for result in results {
let name = result.ratenames.name
let date = result.date
let rating = result.rating
print("name:\(name), date:\(date), rating:\(rating)")
}
}
This will print results similar to your expected results, though it won't include the (name:b, date:nil, rating=nil).
Update
If you want to limit the above to a given date, you can use a predicate for the fetch request:
fetchRequest.predicate = NSPredicate(format:"date == %#", chosenDate)
But since you want to include, (name:b, date:nil, rating=nil), you will need to fetch ALL the RatingName objects. The rating property of each object will include any and all Ratings to which it is related. So I think you will then need to filter them to identify any for the correct date:
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
let fetchRequest = NSFetchRequest(entityName: "RateNames")
do {
let results = try managedContext.executeFetchRequest(fetchRequest)
let datePredicate = NSPredicate(format:"date == %#", chosenDate)
for result in results {
let filteredRatings = result.rating.filteredSetUsingPredicate(datePredicate)
if filteredRatings.count > 0 {
let rating = filteredRatings.anyObject()
print("name:\(result.name), date:\(rating.date), rating:\(rating.rating)")
} else {
print("name:\(result.name), date:nil, rating:nil")
}
}
}
This assumes there can be only one Rating for each RatingName for a given date; if not you will have to iterate through the filteredRatings set.
you need to just setup relationship in Datamodel like i have created for following example
From your code i found that you didn't mentioned One-to-Many Relationship .
Then create again sub class of NSManageObject. xCode will create all needed variables for same.

IOS - AnyObject is not convertible to String when loading core data into a table view?

I use Swift. I can save data into a core data base. And I can even print out the data in a for loop but I can't load it into a table view. I have an empty string array(called subjects) that the table view uses it as a data source but I would like to load the data in a for loop into that array.
Here's how I save the data:
var appDel:AppDelegate = (UIApplication.sharedApplication().delegate as AppDelegate)
var context:NSManagedObjectContext = appDel.managedObjectContext!
var newSubject = NSEntityDescription.insertNewObjectForEntityForName("Subjects", inManagedObjectContext: context) as NSManagedObject
newSubject.setValue("" + classTextField.text, forKey: "subjectName")
context.save(nil)
Here's how I retrieve the data:
I have an empty string array in the class called subjects.
var appDel:AppDelegate = (UIApplication.sharedApplication().delegate as AppDelegate)
var context:NSManagedObjectContext = appDel.managedObjectContext!
var request = NSFetchRequest(entityName: "Subjects")
request.returnsObjectsAsFaults = false
var results:NSArray = context.executeFetchRequest(request, error: nil)!
if(results.count > 0){
for res in results{
println(res)
subjects.append(res)
}
}else{
println("0 Results.")
}
So, I can print out the data as you can see in the for loop, but I can't add that res value into my subjects array which is used by the table view. But I get the AnyObject is not convertible to String error message.
Edit:
Sorry, I misunderstood the code.
You need to unwrap the results to an array of Subjects
if let resultsUnwrapped = results as? [Subjects] {
for res in resultsUnwrapped{
println(res.description())
subjects.append(res.subjectName)
}
}

Swift - Core Data return all rows for attribute

I'd like to return all rows for a given attribute stored in my core data entity. I know how to retrieve rows based on a filtered predicate, but I would like to be able to return all of the rows without specifying a value for the predicate. The code I'm currently using is as follows:
func getUsername() -> NSString {
var appDel: AppDelegate = (UIApplication.sharedApplication().delegate as AppDelegate)
var context:NSManagedObjectContext = appDel.managedObjectContext!
var request = NSFetchRequest(entityName: "User")
//request.returnsObjectsAsFaults = false
//request.predicate = NSPredicate(format: "fstrUsername = %#", pstrUsername)
var results:NSArray = context.executeFetchRequest(request, error: nil)!
if results.count > 0 {
var res = results[0] as NSManagedObject
return res.valueForKey("fstrUsername") as NSString
}
else {
return "false"
}
}
Can anyone tell me how to return all rows for an attribute without having to specify a full or partial value to match on in the predicate? Thanks in advance.
Just remove the predicate code and you will retrieve all the rows!

Core Data: How do I delete all objects with an attribute in Swift?

Say for simplicity that I have an entity named DOWJONES. There are two attributes for every object ex AAPL and AAPL_NSDate. ValueForKey:AAPL returns the stock price history and ValueforKey AAPL_NSDate the corresponding date.
How can I delete the stockprice history and corresponding date quickly and efficiently in swift?
This is how I query:
var appDel:AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate
let context = (UIApplication.sharedApplication().delegate as AppDelegate).managedObjectContext!
var request = NSFetchRequest(entityName: "DOWJONES")
request.returnsObjectsAsFaults = false
var dowjones = context.executeFetchRequest(request, error: nil)! as [DOWJONES]
var aapl = (dowjones as NSArray).valueForKey("AAPL") as NSArray
As suggested from #chris-wagner this is how I could iterate over the results and delete.
func deleteCoreDataObjects(){
var request = NSFetchRequest(entityName: "DOWJONES")
request.returnsObjectsAsFaults = false
var dowjones = context.executeFetchRequest(request, error: nil)!
if dowjones.count > 0 {
for result: AnyObject in dowjones{
context.deleteObject(result as NSManagedObject)
println("NSManagedObject has been Deleted")
}
context.save(nil)
}
}
You can do batch requests directly onto the data store as of iOS 8, using NSPersistentStoreCoordinator's executeRequest(_ request: NSPersistentStoreRequest, withContext context: NSManagedObjectContext, error error: NSErrorPointer) method.
You create the persistent store request similarly to a fetch request, then pass it to the PSC using the above method.
Note however that you shouldn't have any in-context references to objects you're deleting with this method.
There's a nice explanation of it here.
Iterate over the results from your fetch request and call self.context.deleteObject(_:) on each one.

Resources