changes? • especially since the app will be long-lived • How do we minimize the number of requests from the iOS app to the server? • How can we avoid making separate API routes for the iOS app (and every client thereafter)? Questions…
Disadvantages! - Requires global knowledge of all the apps components - Affects other, disjunct service consumers - Difficult to test - Async bookmark operation still fails - (void)logOut { // Synchronously wipe all the user-dependent data [[Services authCredentialDataService] wipeData]; // … ! // Reload UI with new global data [_appController reload]; }
dependence in the service layer - Gracefully supports switching authentication contexts - Easy to test interfaces with a mock Session object - Async bookmark operation succeeds - (void)logOut { // Create an unauthenticated session Session *newSession = [Session loggedOutSession]; ! // Reload UI with logged out session [_appController loadSession:newSession]; }
(nonatomic, strong, readonly) NSString *sessionId; @property (nonatomic, strong, readonly) AuthCredential *authCredential; ! - (BOOL)isAuthenticated; ! @end The Session object directly models user-dependent state, and is injected into objects that need it.
3. Bookmark action is dequeued 4. Bookmark action succeeds 5. PostViewController and logged in Session are cleaned up PostViewService PostService Net LoginViewController Logged out Session dispatch_async(_backgroundQueue, ^{ [[Services postView] bookmark:_postId session:_session]; });
PostViewController PostViewService PostService Net AuthCredentialDataService Data dependence Time dependence AuthCredentialDataService PostViewController
see which version of the app each group has • Easy visibility and communication on features of each of these groups • Automate everything, consider Jenkins CI over Xcode Bots