-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathServerSwitchboard.m
160 lines (136 loc) · 5.61 KB
/
ServerSwitchboard.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
//
// ServerSwitchboard.m
// Bodega
//
// Created by Chris Farber on 30/03/09.
// All code is provided under the New BSD license.
//
#import "ServerSwitchboard.h"
#import "JSON.h"
static ServerSwitchboard * sharedSwitchboard = nil;
@interface ServerSwitchboard (Private)
- (void) _sendRequest: (NSString *)verb withData: (NSDictionary *)data forPath: (NSString *)subpath
target: (id)target selector: (SEL)sel;
- (void) _returnResponseForConnection: (NSURLConnection *)connection;
- (void) connection: (NSURLConnection *)connection didReceiveResponse: (NSHTTPURLResponse *)response;
- (void) connection: (NSURLConnection *)connection didReceiveData: (NSData *)data;
- (void) connection: (NSURLConnection *)connection didFailWithError: (NSError *)error;
- (void) connectionDidFinishLoading: (NSURLConnection *)connection;
@end
@implementation ServerSwitchboard
+ (NSString *)baseURL
{
return @"http://centrix.ca/";
}
+ switchboard
{
if (!sharedSwitchboard) [self new];
return sharedSwitchboard;
}
- init
{
[super init];
if (sharedSwitchboard) {
[self release];
return sharedSwitchboard;
}
connections = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
connectionsData = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
apiURL = [[NSURL alloc] initWithString: [NSString stringWithFormat:@"%@/code/", [ServerSwitchboard baseURL]]];
defaults = [NSUserDefaults standardUserDefaults];
sharedSwitchboard = self;
return self;
}
- (void)dealloc
{
[defaults release];
CFRelease(connections);
CFRelease(connectionsData);
[apiURL release];
[super dealloc];
}
- (void) companiesWithTarget:(id)target selector: (SEL)sel
{
[self _sendRequest: @"GET"
withData: nil
forPath: @"sample.json"
target: target
selector: sel];
}
@end
@implementation ServerSwitchboard (Private)
- (void)_sendRequest: (NSString *)verb withData: (NSDictionary *)data forPath: (NSString *)subpath
target: (id)target selector: (SEL)sel
{
NSURL * requestURL = [NSURL URLWithString: subpath relativeToURL: apiURL];
NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL: requestURL];
[request setHTTPMethod: verb];
if (data) {
[request setValue: @"application/json" forHTTPHeaderField: @"Content-Type"];
[request setHTTPBody: [[data JSONRepresentation] dataUsingEncoding: NSUTF8StringEncoding]];
//NSLog(@"json rep = %@", [data JSONRepresentation]);
}
NSURLConnection * connection = [[NSURLConnection alloc]
initWithRequest: request delegate: self];
if (!connection) {
NSError * error = [NSError errorWithDomain: @"ServerSwitchboardError"
code: 1
userInfo: nil];
[target performSelector: sel withObject: nil withObject: error];
return;
}
CFDictionarySetValue(connectionsData, connection, [NSMutableData data]);
NSValue * selector = [NSValue value: &sel withObjCType: @encode(SEL)];
NSDictionary * targetInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
selector, @"selector",
target, @"target",
nil];
CFDictionarySetValue(connections, connection, targetInfo);
}
- (void) connection: (NSURLConnection *)connection didReceiveResponse: (NSHTTPURLResponse *)response
{
NSMutableDictionary * targetInfo = (id)CFDictionaryGetValue(connections, connection);
[targetInfo setValue: response forKey: @"response"];
}
- (void) connection: (NSURLConnection *)connection didReceiveData: (NSData *)data
{
NSMutableData * connectionData = (id)CFDictionaryGetValue(connectionsData, connection);
[connectionData appendData: data];
}
- (void) connection: (NSURLConnection *)connection didFailWithError: (NSError *)error
{
NSMutableDictionary * targetInfo = (id)CFDictionaryGetValue(connections, connection);
[targetInfo setValue: error forKey: @"error"];
[self _returnResponseForConnection: connection];
}
- (void) connectionDidFinishLoading: (NSURLConnection *)connection
{
[self _returnResponseForConnection: connection];
}
- (void) _returnResponseForConnection: (NSURLConnection *)connection
{
NSMutableDictionary * targetInfo = (id)CFDictionaryGetValue(connections, connection);
NSMutableData * data = (id)CFDictionaryGetValue(connectionsData, connection);
id target = [targetInfo valueForKey: @"target"];
SEL selector;
[[targetInfo valueForKey: @"selector"] getValue: &selector];
NSError * error = [targetInfo valueForKey: @"error"];
if (!error) {
NSHTTPURLResponse * response = [targetInfo valueForKey: @"response"];
NSInteger status = [response statusCode];
if (status != 200) error = [NSError errorWithDomain: @"APIError" code: status userInfo: nil];
}
NSDictionary * dataDictionary = nil;
if ([data length] && [error code] != 401) {
NSString * json = [[[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding] autorelease];
NSLog(@"got response: %@", json);
dataDictionary = [json JSONValue];
}
[target performSelector: selector withObject: dataDictionary withObject: error];
CFDictionaryRemoveValue(connections, connection);
CFDictionaryRemoveValue(connectionsData, connection);
[connection release];
}
@end