I actively use StackOverflow almost daily for more than a year by now, but this is the first question I'm asking here. No other question grasp my exact problem. Solution to close ones doesn't work or doesn't really apply do my case.
What I'm doing
I'm developing an iOS app with a share extension. The extension app save links into CoreData, the containing(main) app, exhibits a listing of this links saved utilizing NSFetchResultsController.
The main app is the Master-Detail template provided by Xcode with really small adaptation.
I've created a embedded framework to carry CoreData stuff and set an App Group to host the CoreData and share it between apps in the usual way.
The CoreData part is working fine: I can insert objects into the ContextObjectManager and whenever my main app becomes active I can query this inserted object there promptly.
The problem
The problem starts when MasterViewController fails to update tableView. I'm inferring the NSFetchedResultsController instance do not track CoreData changes when it happens outside the main app.
I try some approaches while listening to when app becomes active:
func becomeActive(notification: NSNotification) {
//Approach 1: Making sure to delete cache -- even though I do not have a persistent named cache file.
NSFetchedResultsController.deleteCacheWithName(nil)
//Approach 2: Making sure to reload tableView data.
self.tableView.reloadData()
}
It didn't have any effect.
self.fetchedResultsController.sections![0].numberOfObjects
it's always equal the number of exhibited cells. Then, if I share something new with the extension and then come back, this number doesn't change, but DataManager.getAllManagedObjectsFromEntity(Link.entityDescription()).objects.count
equals this quantity + 1.
And then, when I close the app and open it again, it's synced and number of exhibited cells = number of objects fetched = number of all managed objects got from entity.
What I believe that could be possible solution paths
- If I could notify the main app from a CoreData modification from the extension app, I could update the context right in the MasterViewController. I can't find a not-a-hot-fix way to do that.
- I read about "background context" and "background context changes vs main context changes" in one stackoverflow question, but I cannot grasp exactly how it relate to my problem. I'm utilizing only one context.
- I believe if I can reset the context or refetch results, the problem is solved. But how?
It's it. Someone have any suggestions/solutions of what I need to do to sync up the fetched results?
Relevant Code
NSFetchedResultsController instance in MasterViewController.swift
var fetchedResultsController: NSFetchedResultsController {
if _fetchedResultsController != nil {
return _fetchedResultsController!
}
let fetchRequest = NSFetchRequest()
// Edit the entity name as appropriate.
let entity = NSEntityDescription.entityForName("Link", inManagedObjectContext: DataAccess.shared.managedObjectContext)
fetchRequest.entity = entity
// Set the batch size to a suitable number.
fetchRequest.fetchBatchSize = 20
// Edit the sort key as appropriate.
let sortDescriptor = NSSortDescriptor(key: "title", ascending: false)
fetchRequest.sortDescriptors = [sortDescriptor]
/// Template original code
// let aFetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.managedObjectContext!, sectionNameKeyPath: nil, cacheName: "Master")
/// My adaptation
let aFetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: DataAccess.shared.managedObjectContext, sectionNameKeyPath: nil, cacheName: nil)
aFetchedResultsController.delegate = self
_fetchedResultsController = aFetchedResultsController
do {
try _fetchedResultsController!.performFetch()
} catch {
abort()
}
return _fetchedResultsController!
}
func getAllManagedObjectsFromEntity(_:) at embedded framework's DataManager.swift
file
public class func getAllManagedObjectsFromEntity(entity: NSEntityDescription) -> (sucesso: Bool, objects: NSArray){
// let delegate = (UIApplication.sharedApplication()).delegate as! AppDelegate
let context:NSManagedObjectContext? = DataAccess.shared.managedObjectContext
let request:NSFetchRequest = NSFetchRequest()
request.entity = entity
var error:NSError?
var objects:NSArray?
do {
objects = try context?.executeFetchRequest(request)
} catch let error1 as NSError {
error = error1
objects = nil
}
if(error == nil){
return(true, objects!)
}else{
NSLog(error!.description)
return(false, objects!)
}
}
DataManager.getAllManagedObjectsFromEntity
? What does it do, exactly? – ExcuseDataManager.getAllManagedObjectsFromEntity(_:).objects
is an array. I meantDataManager.getAllManagedObjectsFromEntity(_:).objects.count
. – Disconcerted