Can I use NSFetchResultController
on an Apple Watch to show 80 to 90 records in table?
I am using WKInterfaceTable+IGInterfaceDataTable
to make use of datasource type loading methods because that seems to me simple than using NSArray
.
Will NSFetchResultController
help in increasing efficiency or it will make it slow?
I found that NSFetchResultController is not useful at all in iWatch app because WKInterfaceTable does not support delegate method for edit, changes or delete for a single row that NSFetchResultController support in delegate. so you will have to update all data that you want to show each time so i think we should not use it.
I used NSFetchedResultController
and WKInterfaceTable
for my Apple Watch application. It is true that it is not as convenient as a UITableViewController
, but it is very doable. I don't have any performance issues, even in in loading 20+ rows (didn't try 80-90). Of course this is in the simulator, so I don't know how the devices themselves will behave.
Insert, update and delete you have to implement yourself, but is not that hard.
Below part of my code in the InterfaceController, with insert row as an example, but edit and delete is not more difficult:
Interface
...
@property (weak, nonatomic) IBOutlet WKInterfaceTable *interfaceTable;
@property(strong, nonatomic) NSFetchRequest *fetchRequest;
@property(strong, nonatomic) NSFetchedResultsController *fetchedResultsController;
@property(strong, nonatomic) NSMutableArray *data;
...
Implementation
The fetching is the same as always, except that we don't assign a delegate to the resultscontroller, but save the data directly:
self.fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"YourModel" inManagedObjectContext:self.managedObjectContext];
self.fetchRequest.entity = entityDescription;
[self.fetchRequest setSortDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"createdAt" ascending:YES]]];
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:self.fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil];
[self.fetchedResultsController performFetch:&error];
self.data= self.fetchedResultsController.fetchedObjects;
I then use a function loadTableData
:
- (void)loadTableData {
[self.interfaceTable setNumberOfRows:[[self data] count] withRowType:@"YourCustomCell"];
[self.interfaceTable insertRowsAtIndexes:[NSIndexSet indexSetWithIndex:[[self data] count]] withRowType:@"YourRowType"];
for (int i = 0; i<[[self data] count];i++)
[self configureRowControllerAtIndex:i];
}
Which calls configureRowControllerAtIndex
, a function that populates one row (I have two labels):
- (void)configureRowControllerAtIndex:(NSInteger)index {
WKTableVIewRowController *listItemRowController = [self.interfaceTable rowControllerAtIndex:index];
[listItemRowController setTitle:[[self.data[index] title] integerValue]];
[listItemRowController setDescription:[self.data[index] description]];
}
When you insert a new row, just add it manually in the managedObjectContext
and in the data array:
// Add in managedObjectContext
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"YourModel" inManagedObjectContext:self.managedObjectContext];
YourModel *newRow = [[YourModel alloc] initWithEntity:entityDescription insertIntoManagedObjectContext:nil];
// Add in data array
[self.data addObject:newRow];
and regularly save the managedObjectContext:
if (![self.managedObjectContext save:&error]) {
if (error) {
NSLog(@"Unable to save changes.");
NSLog(@"%@, %@", error, error.localizedDescription);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With