convert syntax to swift 3.0 NSFetchedResultsController - ios

how can I convert my NSFetchedResultsController to swift 3.0, i can't get it to work.... I tried apple's auto conversion but it's not working??
I had this:
lazy var fetchedResultsControler: NSFetchedResultsController = {
let fetchRequest = NSFetchRequest(entityName: "Mesages")
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "timestamp", ascending: true)]
fetchRequest.predicate = NSPredicate(format: "user.id = %#", self.friend!.id!)
let moc = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
let frc = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: moc, sectionNameKeyPath: nil, cacheName: nil)
frc.delegate = self
return frc
}()
automatically converted to this:
lazy var fetchedResultsControler: NSFetchedResultsController = { () -> <<error type>> in
let fetchRequest = NSFetchRequest(entityName: "Mesages")
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "timestamp", ascending: true)]
fetchRequest.predicate = NSPredicate(format: "user.id = %#", self.friend!.id!)
let moc = (UIApplication.shared.delegate as! AppDelegate).managedObjectContext
let frc = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: moc, sectionNameKeyPath: nil, cacheName: nil)
frc.delegate = self
return frc
}()
but It's not working, it's asking me to put semi colons in random places

It is needed to set up NSFetchRequestResult inside brackets <>.
For swift 3.0:
lazy var fetchedResultsControler: NSFetchedResultsController<NSFetchRequestResult> = {
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Mesages")
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "timestamp", ascending: true)]
fetchRequest.predicate = NSPredicate(format: "user.id = %#", self.friend!.id!)
let moc = (UIApplication.shared.delegate as! AppDelegate).managedObjectContext
let frc = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: moc, sectionNameKeyPath: nil, cacheName: nil)
frc.delegate = self
return frc
}()

Related

Fetched objects returned by NSFetchRequest are not in the proper section

No matter what I put as the value in sectionNameKeyPath: "value", the fetched objects get returned in the order in which they were saved in the database. The number of sections is correct, but whether I view the fetched objects by section fetchedResultsController.sections or fetchedResultsController.object(at: indexPath) I get the same results.
This is in the UITableViewController
lazy var fetchedResultsController: NSFetchedResultsController<Dice> = {
let fetchRequest: NSFetchRequest<Dice> = Dice.fetchRequest()
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "createdAt", ascending: false)]
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
// Doesn't matter what I set in the "sectionNameKeyPath" value
let fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: context, sectionNameKeyPath: "set.identifier", cacheName: nil)
fetchedResultsController.delegate = self
return fetchedResultsController
}()
Has anyone else seen this?

Ios Swift3 : lazy var fetchrequestcontroller showing an error

I was using a lazy var in table view controller to get the data from CoreData. It was working good in swift2. But When I upgraded to Swift3, Its showing an error as below. Kindly help me to change for Swift3
Error : Cannot convert value of type 'Error' to specified type 'NSFetchedResultsController'
lazy var fetchedResultsController: NSfetchedResultsController =
{
let fetchRequest = NSFetchRequest(entityName: "EvtIvtTbl")
let sortDescriptor = NSSortDescriptor(key: "bym_kol", ascending: true)
fetchRequest.sortDescriptors = [sortDescriptor]
let fetchedResultsController = NSfetchedResultsController(fetchRequest: fetchRequest,
managedObjectContext: self.managedObjectContext,
sectionNameKeyPath: nil,
cacheName: nil)
fetchedResultsController.delegate = self
return fetchedResultsController
}()
In Swift 3.0, NSFetchedResultsController and NSFetchRequest want type parameters. Assuming that EvtIvtTbl is your NSManagedObject subclass, your code should look like this:
lazy var fetchedResultsController: NSFetchedResultsController<EvtIvtTbl> = {
let fetchRequest = NSFetchRequest<EvtIvtTbl>(entityName: "EvtIvtTbl")
let sortDescriptor = NSSortDescriptor(key: "bym_kol", ascending: true)
fetchRequest.sortDescriptors = [sortDescriptor]
let fetchedResultsController = NSFetchedResultsController<EvtIvtTbl>(fetchRequest: fetchRequest,
managedObjectContext: self.managedObjectContext,
sectionNameKeyPath: nil,
cacheName: nil)
fetchedResultsController.delegate = self
return fetchedResultsController
}()

Load more in bottom UITableView using NSFetchedResultsController

I want to load more cells when user in the last cell. I use CoreData and I get data from it. I use this answer to do what I want, but it didn't work. What problem can be there? Also I have one more question. I don't know why working only first implementation.
First implementation
var fetchedResultsController: NSFetchedResultsController {
let moc = DatabaseController.sharedInstance.managedObjectContext
let fetchRequest = NSFetchRequest()
let entity = NSEntityDescription.entityForName("Coctail", inManagedObjectContext: moc)
fetchRequest.entity = entity
fetchRequest.fetchLimit = 10
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "name", ascending: true)]
let aFetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest,
managedObjectContext: moc,
sectionNameKeyPath: nil,
cacheName: nil)
aFetchedResultsController.delegate = self
do {
try aFetchedResultsController.performFetch()
} catch {
fatalError("\(error)")
}
return aFetchedResultsController
}
Second Implementation
func initilizeFetchedResultsController() {
let moc = DatabaseController.sharedInstance.managedObjectContext
let fetchRequest = NSFetchRequest()
let entity = NSEntityDescription.entityForName("Coctail", inManagedObjectContext: moc)
fetchRequest.entity = entity
fetchRequest.fetchLimit = 10
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "name", ascending: true)]
let aFetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest,
managedObjectContext: moc,
sectionNameKeyPath: nil,
cacheName: nil)
aFetchedResultsController.delegate = self
do {
try aFetchedResultsController.performFetch()
} catch {
fatalError("\(error)")
}
fetchedResultsController = aFetchedResultsController
}
Hard to tell why the first solution but the second doesn't without seeing the other code that would have used the fetchedResultsController or called initilizeFetchedResultsController().
The reason you're not getting more data is that you've hardcoded your fetchLimit to 10. No matter what you do, you'll only ever get 10 results.
You'll need to change the fetchLimit to get more data. Check out this answer -- it is similar to what you'll need to do: https://stackoverflow.com/a/6786931/5605379

filter NSFetchedResultsController result swift 2

I want automatic updates on tableview..For that i have used NSFetchedResultsControlleras
lazy var fetchedResultsController: NSFetchedResultsController = {
// Initialize Fetch Request
let fetchRequest = NSFetchRequest(entityName: "Student")
// Add Sort Descriptors
let sortDescriptor = NSSortDescriptor(key: "grade", ascending: true)
fetchRequest.sortDescriptors = [sortDescriptor]
// Initialize Fetched Results Controller
let fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.managedObjectContext, sectionNameKeyPath: nil, cacheName: nil)
// Configure Fetched Results Controller
fetchedResultsController.delegate = self
return fetchedResultsController
}()
But i have to filter the results after loading as of user selection as..
#IBAction func onSegmentValueChanged(sender: UISegmentedControl)
{
if sender.selectedSegmentIndex == 0{
//filter by grade
let fetchRequest = NSFetchRequest(entityName: "Student")
let sortDescriptor = NSSortDescriptor(key: "grade", ascending: true)
fetchRequest.sortDescriptors = [sortDescriptor]
let filterfetchResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.managedObjectContext, sectionNameKeyPath: nil, cacheName: nil)
let predicate = NSPredicate(format: "address = %#","Russia")
filterfetchResultsController.fetchRequest.predicate = predicate
self.tableView.reloadData()
}else{
let fetchRequest = NSFetchRequest(entityName: "Student")
let sortDescriptor = NSSortDescriptor(key: "grade", ascending: true)
fetchRequest.sortDescriptors = [sortDescriptor]
let filterfetchResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.managedObjectContext, sectionNameKeyPath: nil, cacheName: nil)
let predicate = NSPredicate(format: "grade = %d",10)
filterfetchResultsController.fetchRequest.predicate = predicate
self.tableView.reloadData()
}
}
This however reload the tableView but data is not filtered.how do i solve this problem?This is the demo project i am working on.Or should i use the normal way passing the results and reloading tableView as of normal way to solve this problem?
You must use self.fetchedResultsController, this is your datasource, not filterfetchResultsController: thereĀ“s no connection.
You must do a performFetch() to execute the changed predicates
This works for me:
#IBAction func onSegmentValueChanged(sender: UISegmentedControl)
{
if sender.selectedSegmentIndex == 1{
//filter by address
let predicate = NSPredicate(format: "address == %#","Russia")
self.fetchedResultsController.fetchRequest.predicate = predicate
}else{
let predicate = NSPredicate(format: "grade = %d",10)
self.fetchedResultsController.fetchRequest.predicate = predicate
}
do {
try self.fetchedResultsController.performFetch()
} catch {
let fetchError = error as NSError
print("\(fetchError), \(fetchError.userInfo)")
}
self.tableView.reloadData()
}

What this CoreData error means?

On compile this code:
func managedObjectContext_roster() -> NSManagedObjectContext {
return Messenger.sharedInstance.xmppRosterStorage!.mainThreadManagedObjectContext
}
I get the next error:
CoreData: error: Failed to call designated initializer on NSManagedObject class 'XMPPUserCoreDataStorageObject'
What this error means and how can I fix it? I searched in Google, but did not find anything
UPDATE
func fetchedResultsController() -> NSFetchedResultsController? {
if fetchedResultsControllerVar == nil {
let moc = MessengerRoster.sharedInstance.managedObjectContext_roster() as NSManagedObjectContext?
let entity = NSEntityDescription.entityForName("XMPPUserCoreDataStorageObject", inManagedObjectContext: moc!)
let sd1 = NSSortDescriptor(key: "sectionNum", ascending: true)
let sd2 = NSSortDescriptor(key: "displayName", ascending: true)
let sortDescriptors = [sd1, sd2]
let fetchRequest = NSFetchRequest()
fetchRequest.entity = entity
fetchRequest.sortDescriptors = sortDescriptors
fetchRequest.fetchBatchSize = 10
fetchedResultsControllerVar = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: moc!, sectionNameKeyPath: "sectionNum", cacheName: nil)
fetchedResultsControllerVar?.delegate = self
if fetchedResultsControllerVar?.performFetch(nil) == nil {
//Handle fetch error
}
}
return fetchedResultsControllerVar!
}

Resources