-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathGMNetworkOperation.m
executable file
·253 lines (199 loc) · 9.56 KB
/
GMNetworkOperation.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
//
// GMNetwork Kit
//
// Created by Gersham Meharg on 11-02-13.
// Copyright 2011 Gersham Meharg. All rights reserved.
//
#import "GMNetworkOperation.h"
#import "GMNetworkManager.h"
#import "GMOperationResult.h"
#import "NSString+URLEncode.h"
@implementation GMNetworkOperation
@synthesize url = _url;
@synthesize parameters = _parameters;
@synthesize delegate = _delegate;
@synthesize httpMethod = _httpMethod;
@synthesize jsonString = _jsonString;
@synthesize result = _result;
@synthesize completion = _completion;
@synthesize parseResults = _parseResults;
- (id)init {
self = [super init];
self.httpMethod = HTTPGet;
self.parameters = [NSMutableDictionary dictionaryWithCapacity:4];
return self;
}
- (void)setJsonData:(id)data {
self.jsonString = [data jsonString];
}
- (void)main
{
[NSThread setThreadPriority:0];
if ([self isCancelled]) {
NSLog(@"Operation is cancelled");
return;
}
NSLog(@"* REQ %@", _url);
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:_url
cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
timeoutInterval:20.0];
[request setHTTPShouldHandleCookies:NO];
[request setHTTPShouldUsePipelining:NO];
// JSON PUT/POST
if (self.jsonString) {
NSData *body = [self.jsonString dataUsingEncoding:NSUTF8StringEncoding];
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[request setValue:[NSString stringWithFormat:@"%d", [body length]] forHTTPHeaderField:@"Content-Length"];
[request setHTTPBody:body];
// Regular POST/PUT
} else if (self.httpMethod == @"POST" || self.httpMethod == @"PUT") {
NSLog(@"* PARAMETERS %@", _parameters);
NSString *formPostParams = [self encodeFormPostParameters:_parameters];
[request setValue: @"application/x-www-form-urlencoded; charset=utf-8" forHTTPHeaderField: @"Content-Type"];
[request setHTTPBody:[formPostParams dataUsingEncoding:NSUTF8StringEncoding]];
// Other Methods
} else {
}
NSString *version = [NSString stringWithFormat:@"%@-%@",
[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"],
[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"]];
[request setValue:version forHTTPHeaderField:@"APP_VERSION"];
// Set headers from the network manager
NSMutableDictionary *defaultHeaders = [SharedNetworkManager.defaultHeaders mutableCopy];
for (NSString *key in defaultHeaders.allKeys) {
[request setValue:[defaultHeaders valueForKey:key] forHTTPHeaderField:key];
}
[request setHTTPMethod:_httpMethod];
[request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
NSError *error = nil;
NSHTTPURLResponse *response;
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
if ([self isCancelled]) {
NSLog(@"Operation is cancelled");
return;
}
//NSLog(@"* RES %i %@", [response statusCode], _url);
// Build the result
self.result = [GMOperationResult new];
_result.httpCode = [response statusCode];
_result.parameters = _parameters;
_result.url = _url;
_result.completion = _completion;
// Handle Errors
if (error != nil || _result.httpCode < 200 || _result.httpCode > 299) {
NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSMutableDictionary *errorInfo = [NSMutableDictionary dictionaryWithCapacity:2];
if (_result.httpCode == 401) {
[errorInfo setObject:@"Authentication Failure" forKey:NSLocalizedDescriptionKey];
[errorInfo setObject:@"The supplied API Key was not found" forKey:NSLocalizedFailureReasonErrorKey];
} else if (error.code == -1012) {
_result.httpCode = 401;
[errorInfo setObject:@"Authentication Failure" forKey:NSLocalizedDescriptionKey];
[errorInfo setObject:@"The supplied API Key was not found" forKey:NSLocalizedFailureReasonErrorKey];
} else if (error != nil) {
[errorInfo setObject:@"Connection Error" forKey:NSLocalizedDescriptionKey];
[errorInfo setObject:error.localizedDescription forKey:NSLocalizedFailureReasonErrorKey];
NSLog(@"Connection Error, %@", error);
} else {
NSLog(@"* Error %i %@", _result.httpCode, responseString);
switch (_result.httpCode) {
case 400:
[errorInfo setObject:@"Bad Request" forKey:NSLocalizedDescriptionKey];
[errorInfo setObject:responseString forKey:NSLocalizedFailureReasonErrorKey];
break;
case 403:
[errorInfo setObject:@"Forbidden" forKey:NSLocalizedDescriptionKey];
[errorInfo setObject:responseString forKey:NSLocalizedFailureReasonErrorKey];
break;
case 404:
[errorInfo setObject:@"Not Found" forKey:NSLocalizedDescriptionKey];
[errorInfo setObject:responseString forKey:NSLocalizedFailureReasonErrorKey];
break;
case 405:
[errorInfo setObject:@"Method Not Allowed" forKey:NSLocalizedDescriptionKey];
[errorInfo setObject:responseString forKey:NSLocalizedFailureReasonErrorKey];
break;
case 409:
[errorInfo setObject:@"Conflict" forKey:NSLocalizedDescriptionKey];
[errorInfo setObject:responseString forKey:NSLocalizedFailureReasonErrorKey];
break;
case 491:
case 492:
case 493:
case 494:
case 495:
case 496:
case 497:
case 498:
case 499:
[errorInfo setObject:@"Special Error" forKey:NSLocalizedDescriptionKey];
[errorInfo setObject:responseString forKey:NSLocalizedFailureReasonErrorKey];
break;
case 500:
case 501:
case 502:
case 503:
case 504:
NSLog(@"* 50x Error from server \n\n %@ \n\n", responseString);
[errorInfo setObject:@"Server Error" forKey:NSLocalizedDescriptionKey];
[errorInfo setObject:[NSString stringWithFormat:@"Error attempting to communicate to server (%i). Please try again later.", _result.httpCode] forKey:NSLocalizedFailureReasonErrorKey];
break;
default:
[errorInfo setObject:@"Connection Error" forKey:NSLocalizedDescriptionKey];
[errorInfo setObject:[NSString stringWithFormat:@"Error attempting to communicate to server (%i). Please try again later.", _result.httpCode] forKey:NSLocalizedFailureReasonErrorKey];
break;
}
}
_result.error = [NSError errorWithDomain:@"NetworkOperationError" code:_result.httpCode userInfo:errorInfo];
_result.errorTitle = [_result.error.userInfo objectForKey:NSLocalizedDescriptionKey];
_result.errorDescription = [_result.error.userInfo objectForKey:NSLocalizedFailureReasonErrorKey];
// Try to parse out a JSON error message
if (data != nil) {
NSError *error = nil;
_result.json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
if (error == nil && [_result.json valueForKey:@"error_message"]) {
_result.errorDescription = [_result.json valueForKey:@"error_message"];
}
}
} else {
NSError *error = nil;
_result.json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
if (error != nil) {
NSLog(@"Error parsing JSON %@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
NSMutableDictionary *errorInfo = [NSMutableDictionary dictionaryWithCapacity:2];
[errorInfo setObject:@"JSON Parsing Error" forKey:NSLocalizedDescriptionKey];
[errorInfo setObject:@"Error parsing JSON" forKey:NSLocalizedFailureReasonErrorKey];
_result.error = [NSError errorWithDomain:@"NetworkOperationError" code:_result.httpCode userInfo:errorInfo];
_result.errorTitle = [_result.error.userInfo objectForKey:NSLocalizedDescriptionKey];
_result.errorDescription = [_result.error.userInfo objectForKey:NSLocalizedFailureReasonErrorKey];
}
}
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
// Send the result to the delegate
if ([_delegate respondsToSelector:@selector(networkOperationResult:)]) {
[_delegate performSelectorOnMainThread:@selector(networkOperationResult:) withObject:_result waitUntilDone:YES];
} else if (_delegate != nil) {
NSLog(@"* Delegate doesn't respond to networkOperationResult");
}
}
- (NSString *)encodeFormPostParameters: (NSDictionary *)postParameters {
NSMutableString *formPostParams = [[NSMutableString alloc] init];
NSEnumerator *keys = [postParameters keyEnumerator];
NSString *name = [keys nextObject];
while (nil != name) {
NSString *encodedValue = [NSString stringWithString:[postParameters valueForKey:name]];
if ([encodedValue isMemberOfClass:[NSString class]]) {
encodedValue = [encodedValue urlEncodedString];
}
[formPostParams appendString: name];
[formPostParams appendString: @"="];
[formPostParams appendString: encodedValue];
name = [keys nextObject];
if (nil != name) {
[formPostParams appendString: @"&"];
}
}
return formPostParams;
}
@end