Index: remoting/ios/host_refresh.mm |
diff --git a/remoting/ios/host_refresh.mm b/remoting/ios/host_refresh.mm |
new file mode 100644 |
index 0000000000000000000000000000000000000000..eddfcaad109179530312bd8432a3bb26d04ab091 |
--- /dev/null |
+++ b/remoting/ios/host_refresh.mm |
@@ -0,0 +1,195 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#if !defined(__has_feature) || !__has_feature(objc_arc) |
+#error "This file requires ARC support." |
+#endif |
+ |
+#import "remoting/ios/host_refresh.h" |
+ |
+#import "remoting/ios/host.h" |
+#import "remoting/ios/utility.h" |
+ |
+@interface HostRefresh (Private) |
+- (void)authentication:(GTMOAuth2Authentication*)auth |
+ request:(NSMutableURLRequest*)request |
+ error:(NSError*)error; |
++ (NSMutableArray*)parseJSON:(NSMutableData*)data; |
++ (void)setNetworkActivityIndicator:(BOOL)show; |
++ (void)callFailed:(NSString*)error; |
+@end |
+ |
+// Logic flow begins with refreshHostList, and continutes until an error occurs, |
+// or the host list is returned to the delegate |
+@implementation HostRefresh |
+ |
+// Begin the authentication and authorization process. Begin the process by |
+// createing an oAuth2 request to google api's including the needed scopes to |
dcaiafa
2014/03/19 01:14:15
nit: spelling
aboone
2014/03/21 16:42:07
Done.
|
+// fetch the users host list. |
+- (void)refreshHostList:(GTMOAuth2Authentication*)authReq |
+ delegate:(id<HostRefreshDelegate>)delegate { |
+ _jsonData = [[NSMutableData alloc] init]; |
+ _delegate = delegate; |
+ |
+ // Build request URL using API HTTP endpoint, and our api key |
+ NSMutableString* urlStr = [[NSMutableString alloc] init]; |
+ [urlStr |
+ appendFormat: |
+ @"%@%@%@", |
+ [NSString stringWithUTF8String:remoting::ServiceUrls::GetInstance() |
dcaiafa
2014/03/19 01:14:15
Store intermediate values in locals to improve rea
aboone
2014/03/21 16:42:07
Done.
|
+ ->directory_hosts_url() |
+ .c_str()], |
+ @"?key=", |
+ [NSString stringWithUTF8String:google_apis::GetAPIKey().c_str()]]; |
+ NSURL* url = [NSURL URLWithString:urlStr]; |
+ NSMutableURLRequest* theRequest = [NSMutableURLRequest requestWithURL:url]; |
+ |
+ // Add scopes if needed |
+ NSString* scope = authReq.scope; |
+ if ([scope rangeOfString:[NSString stringWithUTF8String: |
+ remoting::GetOauthScope().c_str()]] |
+ .location == NSNotFound) { |
+ scope = [GTMOAuth2Authentication |
+ scopeWithStrings: |
+ scope, |
+ [NSString stringWithUTF8String:remoting::GetOauthScope().c_str()], |
+ nil]; |
+ authReq.scope = scope; |
+ } |
+ // Execute request async |
+ [authReq authorizeRequest:theRequest |
+ delegate:self |
+ didFinishSelector:@selector(authentication:request:error:)]; |
+ |
+ [HostRefresh setNetworkActivityIndicator:YES]; |
+} |
+ |
+// Handle completion of the authorization process. Append service credientals |
+// for jabber. If an error occured, notify user. |
+- (void)authentication:(GTMOAuth2Authentication*)auth |
+ request:(NSMutableURLRequest*)request |
+ error:(NSError*)error { |
+ [HostRefresh setNetworkActivityIndicator:NO]; |
+ if (error != nil) { |
+ [HostRefresh callFailed:error.localizedDescription]; |
+ } else { |
+ // Add credientails for service |
+ [request addValue:[NSString stringWithUTF8String: |
+ google_apis::GetOAuth2ClientID( |
+ google_apis::CLIENT_REMOTING).c_str()] |
+ forHTTPHeaderField:@"client_id"]; |
+ [request addValue:[NSString stringWithUTF8String: |
+ google_apis::GetOAuth2ClientSecret( |
+ google_apis::CLIENT_REMOTING).c_str()] |
+ forHTTPHeaderField:@"client_secret"]; |
+ |
+ // Begin connection, the returned reference is not useful right now and |
+ // marked as __unused |
+ __unused NSURLConnection* connection = |
+ [[NSURLConnection alloc] initWithRequest:request delegate:self]; |
+ [HostRefresh setNetworkActivityIndicator:YES]; |
+ } |
+} |
+ |
+// @protocol NSURLConnectionDelegate, handle any error during connection |
+- (void)connection:(NSURLConnection*)connection |
+ didFailWithError:(NSError*)error { |
+ [HostRefresh setNetworkActivityIndicator:NO]; |
+ [HostRefresh callFailed:[error localizedDescription]]; |
+ |
+ // if we have any _jsonData go ahead and release it |
+ [_jsonData setLength:0]; |
+} |
+ |
+// @protocol NSURLConnectionDataDelegate, may be called async multiple times. |
+// Each call appeads the new data to the known data until completed. |
+- (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data { |
+ [_jsonData appendData:data]; |
+} |
+ |
+// @protocol NSURLConnectionDataDelegate |
+// Ensure connection succeeded: HTTP 200 OK |
+- (void)connection:(NSURLConnection*)connection |
+ didReceiveResponse:(NSURLResponse*)response { |
+ NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response; |
+ if ([response respondsToSelector:@selector(allHeaderFields)]) { |
+ NSNumber* responseCode = |
+ [[NSNumber alloc] initWithInteger:[httpResponse statusCode]]; |
+ if (responseCode.intValue != 200) { |
+ |
+ // if we have any _jsonData go ahead and release it |
+ [_jsonData setLength:0]; |
+ [HostRefresh |
+ callFailed:[NSString stringWithFormat:@"HTTP STATUS CODE: %d", |
+ [httpResponse statusCode]]]; |
+ } |
+ } |
+} |
+ |
+// @protocol NSURLConnectionDataDelegate handle a completed connection, parse |
+// received data, and return host list to delagate |
+- (void)connectionDidFinishLoading:(NSURLConnection*)connection { |
+ [HostRefresh setNetworkActivityIndicator:NO]; |
+ if ([_jsonData length] == 0 || _delegate == nil) { |
+ [HostRefresh callFailed:nil]; |
+ } |
+ [_delegate hostListRefresh:[HostRefresh parseJSON:_jsonData]]; |
+ |
+ // Done with the data, release it |
+ [_jsonData setLength:0]; |
+} |
+ |
+// Parse jsonData into Host list |
++ (NSMutableArray*)parseJSON:(NSMutableData*)data { |
+ NSError* error; |
+ NSDictionary* json = [NSJSONSerialization JSONObjectWithData:data |
+ options:kNilOptions |
+ error:&error]; |
+ |
+ NSDictionary* dataDict = [json objectForKey:@"data"]; |
+ |
+ NSArray* availableServers = [dataDict objectForKey:@"items"]; |
+ |
+ NSMutableArray* serverList = [[NSMutableArray alloc] init]; |
+ |
+ NSUInteger idx = 0; |
+ NSDictionary* svr; |
+ NSUInteger count = [availableServers count]; |
+ |
+ while (idx < count) { |
+ svr = [availableServers objectAtIndex:idx++]; |
+ Host* host = [[Host alloc] init]; |
+ host.createdTime = [svr objectForKey:@"createdTime"]; |
+ host.hostId = [svr objectForKey:@"hostId"]; |
+ host.hostName = [svr objectForKey:@"hostName"]; |
+ host.hostVersion = [svr objectForKey:@"hostVersion"]; |
+ host.jabberId = [svr objectForKey:@"jabberId"]; |
+ host.kind = [svr objectForKey:@"kind"]; |
+ host.publicKey = [svr objectForKey:@"publicKey"]; |
+ host.status = [svr objectForKey:@"status"]; |
+ host.updatedTime = [svr objectForKey:@"updatedTime"]; |
+ [serverList addObject:host]; |
+ } |
+ |
+ return serverList; |
+} |
+ |
+// Request 'wait' annimation from application |
++ (void)setNetworkActivityIndicator:(BOOL)show { |
+ [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:show]; |
+} |
+ |
+// Notifiy user with an error message |
++ (void)callFailed:(NSString*)error { |
+ NSString* errorMsg = @"The Host list refresh is not available at this time. " |
+ " Please try again later."; |
+ if (error != nil && error.length > 0) { |
+ errorMsg = |
+ [errorMsg stringByAppendingString:[@" " stringByAppendingString:error]]; |
+ } |
+ |
+ [Utility showAlert:@"Host Refresh Failed" message:errorMsg]; |
+} |
+ |
+@end |