Stop using an NSTimer to update progress, we just do it from the main request loop instead
Added default values for didFailSelector and didFinishSelector for the simple cases Several small bug fixes Order of methods in implementation now matches the order of those in the header
Showing
6 changed files
with
102 additions
and
47 deletions
@@ -10,9 +10,11 @@ | @@ -10,9 +10,11 @@ | ||
10 | #import <Cocoa/Cocoa.h> | 10 | #import <Cocoa/Cocoa.h> |
11 | #import "ASIProgressDelegate.h" | 11 | #import "ASIProgressDelegate.h" |
12 | 12 | ||
13 | + | ||
14 | + | ||
13 | @interface ASIHTTPRequest : NSOperation { | 15 | @interface ASIHTTPRequest : NSOperation { |
14 | 16 | ||
15 | - //The url for this operation, should include get params in the query string where appropriate | 17 | + //The url for this operation, should include GET params in the query string where appropriate |
16 | NSURL *url; | 18 | NSURL *url; |
17 | 19 | ||
18 | //The delegate, you need to manage setting and talking to your delegate in your subclasses | 20 | //The delegate, you need to manage setting and talking to your delegate in your subclasses |
@@ -78,103 +80,145 @@ | @@ -78,103 +80,145 @@ | ||
78 | //Size of the POST payload | 80 | //Size of the POST payload |
79 | double postLength; | 81 | double postLength; |
80 | 82 | ||
81 | - //Timer used to update the progress delegates | ||
82 | - NSTimer *progressTimer; | ||
83 | - | ||
84 | //The total amount of downloaded data | 83 | //The total amount of downloaded data |
85 | double totalBytesRead; | 84 | double totalBytesRead; |
86 | 85 | ||
86 | + //Last amount of data read (used for incrementing progress) | ||
87 | + double lastBytesRead; | ||
88 | + //Last amount of data sent (used for incrementing progress) | ||
89 | + double lastBytesSent; | ||
90 | + | ||
87 | //Realm for authentication when credentials are required | 91 | //Realm for authentication when credentials are required |
88 | NSString *authenticationRealm; | 92 | NSString *authenticationRealm; |
89 | 93 | ||
94 | + //This lock will block the request until the delegate supplies authentication info | ||
95 | + NSConditionLock *authenticationLock; | ||
96 | + | ||
90 | //Called on the delegate when the request completes successfully | 97 | //Called on the delegate when the request completes successfully |
91 | SEL didFinishSelector; | 98 | SEL didFinishSelector; |
92 | 99 | ||
93 | //Called on the delegate when the request fails | 100 | //Called on the delegate when the request fails |
94 | SEL didFailSelector; | 101 | SEL didFailSelector; |
95 | 102 | ||
96 | - //This lock will block the request until the delegate supplies authentication info | ||
97 | - NSConditionLock *authenticationLock; | ||
98 | } | 103 | } |
99 | 104 | ||
105 | +#pragma mark init / dealloc | ||
106 | + | ||
100 | // Should be an HTTP or HTTPS url, may include username and password if appropriate | 107 | // Should be an HTTP or HTTPS url, may include username and password if appropriate |
101 | - (id)initWithURL:(NSURL *)newURL; | 108 | - (id)initWithURL:(NSURL *)newURL; |
102 | 109 | ||
110 | +#pragma mark delegate configuration | ||
111 | + | ||
112 | +// Delegate will get messages when the request completes, fails or when authentication is required | ||
113 | +- (void)setDelegate:(id)newDelegate; | ||
114 | + | ||
115 | +// upload progress delegate (usually an NSProgressIndicator) is sent information on upload progress | ||
116 | +- (void)setUploadProgressDelegate:(id)newDelegate; | ||
117 | + | ||
118 | +// download progress delegate (usually an NSProgressIndicator) is sent information on download progress | ||
119 | +- (void)setDownloadProgressDelegate:(id)newDelegate; | ||
120 | + | ||
121 | +#pragma mark setup request | ||
122 | + | ||
123 | +//Add a custom header to the request | ||
124 | +- (void)addRequestHeader:(NSString *)header value:(NSString *)value; | ||
125 | + | ||
103 | //Add a POST variable to the request | 126 | //Add a POST variable to the request |
104 | - (void)setPostValue:(id)value forKey:(NSString *)key; | 127 | - (void)setPostValue:(id)value forKey:(NSString *)key; |
105 | 128 | ||
106 | //Add the contents of a local file as a POST variable to the request | 129 | //Add the contents of a local file as a POST variable to the request |
107 | - (void)setFile:(NSString *)filePath forKey:(NSString *)key; | 130 | - (void)setFile:(NSString *)filePath forKey:(NSString *)key; |
108 | 131 | ||
109 | -//Add a custom header to the request | 132 | +// When set, username and password will be presented for HTTP authentication |
110 | -- (void)addRequestHeader:(NSString *)header value:(NSString *)value; | 133 | +- (void)setUsername:(NSString *)newUsername andPassword:(NSString *)newPassword; |
134 | + | ||
135 | +// When true, authentication information will automatically be stored in (and re-used from) the keychain | ||
136 | +- (void)setUsesKeychain:(BOOL)shouldUseKeychain; | ||
111 | 137 | ||
112 | //the results of this request will be saved to downloadDestinationPath, if it is set | 138 | //the results of this request will be saved to downloadDestinationPath, if it is set |
113 | - (void)setDownloadDestinationPath:(NSString *)newDestinationPath; | 139 | - (void)setDownloadDestinationPath:(NSString *)newDestinationPath; |
114 | -- (NSString *)downloadDestinationPath; | ||
115 | 140 | ||
116 | -// When set, username and password will be presented for HTTP authentication | 141 | +- (NSString *)downloadDestinationPath; |
117 | -- (void)setUsername:(NSString *)newUsername andPassword:(NSString *)newPassword; | ||
118 | - | ||
119 | -// Delegate will get messages when the request completes, fails or when authentication is required | ||
120 | -- (void)setDelegate:(id)newDelegate; | ||
121 | 142 | ||
122 | -// Called on the delegate when the request completes successfully | 143 | +// This selector will be called on the delegate when the request completes successfully |
123 | - (void)setDidFinishSelector:(SEL)selector; | 144 | - (void)setDidFinishSelector:(SEL)selector; |
124 | 145 | ||
125 | -// Called on the delegate when the request fails | 146 | +// This selector will be called on the delegate when the request fails |
126 | - (void)setDidFailSelector:(SEL)selector; | 147 | - (void)setDidFailSelector:(SEL)selector; |
127 | 148 | ||
128 | -// upload progress delegate (usually an NSProgressIndicator) is sent information on upload progress | 149 | +#pragma mark get information about this request |
129 | -- (void)setUploadProgressDelegate:(id)newDelegate; | ||
130 | 150 | ||
131 | -// download progress delegate (usually an NSProgressIndicator) is sent information on download progress | 151 | +// Accessors for getting information about the request (useful for auth dialogs) |
132 | -- (void)setDownloadProgressDelegate:(id)newDelegate; | 152 | +- (NSString *)authenticationRealm; |
153 | +- (NSString *)host; | ||
133 | 154 | ||
134 | -// When true, authentication information will automatically be stored in (and re-used from) the keychain | 155 | +// Contains a description of the error that occurred if the request failed |
135 | -- (void)setUsesKeychain:(BOOL)shouldUseKeychain; | 156 | +- (NSError *)error; |
157 | +- (void)setError:(NSError *)newError; | ||
136 | 158 | ||
137 | // Will be true when the request is complete (success or failure) | 159 | // Will be true when the request is complete (success or failure) |
138 | - (BOOL)complete; | 160 | - (BOOL)complete; |
161 | +- (BOOL)isFinished; //Same thing, for NSOperationQueues to read | ||
162 | + | ||
163 | +// Get total amount of data received so far for this request | ||
164 | +- (double)totalBytesRead; | ||
139 | 165 | ||
140 | // Returns the contents of the result as an NSString (not appropriate for binary data!) | 166 | // Returns the contents of the result as an NSString (not appropriate for binary data!) |
141 | - (NSString *)dataString; | 167 | - (NSString *)dataString; |
142 | 168 | ||
143 | -// Accessors for getting information about the request (useful for auth dialogs) | 169 | +#pragma mark request logic |
144 | -- (NSString *)authenticationRealm; | ||
145 | -- (NSString *)host; | ||
146 | 170 | ||
147 | -// Contains a description of the error that occurred if the request failed | 171 | +// Start loading the request |
148 | -- (NSError *)error; | 172 | +- (void)loadRequest; |
149 | 173 | ||
174 | +// Cancel loading and clean up | ||
175 | +- (void)cancelLoad; | ||
150 | 176 | ||
151 | -// CFnetwork event handlers | 177 | +#pragma mark upload/download progress |
152 | -- (void)handleStreamComplete; | ||
153 | -- (void)handleStreamError; | ||
154 | -- (void)handleBytesAvailable; | ||
155 | -- (void)handleNetworkEvent:(CFStreamEventType)type; | ||
156 | 178 | ||
157 | -// Start loading the request | 179 | +// Called on main thread to update progress delegates |
158 | -- (void)loadRequest; | 180 | +- (void)updateProgressIndicators; |
181 | +- (void)resetUploadProgress:(NSNumber *)max; | ||
182 | +- (void)updateUploadProgress; | ||
183 | +- (void)resetDownloadProgress:(NSNumber *)max; | ||
184 | +- (void)updateDownloadProgress; | ||
185 | + | ||
186 | +#pragma mark handling request complete / failure | ||
187 | + | ||
188 | +//Called when a request completes successfully - defaults to: @selector(requestFinished:) | ||
189 | +- (void)requestFinished; | ||
190 | + | ||
191 | +//Called when a request fails - defaults to: @selector(requestFailed:) | ||
192 | +- (void)failWithProblem:(NSString *)problem; | ||
193 | + | ||
194 | +#pragma mark http authentication stuff | ||
159 | 195 | ||
160 | // Reads the response headers to find the content length, and returns true if the request needs a username and password (or if those supplied were incorrect) | 196 | // Reads the response headers to find the content length, and returns true if the request needs a username and password (or if those supplied were incorrect) |
161 | - (BOOL)isAuthorizationFailure; | 197 | - (BOOL)isAuthorizationFailure; |
162 | 198 | ||
163 | -// Apply authentication information and resume the request after an authentication challenge | ||
164 | -- (void)applyCredentialsAndResume; | ||
165 | - | ||
166 | // Unlock (unpause) the request thread so it can resume the request | 199 | // Unlock (unpause) the request thread so it can resume the request |
167 | // Should be called by delegates when they have populated the authentication information after an authentication challenge | 200 | // Should be called by delegates when they have populated the authentication information after an authentication challenge |
168 | - (void)retryWithAuthentication; | 201 | - (void)retryWithAuthentication; |
169 | 202 | ||
170 | -// Cancel loading and clean up | 203 | +// Apply authentication information and resume the request after an authentication challenge |
171 | -- (void)cancelLoad; | 204 | +- (void)applyCredentialsAndResume; |
172 | 205 | ||
173 | -// Called from timer on main thread to update progress delegates | 206 | +// Look for somewhere we can get authentication information from |
174 | -- (void)updateUploadProgress; | 207 | +- (void)applyCredentialsLoad; |
175 | -- (void)updateDownloadProgress; | 208 | + |
209 | +// Customise or overidde this to have a generic error for authentication failure | ||
210 | +- (NSError *)authenticationError; | ||
176 | 211 | ||
177 | -#pragma mark keychain stuff | 212 | +#pragma mark stream status handlers |
213 | + | ||
214 | +// CFnetwork event handlers | ||
215 | +- (void)handleNetworkEvent:(CFStreamEventType)type; | ||
216 | +- (void)handleBytesAvailable; | ||
217 | +- (void)handleStreamComplete; | ||
218 | +- (void)handleStreamError; | ||
219 | + | ||
220 | + | ||
221 | +#pragma mark keychain storage | ||
178 | 222 | ||
179 | //Save credentials to the keychain | 223 | //Save credentials to the keychain |
180 | + (void)saveCredentials:(NSURLCredential *)credentials forHost:(NSString *)host port:(int)port protocol:(NSString *)protocol realm:(NSString *)realm; | 224 | + (void)saveCredentials:(NSURLCredential *)credentials forHost:(NSString *)host port:(int)port protocol:(NSString *)protocol realm:(NSString *)realm; |
@@ -182,10 +226,16 @@ | @@ -182,10 +226,16 @@ | ||
182 | //Return credentials from the keychain | 226 | //Return credentials from the keychain |
183 | + (NSURLCredential *)savedCredentialsForHost:(NSString *)host port:(int)port protocol:(NSString *)protocol realm:(NSString *)realm; | 227 | + (NSURLCredential *)savedCredentialsForHost:(NSString *)host port:(int)port protocol:(NSString *)protocol realm:(NSString *)realm; |
184 | 228 | ||
185 | -//Called when a request completes successfully | 229 | +//Remove credentials from the keychain |
186 | -- (void)requestFinished; | 230 | ++ (void)removeCredentialsForHost:(NSString *)host port:(int)port protocol:(NSString *)protocol realm:(NSString *)realm; |
231 | + | ||
232 | + | ||
233 | + | ||
234 | + | ||
235 | + | ||
236 | + | ||
237 | + | ||
238 | + | ||
187 | 239 | ||
188 | -//Called when a request fails | ||
189 | -- (void)failWithProblem:(NSString *)problem; | ||
190 | 240 | ||
191 | @end | 241 | @end |
This diff is collapsed. Click to expand it.
@@ -13,4 +13,5 @@ | @@ -13,4 +13,5 @@ | ||
13 | - (void)setDoubleValue:(double)newValue; | 13 | - (void)setDoubleValue:(double)newValue; |
14 | - (void)incrementBy:(double)amount; | 14 | - (void)incrementBy:(double)amount; |
15 | - (void)setMaxValue:(double)newMax; | 15 | - (void)setMaxValue:(double)newMax; |
16 | +- (double)maxValue; | ||
16 | @end | 17 | @end |
@@ -27,6 +27,10 @@ | @@ -27,6 +27,10 @@ | ||
27 | - (IBAction)simpleURLFetch:(id)sender | 27 | - (IBAction)simpleURLFetch:(id)sender |
28 | { | 28 | { |
29 | ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:[NSURL URLWithString:@"http://allseeing-i.com"]] autorelease]; | 29 | ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:[NSURL URLWithString:@"http://allseeing-i.com"]] autorelease]; |
30 | + | ||
31 | + //Customise our user agent, for no real reason | ||
32 | + [request addRequestHeader:@"User-Agent" value:@"ASIHTTPRequest"]; | ||
33 | + | ||
30 | [request start]; | 34 | [request start]; |
31 | if ([request dataString]) { | 35 | if ([request dataString]) { |
32 | [htmlSource setString:[request dataString]]; | 36 | [htmlSource setString:[request dataString]]; |
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
-
Please register or login to post a comment