-
Notifications
You must be signed in to change notification settings - Fork 0
/
YAJLParserOperation.m
173 lines (144 loc) · 3.94 KB
/
YAJLParserOperation.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
//
// YAJLParserOperation.m
// Pulse News
//
// Created by Ankit Gupta on 7/2/10.
// Copyright 2010 Stanford University. All rights reserved.
//
#import "YAJLParserOperation.h"
@implementation YAJLParserOperation
@synthesize document_, error_;
#pragma mark -
#pragma mark Initialization & Memory Management
- (id)init
{
return [self initWithURL:nil];
}
- (id)initWithURL:(NSURL *)url
{
NSParameterAssert( url );
if( (self = [super init]) ) {
connectionURL_ = [url copy];
YAJLDocument* document = [[YAJLDocument alloc] init];
self.document_ = document;
[document release];
}
return self;
}
- (void)dealloc
{
if( connection_ ) { [connection_ cancel]; [connection_ release]; connection_ = nil; }
[connectionURL_ release];
[error_ release];
[document_ release];
document_ = nil;
[super dealloc];
}
#pragma mark -
#pragma mark Start & Utility Methods
// This method is just for convenience. It cancels the URL connection if it
// still exists and finishes up the operation.
- (void)done
{
if( connection_ ) {
[connection_ cancel];
[connection_ release];
[connectionURL_ release];
connectionURL_ = nil;
connection_ = nil;
}
// Alert anyone that we are finished
[self willChangeValueForKey:@"isExecuting"];
[self willChangeValueForKey:@"isFinished"];
executing_ = NO;
finished_ = YES;
[self didChangeValueForKey:@"isFinished"];
[self didChangeValueForKey:@"isExecuting"];
}
- (void)start
{
//iOS 4 bug fix
if (![NSThread isMainThread])
{
[self performSelectorOnMainThread:@selector(start)
withObject:nil waitUntilDone:NO];
return;
}
// Ensure this operation is not being restarted and that it has not been cancelled
if( finished_ || [self isCancelled] ) { [self done]; return; }
NSLog(@"Started Parsing %@", [connectionURL_ description]);
// From this point on, the operation is officially executing--remember, isExecuting
// needs to be KVO compliant!
[self willChangeValueForKey:@"isExecuting"];
executing_ = YES;
[self didChangeValueForKey:@"isExecuting"];
// Create the NSURLConnection--this could have been done in init, but we delayed
// until no in case the operation was never enqueued or was cancelled before starting
connection_ = [[NSURLConnection alloc] initWithRequest:[NSURLRequest requestWithURL:connectionURL_]
delegate:self];
}
#pragma mark -
#pragma mark Overrides
- (BOOL)isConcurrent
{
return YES;
}
- (BOOL)isExecuting
{
return executing_;
}
- (BOOL)isFinished
{
return finished_;
}
- (void)cancel
{
[self done];
[super cancel];
}
#pragma mark -
#pragma mark Delegate Methods for NSURLConnection
// For this example, we only handle the standard delegate call-backs
// The connection failed
- (void)connection:(NSURLConnection*)connection didFailWithError:(NSError*)error
{
error_ = [error retain];
[self done];
}
// The connection received more data
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
if([self isCancelled]) {
[self done];
}
NSError *error = nil;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
YAJLParserStatus status = [document_ parse:data error:&error];
[pool release];
if (status == YAJLParserStatusOK) {
NSLog(@"Parser OK");
[self done];
}
}
// Initial response
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
if([self isCancelled]) {
[self done];
}
NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
NSInteger statusCode = [httpResponse statusCode];
if( statusCode == 200 ) {
} else {
NSString* statusError = [NSString stringWithFormat:NSLocalizedString(@"HTTP Error: %ld", nil), statusCode];
NSDictionary* userInfo = [NSDictionary dictionaryWithObject:statusError forKey:NSLocalizedDescriptionKey];
error_ = [[NSError alloc] initWithDomain:@"ExampleOperationDomain"
code:statusCode
userInfo:userInfo];
[self done];
}
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[self done];
}
@end