HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

Synchronization with remote web service

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
synchronizationwithservicewebremote

Problem

I am writing a method to synchronize the local Core Data entities with a remote web service (in this case, Parse.com).

To update changed or created objects, I fetch all where the updatedAt date property is larger than the last local sync date. So far, so good.

But I am struggling with the deletion of local objects that have been removed on the server. My current approach is the following. This however seems quite expensive to me (\$O(r*l)\$ in the worst case, if I recall correctly). Is there any way to reduce the two loops?

PFQuery *idQuery = [PFQuery queryWithClassName:@"Product"];
[idQuery selectKeys:@[]];
NSArray *allRemote = [idQuery findObjects];
NSArray *allRemoteIds = [allRemote valueForKey:@"objectId"];

NSArray *allLocal = [Product all];
for(Product *p in allLocal) {
    BOOL shouldDelete = YES;
    for(NSString *remoteId in allRemoteIds) {
        if([remoteId isEqualToString:p.productId]) {
            shouldDelete = NO;
            break;
        }
    }

    if(shouldDelete) {
        [p delete];
    }
}

Solution

You can use NSPredicate:

NSArray* productsToDelete = [allLocal filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"NOT (productId IN %@)", allRemoteIds]];
for(Product* product in productsToDelete) {
    [product delete];
}


This will for sure improve readability of your code. I'm not sure about performance, but I would assume that Apple's implementation of filteredArrayUsingPredicate should be fast enough. If you really want to know it, do some profiling.

You can also read great article about performance of collections in Objective-C:

http://www.objc.io/issue-7/collections.html

Code Snippets

NSArray* productsToDelete = [allLocal filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"NOT (productId IN %@)", allRemoteIds]];
for(Product* product in productsToDelete) {
    [product delete];
}

Context

StackExchange Code Review Q#40095, answer score: 2

Revisions (0)

No revisions yet.