Due mesi fa ho iniziato a scrivere una nuova applicazione iPhone e per questo motivo ho creato un servizio web RESTFul generico, che mi consente di avere molte di queste funzionalità necessarie come l'autenticazione dell'utente, i profili utente, un sistema di amicizia, elaborazione dei media, un sistema di messaggistica e così via. Nella mia mente ci sono diversi casi d'uso per riutilizzare questo servizio web per le future applicazioni iPhone.iOS App Architecture con NSOperations
Con questo stato d'animo, ho deciso di scrivere una libreria statica per questa applicazione (e tutte le future app) che gestisce tutte le operazioni di installazione e elaborazione dei media (immagine, video, audio), comunicando con il servizio web , analisi e mappatura dei risultati, gestione di CoreData e così via.
Data la mia applicazione ci sono scenari in cui sono in esecuzione molte attività parallele (caso peggiore) ad es. l'utente modifica attualmente la propria immagine del profilo, mentre l'applicazione invia la posizione degli utenti al server (in background) e viene ricevuta una nuova notifica push.
Così deciso di incapsulare ogni operazione logica (come SendUserLocation o GetCurrentFriendList) in un NSOperation e aggiungerli a un servizioQueue (NSOperationQueue).
Ogni operazione è in grado di generare sottogruppi quando l'operazione ha ottenuto un risultato dal servizio web e deve elaborarlo ora.
Un tipico metodo ServiceManager sembra
- (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];
}
}
Ogni operazione, richiesta (per server) e Subtask utilizza un GUID come notificationName per notificare l'oggetto padre quando è fatto di elaborazione. Se tutto è in un'operazione, invia una notifica all'interfaccia utente.
Detto questo, il codice per l'aggiunta e la rimozione di sottocompiti assomiglia a questo
- (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];
}
Ora tutto quello che ho da fare è chiamare il ServiceManager nel mio gui per avviare una specifica operazione come
[self.core.serviceManager activateFriendsSync:nil onSuccess:nil];
Se voglio registrare un osservatore, ho solo passare un oggetto osservatore ed un selettore simili
[self.core.serviceManager activateFriendsSync:self onSuccess:@selector(myMethod:)];
Ultimo ma non meno importante la mia domanda/le: "L'architettura" funziona molto bene e stabile, ma vale la pena farlo? Crea troppe spese generali? Ha senso? Come tu, personalmente, implementa operazioni simultanee?
Miglior Henrik
P.S. Sentiti libero di modificare la mia domanda, porre domande (come commento), chiamami per questo pensiero.
Ho davvero avuto difficoltà a spiegarlo, fondamentalmente perché non sono un madrelingua inglese. E non fraintendermi. Non ho scritto questo post per sfoggiare in alcun modo.Tutto quello che voglio fare è imparare (e magari a scrivere la più avanzata iphone/Objective C questione)
Ciao Dean, grazie ai tuoi approfondimenti. –