1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #if !defined(__has_feature) || !__has_feature(objc_arc)
6 #error "This file requires ARC support."
9 #import "remoting/ios/host_refresh.h"
11 #import "remoting/ios/authorize.h"
12 #import "remoting/ios/host.h"
13 #import "remoting/ios/utility.h"
16 NSString* kDefaultErrorMessage = @"The Host list refresh is not available at "
17 @"this time. Please try again later.";
20 @interface HostRefresh (Private)
21 - (void)authentication:(GTMOAuth2Authentication*)auth
22 request:(NSMutableURLRequest*)request
23 error:(NSError*)error;
24 - (void)formatErrorMessage:(NSString*)error;
25 - (void)notifyDelegate;
28 // Logic flow begins with refreshHostList, and continues until an error occurs,
29 // or the host list is returned to the delegate
30 @implementation HostRefresh
32 @synthesize jsonData = _jsonData;
33 @synthesize errorMessage = _errorMessage;
34 @synthesize delegate = _delegate;
36 // Override default constructor and initialize internals
40 _jsonData = [[NSMutableData alloc] init];
45 // Begin the authentication and authorization process. Begin the process by
46 // creating an oAuth2 request to google api's including the needed scopes to
47 // fetch the users host list.
48 - (void)refreshHostList:(GTMOAuth2Authentication*)authReq
49 delegate:(id<HostRefreshDelegate>)delegate {
51 CHECK(_delegate == nil); // Do not reuse an instance of this class
55 [Authorize beginRequest:authReq
57 didFinishSelector:@selector(authentication:request:error:)];
60 // Handle completion of the authorization process. Append service credentials
61 // for jabber. If an error occurred, notify user.
62 - (void)authentication:(NSObject*)auth
63 request:(NSMutableURLRequest*)request
64 error:(NSError*)error {
66 [self formatErrorMessage:error.localizedDescription];
68 // Add credentials for service
69 [Authorize appendCredentials:request];
71 // Begin connection, the returned reference is not useful right now and
73 __unused NSURLConnection* connection =
74 [[NSURLConnection alloc] initWithRequest:request delegate:self];
78 // @protocol NSURLConnectionDelegate, handle any error during connection
79 - (void)connection:(NSURLConnection*)connection
80 didFailWithError:(NSError*)error {
81 [self formatErrorMessage:[error localizedDescription]];
83 [self notifyDelegate];
86 // @protocol NSURLConnectionDataDelegate, may be called async multiple times.
87 // Each call appends the new data to the known data until completed.
88 - (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data {
89 [_jsonData appendData:data];
92 // @protocol NSURLConnectionDataDelegate
93 // Ensure connection succeeded: HTTP 200 OK
94 - (void)connection:(NSURLConnection*)connection
95 didReceiveResponse:(NSURLResponse*)response {
96 NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
97 if ([response respondsToSelector:@selector(allHeaderFields)]) {
98 NSNumber* responseCode =
99 [[NSNumber alloc] initWithInteger:[httpResponse statusCode]];
100 if (responseCode.intValue != 200) {
101 [self formatErrorMessage:[NSString
102 stringWithFormat:@"HTTP STATUS CODE: %d",
103 [httpResponse statusCode]]];
108 // @protocol NSURLConnectionDataDelegate handle a completed connection, parse
109 // received data, and return host list to delegate
110 - (void)connectionDidFinishLoading:(NSURLConnection*)connection {
111 [self notifyDelegate];
114 // Store a formatted error message to return later
115 - (void)formatErrorMessage:(NSString*)error {
116 _errorMessage = kDefaultErrorMessage;
117 if (error != nil && error.length > 0) {
118 _errorMessage = [_errorMessage
119 stringByAppendingString:[@" " stringByAppendingString:error]];
123 // The connection has finished, call to delegate
124 - (void)notifyDelegate {
125 if (_jsonData.length == 0 && _errorMessage == nil) {
126 [self formatErrorMessage:nil];
129 [_delegate hostListRefresh:[Host parseListFromJSON:_jsonData]
130 errorMessage:_errorMessage];