Two month ago I started to write a new iPhone Application and for this reason I created a generic RESTFul web service, which allows me have a lot of these necessary features like user authentication, user profiles, a friendship system, media processing, a messaging system and so on. In my mind there are several use cases to reuse this webservice for future iPhone applications.
With this state of mind, I decided to write a static library for this application (and all future apps) that handles all the heavy lifting like media (image, video, sound) setup and processing, communicating with the web service, parsing and mapping of the results, handling CoreData and so on.
Given my application there are scenarios when a lot of parallel tasks are running (worst case) i.e.
the user currently changes his/her profile picture, while the application sends the users location to the server (in the background) and a new push notification is received.
So decided to encapsule each logical operation (like SendUserLocation or GetCurrentFriendList) in a NSOperation and add them to a ServiceQueue (NSOperationQueue).
Each Operation is able to spawn subtasks when the operation successfully got a result from the webservice and should process it now.
A typical ServiceManager method looks like
- (void)activateFriendsSync:(id)observer onSuccess:(SEL)selector {
ELOSyncFriends *opSyncFriends = [[ELOSyncFriends alloc] initWithSM:self];
[self ELServiceLogger:opSyncFriends];
[serviceQueue addOperation:opSyncFriends];
if(observer) {
[self registerObserver:observer selector:selector name:opSyncFriends.notificationName];
}
}
Each operation, request (to the server), and subTask uses a GUID as a notificationName to notify it's parent object when it's done processing. If everything in an operation is done, it sends a notification back to the User Interface.
That said, the code for adding and removing subtasks looks like this
- (void)removeSubTask:(NSNotification*)notification {
ELRequest *request = (ELRequest*)[notification object];
[subTasks removeObjectIdenticalTo:request.notificationName];
if([subTasks count] == 0) {
// all SubTaks done, send notification to parent
[serviceManager.notificationCenter postNotificationName:self.notificationName object:request];
}
}
- (NSString*)addSubTask {
NSString* newName = [self GetUUID];
[subTasks addObject:[newName retain]];
[serviceManager.notificationCenter addObserver:self selector:@selector(removeSubTask:) name:newName object:nil];
return newName;
}
- (NSString *)GetUUID {
CFUUIDRef theUUID = CFUUIDCreate(NULL);
CFStringRef string = CFUUIDCreateString(NULL, theUUID);
CFRelease(theUUID);
return [(NSString *)string autorelease];
}
Now all I have to do in my Interface is to call the serviceManager to start a specific operation like
[self.core.serviceManager activateFriendsSync:nil onSuccess:nil];
If I want to register an observer, I just pass an observer object and a selector like this
[self.core.serviceManager activateFriendsSync:self onSuccess:@selector(myMethod:)];
Last but not least my question(s): The "architecture" runs very well and stable, but is it worth doing? Does it create too much overhead? Does it even make sense? How you, personally, implement concurrent operations?
Best Henrik
P.S. Feel free to edit my question, ask questions (as a comment), call me names for this thinking.
I really had a hard time explaining it, basically because I'm not a native english speaker. And don't get me wrong. I didn't write this posting to show off in any kind. All I want to do is learn (and maybe to write a more advanced iphone / objective c question)