NSSortDescriptor case sensitivity in Swift 4.2 - nssortdescriptor

I am trying to sort alphabetically without case sensitivity using NSSortDescriptor is Swift 4.2. Unfortunately, I have only found solutions in Objective-C.
func fetchRequest() -> NSFetchRequest<NSFetchRequestResult> {
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Entity")
let sorter = NSSortDescriptor(key: "texttitle", ascending: true)
fetchRequest.sortDescriptors = [sorter]
return fetchRequest
}

Using
caseInsensitiveCompare: (with the colon) does not work in Swift 4.2.
This works:
func fetchRequest() -> NSFetchRequest<NSFetchRequestResult> {
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Entity")
let sorter = NSSortDescriptor(key: "texttitle", ascending: true, selector: #selector(NSString.caseInsensitiveCompare))
fetchRequest.sortDescriptors = [sorter]
return fetchRequest
}

Related

Core Data - NSFetchedResultsController using NSPredicate

I have Parent entity called Card and child entity CardHistoryItem with the to-many relationship. I'm trying to fetch histories for my current selected card, but it returns nothing just empty array.
My code:
lazy var cardHistoryItemsFRC: NSFetchedResultsController<CardHistoryItem> = {
let fetchRequest = NSFetchRequest<CardHistoryItem>(entityName: "CardHistoryItem")
if let currentCard = self.currentEntity as? Card {
fetchRequest.predicate = NSPredicate(format: "card = %#", currentCard)
}
let sort = NSSortDescriptor(key: "date", ascending: true)
fetchRequest.sortDescriptors = [sort]
fetchRequest.returnsObjectsAsFaults = false
let mainContext = CoreDataController.sharedInstance.mainContext
let frc = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: mainContext, sectionNameKeyPath: nil, cacheName: nil)
frc.delegate = self
do {
try frc.performFetch()
} catch {
fatalError("NSFetchedResultsController perform fetch error!")
}
return frc
}()
Can someone please help me to find correct predicate?
Thanks

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 sort FetchRequest result by Turkish locale

How can I sort fetchResult by Turkish language, turkish characters sorted at the end of results.
let managedObjectContext = (UIApplication.shared.delegate as! AppDelegate).managedObjectContext
let fetch = NSFetchRequest<Contact>(entityName: "Contact")
let sortDescriptor = NSSortDescriptor(key: "firstName", ascending: true)
let sortDescriptors = [sortDescriptor]
fetch.sortDescriptors = sortDescriptors
do {
let list = try managedObjectContext.fetch(fetch)
} catch {
fatalError("Failed \(error)")
}
Working code:
let managedObjectContext = (UIApplication.shared.delegate as! AppDelegate).managedObjectContext
let fetch = NSFetchRequest<Contact>(entityName: "Contact")
let sortDescriptor = NSSortDescriptor(key: "firstName", ascending: true, selector: #selector(NSString.localizedCaseInsensitiveCompare))
let sortDescriptors = [sortDescriptor]
fetch.sortDescriptors = sortDescriptors
do {
let list = try managedObjectContext.fetch(fetch)
} catch {
fatalError("Failed \(error)")
}

Sort by date - Swift 3

I have a func getData() which retrieves core data entity, and I want to sort them by date. How can I apply NSPredicate or Predicate to get the data from CoreData sorted by date?
My core data entity:
Entity: Expenses
Attributes:
amount
category
date
func getData() {
let context = appDelegate.persistentContainer.viewContext
do {
expenses = try context.fetch(Expenses.fetchRequest())
} catch {
print("Cannot fetch Expenses")
}
}
Predicates are for filtering your search results. To sort them you need to use an NSSortDescriptor. Assuming you have an attribute on your Expenses entity called date of type Date:
func getData() {
let context = appDelegate.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<Expenses>(entityName: "Expenses")
let sort = NSSortDescriptor(key: #keyPath(Expenses.date), ascending: true)
fetchRequest.sortDescriptors = [sort]
do {
expenses = try context.fetch(fetchRequest)
} catch {
print("Cannot fetch Expenses")
}
}
EDIT: I should have mentioned that the sort selector is added in an array so that multiple sort descriptors can be added if needed. e.g. sort first by date, then by number of legs, then by volume, etc.
You need a sort descriptor to get all the objects in a specific order.
let sectionSortDescriptor = NSSortDescriptor(key: "date", ascending: true)
let sortDescriptors = [sectionSortDescriptor]
fetchRequest.sortDescriptors = sortDescriptors
My function to do a fetchRequest of data in Core Data and sort the results by date "timestamp" in descending order. "Ruta" is the name of the entity.
//Array of Ruta entity
rutas = [Ruta]()
func getData() {
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Ruta")
let sort = NSSortDescriptor(key: "timestamp", ascending: false)
request.sortDescriptors = [sort]
do {
rutas = try context.fetch(request) as! [Ruta]
} catch {
print("Fetching Failed")
}
}
In swift 4 or swift 5, you can use like
func sortlist(){
//1
guard let appDelegate =
UIApplication.shared.delegate as? AppDelegate else {
return
}
let managedContext =
appDelegate.persistentContainer.viewContext
//2
let fetchRequest =
NSFetchRequest<NSManagedObject>(entityName: "User")
let sort = NSSortDescriptor(key: "date", ascending: false)
fetchRequest.sortDescriptors = [sort]
//3
do {
let langugeCodes = try managedContext.fetch(fetchRequest)
for result in langugeCodes as [NSManagedObject] {
var username:String = result.value(forKey: "username")! as! String
print("username==>",username)
}
} catch let error as NSError {
print("Could not fetch. \(error), \(error.userInfo)")
}
}
To get data which are lastly added at first, need to set key of sort descriptor as ObjectId.
let sectionSortDescriptor = NSSortDescriptor(key: #keyPath(Entity.ObjectId)
ascending: false) fetchRequest.sortDescriptors = [sectionSortDescriptor]

NSPredicate filter by more than one string

How do you make an NSPredicate that filters more than one object at the same time? The following works perfect for one object (in this case KDED) but I'm trying to get for example KDED, KDAB and KOMN at the same time, using swift2.
let fetchRequest = NSFetchRequest(entityName: "Airport")
let sortDescriptor = NSSortDescriptor(key: "code", ascending: true)
fetchRequest.sortDescriptors = [sortDescriptor]
let predicate = NSPredicate(format: "code ==%#", "KDED")
fetchRequest.predicate = predicate
if let managedObjectContext = (UIApplication.sharedApplication().delegate as? AppDelegate)?.managedObjectContext {
fetchResultController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: managedObjectContext, sectionNameKeyPath: nil, cacheName: nil)
fetchResultController.delegate = self
do {
try fetchResultController.performFetch()
Airports = fetchResultController.fetchedObjects as! [Airport]
} catch {
print(error)
}
}
Use the IN operator:
let predicate = NSPredicate(format: "code IN %#", ["KDED", "KDAB", "KOMN"])