| // 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/authorize.h" |
| #import "remoting/ios/host.h" |
| #import "remoting/ios/utility.h" |
| |
| namespace { |
| NSString* kDefaultErrorMessage = @"The Host list refresh is not available at " |
| @"this time. Please try again later."; |
| } // namespace |
| |
| @interface HostRefresh (Private) |
| - (void)authentication:(GTMOAuth2Authentication*)auth |
| request:(NSMutableURLRequest*)request |
| error:(NSError*)error; |
| - (void)formatErrorMessage:(NSString*)error; |
| - (void)notifyDelegate; |
| @end |
| |
| // Logic flow begins with refreshHostList, and continues until an error occurs, |
| // or the host list is returned to the delegate |
| @implementation HostRefresh |
| |
| @synthesize jsonData = _jsonData; |
| @synthesize errorMessage = _errorMessage; |
| @synthesize delegate = _delegate; |
| |
| // Override default constructor and initialize internals |
| - (id)init { |
| self = [super init]; |
| if (self) { |
| _jsonData = [[NSMutableData alloc] init]; |
| } |
| return self; |
| } |
| |
| // Begin the authentication and authorization process. Begin the process by |
| // creating an oAuth2 request to google api's including the needed scopes to |
| // fetch the users host list. |
| - (void)refreshHostList:(GTMOAuth2Authentication*)authReq |
| delegate:(id<HostRefreshDelegate>)delegate { |
| |
| CHECK(_delegate == nil); // Do not reuse an instance of this class |
| |
| _delegate = delegate; |
| |
| [Authorize beginRequest:authReq |
| delegate:self |
| didFinishSelector:@selector(authentication:request:error:)]; |
| } |
| |
| // Handle completion of the authorization process. Append service credentials |
| // for jabber. If an error occurred, notify user. |
| - (void)authentication:(NSObject*)auth |
| request:(NSMutableURLRequest*)request |
| error:(NSError*)error { |
| if (error != nil) { |
| [self formatErrorMessage:error.localizedDescription]; |
| } else { |
| // Add credentials for service |
| [Authorize appendCredentials:request]; |
| |
| // Begin connection, the returned reference is not useful right now and |
| // marked as __unused |
| __unused NSURLConnection* connection = |
| [[NSURLConnection alloc] initWithRequest:request delegate:self]; |
| } |
| } |
| |
| // @protocol NSURLConnectionDelegate, handle any error during connection |
| - (void)connection:(NSURLConnection*)connection |
| didFailWithError:(NSError*)error { |
| [self formatErrorMessage:[error localizedDescription]]; |
| |
| [self notifyDelegate]; |
| } |
| |
| // @protocol NSURLConnectionDataDelegate, may be called async multiple times. |
| // Each call appends 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) { |
| [self formatErrorMessage:[NSString |
| stringWithFormat:@"HTTP STATUS CODE: %d", |
| [httpResponse statusCode]]]; |
| } |
| } |
| } |
| |
| // @protocol NSURLConnectionDataDelegate handle a completed connection, parse |
| // received data, and return host list to delegate |
| - (void)connectionDidFinishLoading:(NSURLConnection*)connection { |
| [self notifyDelegate]; |
| } |
| |
| // Store a formatted error message to return later |
| - (void)formatErrorMessage:(NSString*)error { |
| _errorMessage = kDefaultErrorMessage; |
| if (error != nil && error.length > 0) { |
| _errorMessage = [_errorMessage |
| stringByAppendingString:[@" " stringByAppendingString:error]]; |
| } |
| } |
| |
| // The connection has finished, call to delegate |
| - (void)notifyDelegate { |
| if (_jsonData.length == 0 && _errorMessage == nil) { |
| [self formatErrorMessage:nil]; |
| } |
| |
| [_delegate hostListRefresh:[Host parseListFromJSON:_jsonData] |
| errorMessage:_errorMessage]; |
| } |
| @end |