Get last inserted item from Core Data, iOS - iphone

is there a way to get the last inserted item in a core data database?

This returns the very last inserted object.
setFetchLimit:1 and setFetchOffset:[number of all entries - 1]

Method 1:
I've extended #Olsi answer with sample code including the line to get number of all entities. Here's how I've done it:
let appDelegate: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let context: NSManagedObjectContext = appDelegate.managedObjectContext
let request = NSFetchRequest(entityName: "MyEntity")
let allElementsCount = context.countForFetchRequest(request, error: nil)
request.fetchLimit = 1
request.fetchOffset = allElementsCount - 1
request.returnsObjectsAsFaults = false
Method 2:
Howerver there's another approach using sortDescriptors. Not sure which is better fit, they both do the same job:
let appDelegate: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let context: NSManagedObjectContext = appDelegate.managedObjectContext
let request = NSFetchRequest(entityName: "MyEntity")
request.sortDescriptors = [NSSortDescriptor(key: "momentTimeStamp", ascending: false)]
request.fetchLimit = 1
request.returnsObjectsAsFaults = false

I don't think this is supported natively by Core Data. I guess your best bet is to add a "dateInserted" attribute to your entity.

Related

NSSortDescriptor has no effect on Core Data fetch request

My Core Data entity "Entry" has 4 attributes, including the attribute "key", which I want to sort by. "key" is non-optional and unique. Core Data structure:
I am fetching objects from Core Data like this:
var entries: [NSManagedObjectID : NSManagedObject] = [:]
class func fetchEntriesfromPersistentStore () {
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
let managedContext = appDelegate.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "Entry")
let sort = NSSortDescriptor(keyPath: \Entry.key, ascending: true)
fetchRequest.sortDescriptors = [sort]
do {
let fetchesEntries = try managedContext.fetch(fetchRequest)
entries = Dictionary(uniqueKeysWithValues: fetchesEntries.map{ ($0.objectID, $0) })
} catch let error as NSError {
print("Could not fetch entries. \(error), \(error.userInfo)")
}
}
I also tried the following initialisation of the NSSortDescriptor like in the official documentation:
let sort = NSSortDescriptor(key: "key", ascending: true)
The resulting dictionary is always in random order, i.e. in different order on every execution. I confirmed that code above is executed. Removing the NSSortDescriptor also has no effect on the results.
I inspected the list fetchesEntries before the objects are stored in the dictionary, and it is not sorted.
iOS Deployment Target is 13.4, Swift 5.0, Xcode 11.5, macOS 10.15.5
try
let sort = NSSortDescriptor(key: #keyPath(Entry.key), ascending: true)

swift code core data fetchrequest

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)
}
}
}

NSFetchRequest ReturnsDistinctResults gives empty results

I am trying to filter out the duplicate items in a result from a fetchRequest. I use the following code:
let sortDescriptor = NSSortDescriptor(key: "lastupdate", ascending: false)
let sortDescriptors = [sortDescriptor]
var appDel:AppDelegate = (UIApplication.sharedApplication().delegate as! AppDelegate)
var context:NSManagedObjectContext = appDel.managedObjectContext
let fetchRequest = NSFetchRequest(entityName:"Details")
fetchRequest.sortDescriptors = sortDescriptors
fetchRequest.propertiesToFetch = [ "orig_id" ]
fetchRequest.resultType = NSFetchRequestResultType.DictionaryResultType
fetchRequest.returnsDistinctResults = true
let company_temp = try context.executeFetchRequest(fetchRequest)
let company = company_temp as! [Details]
for t in company {
let id = t.orig_id
print(id)
self.myarray.append("\(id)")
}
When I comment out these 3 lines:
fetchRequest.propertiesToFetch = [ "orig_id" ]
fetchRequest.resultType = NSFetchRequestResultType.DictionaryResultType
fetchRequest.returnsDistinctResults = true
I get 8 items in my array. What is wrong with my code?
Did you save your context?
I had the same problem. When you have unsaved changes, the NSDictionaryResultType does not reflect the current state of the persistent store. See Apple Docs about the includesPendingChanges: method.
So a simple context.save() before your code might fixes your problem.
Another problem is that this line will crash: let company = company_temp as! [Details] since you'll get a Dictionary back. Not a list of NSManagedObject.

How to retrieve CoreData that satisfies a condition swift 2

I have a DB with fields like below
Latitude Longitude Flag
54.1425 98.2564 0
52.1036 94.1458 3
51.1569 92.1458 3
50.1326 91.1458 3
56.1236 93.1458 0
I need to retrieve records that have flag as 3.
let fetchRequest = NSFetchRequest()
let appDelegate =
UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
let entityDescription = NSEntityDescription.entityForName("TABLE_LOCATION", inManagedObjectContext: managedContext)
// Configure Fetch Request
fetchRequest.entity = entityDescription
do {
let result = try managedContext.executeFetchRequest(fetchRequest)
//print(result)
} catch {
let fetchError = error as NSError
print(fetchError)
}
All i have is the above code that retrieves all records from the table TABLE_LOCATION any code or working example is much appreciated
Thanks!
You need to add a NSPredicate to your fetchRequest.
https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSPredicate_Class/
fetchRequest.predicate = NSPredicate(format: "flag == %#", "3")
You can use a NSPredicate and set it to the fetchRequest. Create a NSPredicate and set it to the fetchRequest before you execute the fetch request.
fetchRequest.predicate = NSPredicate(format: "flag = 3")
Change Your function to:
func fetchDistinctDataUsingReq(predicate :NSPredicate) -> NSArray {
let fetchRequest = NSFetchRequest()
fetchRequest.predicate = predicate
//Rest of your code
}
Now call this function from using:
let predicate = NSPredicate(format: "flag == %#", 3)
self.fetchDistinctDataUsingReq(predicate)
This is a much better approach and can be reused across fetching. Additionally you can pass the CoreData Table as parameter along with predicate to generalize it.

saving, deleting and fetching data from a one to many relationship core data

I have created a data model like so:
I have this code for a fetch request:
func roundFetchRequest() -> NSFetchRequest {
let fetchRequest = NSFetchRequest(entityName: "Customer")
print("Check here: \(myRoundIndexPath)")
//let predicate : NSPredicate = NSPredicate(format: "custRoundRel = %#", frc2.objectAtIndexPath(myRoundIndexPath!) as! RoundName) //ASSUME THIS IS CORRECT
let sortDescriptor = NSSortDescriptor(key: "c2fna", ascending: true)
//fetchRequest.predicate = predicate
fetchRequest.sortDescriptors = [sortDescriptor]
return fetchRequest
}
My commented out code does not give an error, but I cannot seem to save a customer to the RoundName instance. When I save a customer with its attributes, I have used this code:
func newCust() {
let cont = self.context
let newCustomer = NSEntityDescription.entityForName("Customer", inManagedObjectContext: cont)
let aCust = Customer(entity: newCustomer!, insertIntoManagedObjectContext: cont)
aCust.c2fna = firstName.text
aCust.c3lna = lastName.text
aCust.c4tel = tel.text
aCust.c5mob = mob.text
aCust.c6ema = email.text
aCust.c7hsn = houseNo.text
aCust.c8fir = street.text
aCust.c9sec = secondLine.text
aCust.c10ar = area.text
aCust.c11pc = postcode.text
aCust.c12cos = cost.text
aCust.c13fq = frequencyNumber.text
aCust.c14fqt = frequencyType.text
let DF = NSDateFormatter()
aCust.c15das = DF.dateFromString(startDate.text!)
//Do Pics in a minute & next date in a minute
aCust.c17notes = notes.text
//print("Desc = \(picRound.image?.description)")
do {
try context.save()
print("Save Successful")
} catch {
print("Save Unsuccessful")
}
}
What is the code to link this customer with the correct Round?
Thanks, I am very new to core data and really would appreciate any help.
Yes, you use a predicate on your fetch request, with a format like
NSPredicate(format:"custRoundRel = %#", xxxx)
where xxxx is the Round instance.
You can also just use the roundCustRel relationship depending on what you want to do with the Customer instances and how many there are.
You create Customer objects in the same way you create other managed objects. To link a customer with the correct Round object, just set the to-one relationship (Core Data will automatically set the reverse relationship for you).
newCustomer.round = round
// or, with your arcane attribute names
newCustomer.custRoundRel = theDesiredRoundObject
To get to the customers of one specific round, you do not need fetch requests or predicates.
round.customers
// or, with your arcane attribute names
round.roundCustRel