OLD | NEW |
---|---|
(Empty) | |
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. | |
4 | |
5 #if !defined(__has_feature) || !__has_feature(objc_arc) | |
6 #error "This file requires ARC support." | |
7 #endif | |
8 | |
9 #import "remoting/ios/host_refresh.h" | |
10 | |
11 #import "remoting/ios/host.h" | |
12 #import "remoting/ios/utility.h" | |
13 | |
14 @interface HostRefresh (Private) | |
15 - (void)authentication:(GTMOAuth2Authentication*)auth | |
16 request:(NSMutableURLRequest*)request | |
17 error:(NSError*)error; | |
18 + (NSMutableArray*)parseJSON:(NSMutableData*)data; | |
19 + (void)setNetworkActivityIndicator:(BOOL)show; | |
20 + (void)callFailed:(NSString*)error; | |
21 @end | |
22 | |
23 // Logic flow begins with refreshHostList, and continutes until an error occurs, | |
24 // or the host list is returned to the delegate | |
25 @implementation HostRefresh | |
26 | |
27 // Begin the authentication and authorization process. Begin the process by | |
28 // 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.
| |
29 // fetch the users host list. | |
30 - (void)refreshHostList:(GTMOAuth2Authentication*)authReq | |
31 delegate:(id<HostRefreshDelegate>)delegate { | |
32 _jsonData = [[NSMutableData alloc] init]; | |
33 _delegate = delegate; | |
34 | |
35 // Build request URL using API HTTP endpoint, and our api key | |
36 NSMutableString* urlStr = [[NSMutableString alloc] init]; | |
37 [urlStr | |
38 appendFormat: | |
39 @"%@%@%@", | |
40 [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.
| |
41 ->directory_hosts_url() | |
42 .c_str()], | |
43 @"?key=", | |
44 [NSString stringWithUTF8String:google_apis::GetAPIKey().c_str()]]; | |
45 NSURL* url = [NSURL URLWithString:urlStr]; | |
46 NSMutableURLRequest* theRequest = [NSMutableURLRequest requestWithURL:url]; | |
47 | |
48 // Add scopes if needed | |
49 NSString* scope = authReq.scope; | |
50 if ([scope rangeOfString:[NSString stringWithUTF8String: | |
51 remoting::GetOauthScope().c_str()]] | |
52 .location == NSNotFound) { | |
53 scope = [GTMOAuth2Authentication | |
54 scopeWithStrings: | |
55 scope, | |
56 [NSString stringWithUTF8String:remoting::GetOauthScope().c_str()], | |
57 nil]; | |
58 authReq.scope = scope; | |
59 } | |
60 // Execute request async | |
61 [authReq authorizeRequest:theRequest | |
62 delegate:self | |
63 didFinishSelector:@selector(authentication:request:error:)]; | |
64 | |
65 [HostRefresh setNetworkActivityIndicator:YES]; | |
66 } | |
67 | |
68 // Handle completion of the authorization process. Append service credientals | |
69 // for jabber. If an error occured, notify user. | |
70 - (void)authentication:(GTMOAuth2Authentication*)auth | |
71 request:(NSMutableURLRequest*)request | |
72 error:(NSError*)error { | |
73 [HostRefresh setNetworkActivityIndicator:NO]; | |
74 if (error != nil) { | |
75 [HostRefresh callFailed:error.localizedDescription]; | |
76 } else { | |
77 // Add credientails for service | |
78 [request addValue:[NSString stringWithUTF8String: | |
79 google_apis::GetOAuth2ClientID( | |
80 google_apis::CLIENT_REMOTING).c_str()] | |
81 forHTTPHeaderField:@"client_id"]; | |
82 [request addValue:[NSString stringWithUTF8String: | |
83 google_apis::GetOAuth2ClientSecret( | |
84 google_apis::CLIENT_REMOTING).c_str()] | |
85 forHTTPHeaderField:@"client_secret"]; | |
86 | |
87 // Begin connection, the returned reference is not useful right now and | |
88 // marked as __unused | |
89 __unused NSURLConnection* connection = | |
90 [[NSURLConnection alloc] initWithRequest:request delegate:self]; | |
91 [HostRefresh setNetworkActivityIndicator:YES]; | |
92 } | |
93 } | |
94 | |
95 // @protocol NSURLConnectionDelegate, handle any error during connection | |
96 - (void)connection:(NSURLConnection*)connection | |
97 didFailWithError:(NSError*)error { | |
98 [HostRefresh setNetworkActivityIndicator:NO]; | |
99 [HostRefresh callFailed:[error localizedDescription]]; | |
100 | |
101 // if we have any _jsonData go ahead and release it | |
102 [_jsonData setLength:0]; | |
103 } | |
104 | |
105 // @protocol NSURLConnectionDataDelegate, may be called async multiple times. | |
106 // Each call appeads the new data to the known data until completed. | |
107 - (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data { | |
108 [_jsonData appendData:data]; | |
109 } | |
110 | |
111 // @protocol NSURLConnectionDataDelegate | |
112 // Ensure connection succeeded: HTTP 200 OK | |
113 - (void)connection:(NSURLConnection*)connection | |
114 didReceiveResponse:(NSURLResponse*)response { | |
115 NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response; | |
116 if ([response respondsToSelector:@selector(allHeaderFields)]) { | |
117 NSNumber* responseCode = | |
118 [[NSNumber alloc] initWithInteger:[httpResponse statusCode]]; | |
119 if (responseCode.intValue != 200) { | |
120 | |
121 // if we have any _jsonData go ahead and release it | |
122 [_jsonData setLength:0]; | |
123 [HostRefresh | |
124 callFailed:[NSString stringWithFormat:@"HTTP STATUS CODE: %d", | |
125 [httpResponse statusCode]]]; | |
126 } | |
127 } | |
128 } | |
129 | |
130 // @protocol NSURLConnectionDataDelegate handle a completed connection, parse | |
131 // received data, and return host list to delagate | |
132 - (void)connectionDidFinishLoading:(NSURLConnection*)connection { | |
133 [HostRefresh setNetworkActivityIndicator:NO]; | |
134 if ([_jsonData length] == 0 || _delegate == nil) { | |
135 [HostRefresh callFailed:nil]; | |
136 } | |
137 [_delegate hostListRefresh:[HostRefresh parseJSON:_jsonData]]; | |
138 | |
139 // Done with the data, release it | |
140 [_jsonData setLength:0]; | |
141 } | |
142 | |
143 // Parse jsonData into Host list | |
144 + (NSMutableArray*)parseJSON:(NSMutableData*)data { | |
145 NSError* error; | |
146 NSDictionary* json = [NSJSONSerialization JSONObjectWithData:data | |
147 options:kNilOptions | |
148 error:&error]; | |
149 | |
150 NSDictionary* dataDict = [json objectForKey:@"data"]; | |
151 | |
152 NSArray* availableServers = [dataDict objectForKey:@"items"]; | |
153 | |
154 NSMutableArray* serverList = [[NSMutableArray alloc] init]; | |
155 | |
156 NSUInteger idx = 0; | |
157 NSDictionary* svr; | |
158 NSUInteger count = [availableServers count]; | |
159 | |
160 while (idx < count) { | |
161 svr = [availableServers objectAtIndex:idx++]; | |
162 Host* host = [[Host alloc] init]; | |
163 host.createdTime = [svr objectForKey:@"createdTime"]; | |
164 host.hostId = [svr objectForKey:@"hostId"]; | |
165 host.hostName = [svr objectForKey:@"hostName"]; | |
166 host.hostVersion = [svr objectForKey:@"hostVersion"]; | |
167 host.jabberId = [svr objectForKey:@"jabberId"]; | |
168 host.kind = [svr objectForKey:@"kind"]; | |
169 host.publicKey = [svr objectForKey:@"publicKey"]; | |
170 host.status = [svr objectForKey:@"status"]; | |
171 host.updatedTime = [svr objectForKey:@"updatedTime"]; | |
172 [serverList addObject:host]; | |
173 } | |
174 | |
175 return serverList; | |
176 } | |
177 | |
178 // Request 'wait' annimation from application | |
179 + (void)setNetworkActivityIndicator:(BOOL)show { | |
180 [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:show]; | |
181 } | |
182 | |
183 // Notifiy user with an error message | |
184 + (void)callFailed:(NSString*)error { | |
185 NSString* errorMsg = @"The Host list refresh is not available at this time. " | |
186 " Please try again later."; | |
187 if (error != nil && error.length > 0) { | |
188 errorMsg = | |
189 [errorMsg stringByAppendingString:[@" " stringByAppendingString:error]]; | |
190 } | |
191 | |
192 [Utility showAlert:@"Host Refresh Failed" message:errorMsg]; | |
193 } | |
194 | |
195 @end | |
OLD | NEW |