Given that a refresh pull involves pulling data that is filtered according to an attribute, Soft Delete involves setting that attribute to YES/NO. This affects clients in that they will then not be able to pull that data. Additionally, that data is kept safe in Easy Table for future references and undeletes.
For example, let’s say you create an attribute “complete”.
When pulling data, you may specify that you want to pull all data that has NO for attribute “complete”.
Once you assign YES for attribute complete on say row 88, client refresh pulls will not include row 88 anymore. It will include all rows with NO for attribute “complete”.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
-(void)completeItem:(NSDictionary *)item completion:(QSCompletionBlock)completion { // Set the item to be complete (we need a mutable copy) NSMutableDictionary *mutable = [item mutableCopy]; [mutable setObject:@YES forKey:@"complete"]; // Update the item in the TodoItem table and remove from the items array on completion [self.syncTable update:mutable completion:^(NSError *error) { [self logErrorIfNotNil:error]; [self syncData: ^{ // Let the caller know that we finished if (completion != nil) { dispatch_async(dispatch_get_main_queue(), completion); } }]; }]; } |
When fetching from your fetch controller/core data, simply filter data according to complete == NO.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
- (NSFetchedResultsController *)fetchedResultsController { if (_fetchedResultsController != nil) { return _fetchedResultsController; } NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; QSAppDelegate *delegate = (QSAppDelegate *)[[UIApplication sharedApplication] delegate]; NSManagedObjectContext *context = delegate.managedObjectContext; fetchRequest.entity = [NSEntityDescription entityForName:@"TodoItem" inManagedObjectContext:context]; // show only non-completed items fetchRequest.predicate = [NSPredicate predicateWithFormat:@"complete == NO"]; // sort by item text fetchRequest.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"createdAt" ascending:YES]]; // Note: if storing a lot of data, you should specify a cache for the last parameter // for more information, see Apple's documentation: http://go.microsoft.com/fwlink/?LinkId=524591&clcid=0x409 NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:context sectionNameKeyPath:nil cacheName:nil]; self.fetchedResultsController = theFetchedResultsController; _fetchedResultsController.delegate = self; return _fetchedResultsController; } |
HARD DELETE – Delete on Local and Server
If you want to remove local AND server data, all you have to do is call the delete method from your MSSyncTable.
It sends a request to your local data source to remove the given item, then queues a request to send the delete to the mobile service.
It first removes the data locally.
Then, when the queued request goes through into the mobile service, then it will update remotely, and you can log into your Azure account, look at the Easy Tables, and see that the item has been removed.
1 2 3 4 5 6 7 8 9 10 11 |
/// Sends a request to the MSSyncContext's data source to delete the given /// item in the local store. In addition QUEUES a request to send the delete /// to the mobile service. [self.syncTable delete:item completion:^(NSError * _Nullable error) { if(error) { NSLog(@"ERROR %@", error); } else { NSLog(@"DELETED LOCALLY!"); dispatch_async(dispatch_get_main_queue(), completion); } }]; //delete |
Notes
Do not remove data by hand on the backend directly. Currently, MS have no way to re-syncing, and your client app will have many error messages on its request queue.