BBGMultiAccountManager
|
00001 /* Copyright (c) 2011 Google Inc. 00002 * 00003 * Licensed under the Apache License, Version 2.0 (the "License"); 00004 * you may not use this file except in compliance with the License. 00005 * You may obtain a copy of the License at 00006 * 00007 * http://www.apache.org/licenses/LICENSE-2.0 00008 * 00009 * Unless required by applicable law or agreed to in writing, software 00010 * distributed under the License is distributed on an "AS IS" BASIS, 00011 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00012 * See the License for the specific language governing permissions and 00013 * limitations under the License. 00014 */ 00015 00016 // 00017 // GTMHTTPFetcher.h 00018 // 00019 00020 // This is essentially a wrapper around NSURLConnection for POSTs and GETs. 00021 // If setPostData: is called, then POST is assumed. 00022 // 00023 // When would you use this instead of NSURLConnection? 00024 // 00025 // - When you just want the result from a GET, POST, or PUT 00026 // - When you want the "standard" behavior for connections (redirection handling 00027 // an so on) 00028 // - When you want automatic retry on failures 00029 // - When you want to avoid cookie collisions with Safari and other applications 00030 // - When you are fetching resources with ETags and want to avoid the overhead 00031 // of repeated fetches of unchanged data 00032 // - When you need to set a credential for the http operation 00033 // 00034 // This is assumed to be a one-shot fetch request; don't reuse the object 00035 // for a second fetch. 00036 // 00037 // The fetcher may be created auto-released, in which case it will release 00038 // itself after the fetch completion callback. The fetcher is implicitly 00039 // retained as long as a connection is pending. 00040 // 00041 // But if you may need to cancel the fetcher, retain it and have the delegate 00042 // release the fetcher in the callbacks. 00043 // 00044 // Sample usage: 00045 // 00046 // NSURLRequest *request = [NSURLRequest requestWithURL:myURL]; 00047 // GTMHTTPFetcher* myFetcher = [GTMHTTPFetcher fetcherWithRequest:request]; 00048 // 00049 // // optional upload body data 00050 // [myFetcher setPostData:[postString dataUsingEncoding:NSUTF8StringEncoding]]; 00051 // 00052 // [myFetcher beginFetchWithDelegate:self 00053 // didFinishSelector:@selector(myFetcher:finishedWithData:error:)]; 00054 // 00055 // Upon fetch completion, the callback selector is invoked; it should have 00056 // this signature (you can use any callback method name you want so long as 00057 // the signature matches this): 00058 // 00059 // - (void)myFetcher:(GTMHTTPFetcher *)fetcher finishedWithData:(NSData *)retrievedData error:(NSError *)error; 00060 // 00061 // The block callback version looks like: 00062 // 00063 // [myFetcher beginFetchWithCompletionHandler:^(NSData *retrievedData, NSError *error) { 00064 // if (error != nil) { 00065 // // status code or network error 00066 // } else { 00067 // // succeeded 00068 // } 00069 // }]; 00070 00071 // 00072 // NOTE: Fetches may retrieve data from the server even though the server 00073 // returned an error. The failure selector is called when the server 00074 // status is >= 300, with an NSError having domain 00075 // kGTMHTTPFetcherStatusDomain and code set to the server status. 00076 // 00077 // Status codes are at <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html> 00078 // 00079 // 00080 // Downloading to disk: 00081 // 00082 // To have downloaded data saved directly to disk, specify either a path for the 00083 // downloadPath property, or a file handle for the downloadFileHandle property. 00084 // When downloading to disk, callbacks will be passed a nil for the NSData* 00085 // arguments. 00086 // 00087 // 00088 // HTTP methods and headers: 00089 // 00090 // Alternative HTTP methods, like PUT, and custom headers can be specified by 00091 // creating the fetcher with an appropriate NSMutableURLRequest 00092 // 00093 // 00094 // Proxies: 00095 // 00096 // Proxy handling is invisible so long as the system has a valid credential in 00097 // the keychain, which is normally true (else most NSURL-based apps would have 00098 // difficulty.) But when there is a proxy authetication error, the the fetcher 00099 // will call the failedWithError: method with the NSURLChallenge in the error's 00100 // userInfo. The error method can get the challenge info like this: 00101 // 00102 // NSURLAuthenticationChallenge *challenge 00103 // = [[error userInfo] objectForKey:kGTMHTTPFetcherErrorChallengeKey]; 00104 // BOOL isProxyChallenge = [[challenge protectionSpace] isProxy]; 00105 // 00106 // If a proxy error occurs, you can ask the user for the proxy username/password 00107 // and call fetcher's setProxyCredential: to provide those for the 00108 // next attempt to fetch. 00109 // 00110 // 00111 // Cookies: 00112 // 00113 // There are three supported mechanisms for remembering cookies between fetches. 00114 // 00115 // By default, GTMHTTPFetcher uses a mutable array held statically to track 00116 // cookies for all instantiated fetchers. This avoids server cookies being set 00117 // by servers for the application from interfering with Safari cookie settings, 00118 // and vice versa. The fetcher cookies are lost when the application quits. 00119 // 00120 // To rely instead on WebKit's global NSHTTPCookieStorage, call 00121 // setCookieStorageMethod: with kGTMHTTPFetcherCookieStorageMethodSystemDefault. 00122 // 00123 // If the fetcher is created from a GTMHTTPFetcherService object 00124 // then the cookie storage mechanism is set to use the cookie storage in the 00125 // service object rather than the static storage. 00126 // 00127 // 00128 // Fetching for periodic checks: 00129 // 00130 // The fetcher object tracks ETag headers from responses and 00131 // provide an "If-None-Match" header. This allows the server to save 00132 // bandwidth by providing a status message instead of repeated response 00133 // data. 00134 // 00135 // To get this behavior, create the fetcher from an GTMHTTPFetcherService object 00136 // and look for a fetch callback error with code 304 00137 // (kGTMHTTPFetcherStatusNotModified) like this: 00138 // 00139 // - (void)myFetcher:(GTMHTTPFetcher *)fetcher finishedWithData:(NSData *)data error:(NSError *)error { 00140 // if ([error code] == kGTMHTTPFetcherStatusNotModified) { 00141 // // |data| is empty; use the data from the previous finishedWithData: for this URL 00142 // } else { 00143 // // handle other server status code 00144 // } 00145 // } 00146 // 00147 // 00148 // Monitoring received data 00149 // 00150 // The optional received data selector can be set with setReceivedDataSelector: 00151 // and should have the signature 00152 // 00153 // - (void)myFetcher:(GTMHTTPFetcher *)fetcher receivedData:(NSData *)dataReceivedSoFar; 00154 // 00155 // The number bytes received so far is available as [fetcher downloadedLength]. 00156 // This number may go down if a redirect causes the download to begin again from 00157 // a new server. 00158 // 00159 // If supplied by the server, the anticipated total download size is available 00160 // as [[myFetcher response] expectedContentLength] (and may be -1 for unknown 00161 // download sizes.) 00162 // 00163 // 00164 // Automatic retrying of fetches 00165 // 00166 // The fetcher can optionally create a timer and reattempt certain kinds of 00167 // fetch failures (status codes 408, request timeout; 503, service unavailable; 00168 // 504, gateway timeout; networking errors NSURLErrorTimedOut and 00169 // NSURLErrorNetworkConnectionLost.) The user may set a retry selector to 00170 // customize the type of errors which will be retried. 00171 // 00172 // Retries are done in an exponential-backoff fashion (that is, after 1 second, 00173 // 2, 4, 8, and so on.) 00174 // 00175 // Enabling automatic retries looks like this: 00176 // [myFetcher setRetryEnabled:YES]; 00177 // 00178 // With retries enabled, the success or failure callbacks are called only 00179 // when no more retries will be attempted. Calling the fetcher's stopFetching 00180 // method will terminate the retry timer, without the finished or failure 00181 // selectors being invoked. 00182 // 00183 // Optionally, the client may set the maximum retry interval: 00184 // [myFetcher setMaxRetryInterval:60.0]; // in seconds; default is 60 seconds 00185 // // for downloads, 600 for uploads 00186 // 00187 // Also optionally, the client may provide a callback selector to determine 00188 // if a status code or other error should be retried. 00189 // [myFetcher setRetrySelector:@selector(myFetcher:willRetry:forError:)]; 00190 // 00191 // If set, the retry selector should have the signature: 00192 // -(BOOL)fetcher:(GTMHTTPFetcher *)fetcher willRetry:(BOOL)suggestedWillRetry forError:(NSError *)error 00193 // and return YES to set the retry timer or NO to fail without additional 00194 // fetch attempts. 00195 // 00196 // The retry method may return the |suggestedWillRetry| argument to get the 00197 // default retry behavior. Server status codes are present in the 00198 // error argument, and have the domain kGTMHTTPFetcherStatusDomain. The 00199 // user's method may look something like this: 00200 // 00201 // -(BOOL)myFetcher:(GTMHTTPFetcher *)fetcher willRetry:(BOOL)suggestedWillRetry forError:(NSError *)error { 00202 // 00203 // // perhaps examine [error domain] and [error code], or [fetcher retryCount] 00204 // // 00205 // // return YES to start the retry timer, NO to proceed to the failure 00206 // // callback, or |suggestedWillRetry| to get default behavior for the 00207 // // current error domain and code values. 00208 // return suggestedWillRetry; 00209 // } 00210 00211 00212 00213 #pragma once 00214 00215 #import <Foundation/Foundation.h> 00216 00217 #if defined(GTL_TARGET_NAMESPACE) 00218 // we're using target namespace macros 00219 #import "GTLDefines.h" 00220 #elif defined(GDATA_TARGET_NAMESPACE) 00221 #import "GDataDefines.h" 00222 #else 00223 #if TARGET_OS_IPHONE 00224 #ifndef GTM_FOUNDATION_ONLY 00225 #define GTM_FOUNDATION_ONLY 1 00226 #endif 00227 #ifndef GTM_IPHONE 00228 #define GTM_IPHONE 1 00229 #endif 00230 #endif 00231 #endif 00232 00233 #if TARGET_OS_IPHONE && (__IPHONE_OS_VERSION_MAX_ALLOWED >= 40000) 00234 #define GTM_BACKGROUND_FETCHING 1 00235 #endif 00236 00237 #undef _EXTERN 00238 #undef _INITIALIZE_AS 00239 #ifdef GTMHTTPFETCHER_DEFINE_GLOBALS 00240 #define _EXTERN 00241 #define _INITIALIZE_AS(x) =x 00242 #else 00243 #if defined(__cplusplus) 00244 #define _EXTERN extern "C" 00245 #else 00246 #define _EXTERN extern 00247 #endif 00248 #define _INITIALIZE_AS(x) 00249 #endif 00250 00251 // notifications 00252 // 00253 // fetch started and stopped, and fetch retry delay started and stopped 00254 _EXTERN NSString* const kGTMHTTPFetcherStartedNotification _INITIALIZE_AS(@"kGTMHTTPFetcherStartedNotification"); 00255 _EXTERN NSString* const kGTMHTTPFetcherStoppedNotification _INITIALIZE_AS(@"kGTMHTTPFetcherStoppedNotification"); 00256 _EXTERN NSString* const kGTMHTTPFetcherRetryDelayStartedNotification _INITIALIZE_AS(@"kGTMHTTPFetcherRetryDelayStartedNotification"); 00257 _EXTERN NSString* const kGTMHTTPFetcherRetryDelayStoppedNotification _INITIALIZE_AS(@"kGTMHTTPFetcherRetryDelayStoppedNotification"); 00258 00259 // callback constants 00260 _EXTERN NSString* const kGTMHTTPFetcherErrorDomain _INITIALIZE_AS(@"com.google.GTMHTTPFetcher"); 00261 _EXTERN NSString* const kGTMHTTPFetcherStatusDomain _INITIALIZE_AS(@"com.google.HTTPStatus"); 00262 _EXTERN NSString* const kGTMHTTPFetcherErrorChallengeKey _INITIALIZE_AS(@"challenge"); 00263 _EXTERN NSString* const kGTMHTTPFetcherStatusDataKey _INITIALIZE_AS(@"data"); // data returned with a kGTMHTTPFetcherStatusDomain error 00264 00265 enum { 00266 kGTMHTTPFetcherErrorDownloadFailed = -1, 00267 kGTMHTTPFetcherErrorAuthenticationChallengeFailed = -2, 00268 kGTMHTTPFetcherErrorChunkUploadFailed = -3, 00269 kGTMHTTPFetcherErrorFileHandleException = -4, 00270 kGTMHTTPFetcherErrorBackgroundExpiration = -6, 00271 00272 // The code kGTMHTTPFetcherErrorAuthorizationFailed (-5) has been removed; 00273 // look for status 401 instead. 00274 00275 kGTMHTTPFetcherStatusNotModified = 304, 00276 kGTMHTTPFetcherStatusBadRequest = 400, 00277 kGTMHTTPFetcherStatusUnauthorized = 401, 00278 kGTMHTTPFetcherStatusForbidden = 403, 00279 kGTMHTTPFetcherStatusPreconditionFailed = 412 00280 }; 00281 00282 // cookie storage methods 00283 enum { 00284 kGTMHTTPFetcherCookieStorageMethodStatic = 0, 00285 kGTMHTTPFetcherCookieStorageMethodFetchHistory = 1, 00286 kGTMHTTPFetcherCookieStorageMethodSystemDefault = 2, 00287 kGTMHTTPFetcherCookieStorageMethodNone = 3 00288 }; 00289 00290 void GTMAssertSelectorNilOrImplementedWithArgs(id obj, SEL sel, ...); 00291 00292 // Utility functions for applications self-identifying to servers via a 00293 // user-agent header 00294 00295 // Make a proper app name without whitespace from the given string, removing 00296 // whitespace and other characters that may be special parsed marks of 00297 // the full user-agent string. 00298 NSString *GTMCleanedUserAgentString(NSString *str); 00299 00300 // Make an identifier like "MacOSX/10.7.1" or "iPod_Touch/4.1" 00301 NSString *GTMSystemVersionString(void); 00302 00303 // Make a generic name and version for the current application, like 00304 // com.example.MyApp/1.2.3 relying on the bundle identifier and the 00305 // CFBundleShortVersionString or CFBundleVersion. If no bundle ID 00306 // is available, the process name preceded by "proc_" is used. 00307 NSString *GTMApplicationIdentifier(NSBundle *bundle); 00308 00309 @class GTMHTTPFetcher; 00310 00311 @protocol GTMCookieStorageProtocol <NSObject> 00312 // This protocol allows us to call into the service without requiring 00313 // GTMCookieStorage sources in this project 00314 // 00315 // The public interface for cookie handling is the GTMCookieStorage class, 00316 // accessible from a fetcher service object's fetchHistory or from the fetcher's 00317 // +staticCookieStorage method. 00318 - (NSArray *)cookiesForURL:(NSURL *)theURL; 00319 - (void)setCookies:(NSArray *)newCookies; 00320 @end 00321 00322 @protocol GTMHTTPFetchHistoryProtocol <NSObject> 00323 // This protocol allows us to call the fetch history object without requiring 00324 // GTMHTTPFetchHistory sources in this project 00325 - (void)updateRequest:(NSMutableURLRequest *)request isHTTPGet:(BOOL)isHTTPGet; 00326 - (BOOL)shouldCacheETaggedData; 00327 - (NSData *)cachedDataForRequest:(NSURLRequest *)request; 00328 - (id <GTMCookieStorageProtocol>)cookieStorage; 00329 - (void)updateFetchHistoryWithRequest:(NSURLRequest *)request 00330 response:(NSURLResponse *)response 00331 downloadedData:(NSData *)downloadedData; 00332 - (void)removeCachedDataForRequest:(NSURLRequest *)request; 00333 @end 00334 00335 @protocol GTMHTTPFetcherServiceProtocol <NSObject> 00336 // This protocol allows us to call into the service without requiring 00337 // GTMHTTPFetcherService sources in this project 00338 - (BOOL)fetcherShouldBeginFetching:(GTMHTTPFetcher *)fetcher; 00339 - (void)fetcherDidStop:(GTMHTTPFetcher *)fetcher; 00340 00341 - (GTMHTTPFetcher *)fetcherWithRequest:(NSURLRequest *)request; 00342 - (BOOL)isDelayingFetcher:(GTMHTTPFetcher *)fetcher; 00343 @end 00344 00345 @protocol GTMFetcherAuthorizationProtocol <NSObject> 00346 @required 00347 // This protocol allows us to call the authorizer without requiring its sources 00348 // in this project 00349 - (void)authorizeRequest:(NSMutableURLRequest *)request 00350 delegate:(id)delegate 00351 didFinishSelector:(SEL)sel; 00352 00353 - (void)stopAuthorization; 00354 00355 - (BOOL)isAuthorizingRequest:(NSURLRequest *)request; 00356 00357 - (BOOL)isAuthorizedRequest:(NSURLRequest *)request; 00358 00359 - (NSString *)userEmail; 00360 00361 @optional 00362 @property (assign) id <GTMHTTPFetcherServiceProtocol> fetcherService; // WEAK 00363 00364 - (BOOL)primeForRefresh; 00365 @end 00366 00367 // GTMHTTPFetcher objects are used for async retrieval of an http get or post 00368 // 00369 // See additional comments at the beginning of this file 00370 @interface GTMHTTPFetcher : NSObject { 00371 @protected 00372 NSMutableURLRequest *request_; 00373 NSURLConnection *connection_; 00374 NSMutableData *downloadedData_; 00375 NSString *downloadPath_; 00376 NSString *temporaryDownloadPath_; 00377 NSFileHandle *downloadFileHandle_; 00378 unsigned long long downloadedLength_; 00379 NSURLCredential *credential_; // username & password 00380 NSURLCredential *proxyCredential_; // credential supplied to proxy servers 00381 NSData *postData_; 00382 NSInputStream *postStream_; 00383 NSMutableData *loggedStreamData_; 00384 NSURLResponse *response_; // set in connection:didReceiveResponse: 00385 id delegate_; 00386 SEL finishedSel_; // should by implemented by delegate 00387 SEL sentDataSel_; // optional, set with setSentDataSelector 00388 SEL receivedDataSel_; // optional, set with setReceivedDataSelector 00389 #if NS_BLOCKS_AVAILABLE 00390 void (^completionBlock_)(NSData *, NSError *); 00391 void (^receivedDataBlock_)(NSData *); 00392 void (^sentDataBlock_)(NSInteger, NSInteger, NSInteger); 00393 BOOL (^retryBlock_)(BOOL, NSError *); 00394 #elif !__LP64__ 00395 // placeholders: for 32-bit builds, keep the size of the object's ivar section 00396 // the same with and without blocks 00397 id completionPlaceholder_; 00398 id receivedDataPlaceholder_; 00399 id sentDataPlaceholder_; 00400 id retryPlaceholder_; 00401 #endif 00402 BOOL hasConnectionEnded_; // set if the connection need not be cancelled 00403 BOOL isCancellingChallenge_; // set only when cancelling an auth challenge 00404 BOOL isStopNotificationNeeded_; // set when start notification has been sent 00405 BOOL shouldFetchInBackground_; 00406 #if GTM_BACKGROUND_FETCHING 00407 NSUInteger backgroundTaskIdentifer_; // UIBackgroundTaskIdentifier 00408 #endif 00409 id userData_; // retained, if set by caller 00410 NSMutableDictionary *properties_; // more data retained for caller 00411 NSArray *runLoopModes_; // optional, for 10.5 and later 00412 id <GTMHTTPFetchHistoryProtocol> fetchHistory_; // if supplied by the caller, used for Last-Modified-Since checks and cookies 00413 NSInteger cookieStorageMethod_; // constant from above 00414 id <GTMCookieStorageProtocol> cookieStorage_; 00415 00416 id <GTMFetcherAuthorizationProtocol> authorizer_; 00417 00418 // the service object that created and monitors this fetcher, if any 00419 id <GTMHTTPFetcherServiceProtocol> service_; 00420 NSString *serviceHost_; 00421 NSInteger servicePriority_; 00422 NSThread *thread_; 00423 00424 BOOL isRetryEnabled_; // user wants auto-retry 00425 SEL retrySel_; // optional; set with setRetrySelector 00426 NSTimer *retryTimer_; 00427 NSUInteger retryCount_; 00428 NSTimeInterval maxRetryInterval_; // default 600 seconds 00429 NSTimeInterval minRetryInterval_; // random between 1 and 2 seconds 00430 NSTimeInterval retryFactor_; // default interval multiplier is 2 00431 NSTimeInterval lastRetryInterval_; 00432 BOOL hasAttemptedAuthRefresh_; 00433 00434 NSString *comment_; // comment for log 00435 NSString *log_; 00436 } 00437 00438 // Create a fetcher 00439 // 00440 // fetcherWithRequest will return an autoreleased fetcher, but if 00441 // the connection is successfully created, the connection should retain the 00442 // fetcher for the life of the connection as well. So the caller doesn't have 00443 // to retain the fetcher explicitly unless they want to be able to cancel it. 00444 + (GTMHTTPFetcher *)fetcherWithRequest:(NSURLRequest *)request; 00445 00446 // Convenience methods that make a request, like +fetcherWithRequest 00447 + (GTMHTTPFetcher *)fetcherWithURL:(NSURL *)requestURL; 00448 + (GTMHTTPFetcher *)fetcherWithURLString:(NSString *)requestURLString; 00449 00450 // Designated initializer 00451 - (id)initWithRequest:(NSURLRequest *)request; 00452 00453 // Fetcher request 00454 // 00455 // The underlying request is mutable and may be modified by the caller 00456 @property (retain) NSMutableURLRequest *mutableRequest; 00457 00458 // Setting the credential is optional; it is used if the connection receives 00459 // an authentication challenge 00460 @property (retain) NSURLCredential *credential; 00461 00462 // Setting the proxy credential is optional; it is used if the connection 00463 // receives an authentication challenge from a proxy 00464 @property (retain) NSURLCredential *proxyCredential; 00465 00466 // If post data or stream is not set, then a GET retrieval method is assumed 00467 @property (retain) NSData *postData; 00468 @property (retain) NSInputStream *postStream; 00469 00470 // The default cookie storage method is kGTMHTTPFetcherCookieStorageMethodStatic 00471 // without a fetch history set, and kGTMHTTPFetcherCookieStorageMethodFetchHistory 00472 // with a fetch history set 00473 // 00474 // Applications needing control of cookies across a sequence of fetches should 00475 // create fetchers from a GTMHTTPFetcherService object (which encapsulates 00476 // fetch history) for a well-defined cookie store 00477 @property (assign) NSInteger cookieStorageMethod; 00478 00479 + (id <GTMCookieStorageProtocol>)staticCookieStorage; 00480 00481 // Object to add authorization to the request, if needed 00482 @property (retain) id <GTMFetcherAuthorizationProtocol> authorizer; 00483 00484 // The service object that created and monitors this fetcher, if any 00485 @property (retain) id <GTMHTTPFetcherServiceProtocol> service; 00486 00487 // The host, if any, used to classify this fetcher in the fetcher service 00488 @property (copy) NSString *serviceHost; 00489 00490 // The priority, if any, used for starting fetchers in the fetcher service 00491 // 00492 // Lower values are higher priority; the default is 0, and values may 00493 // be negative or positive. This priority affects only the start order of 00494 // fetchers that are being delayed by a fetcher service. 00495 @property (assign) NSInteger servicePriority; 00496 00497 // The thread used to run this fetcher in the fetcher service 00498 @property (retain) NSThread *thread; 00499 00500 // The delegate is retained during the connection 00501 @property (retain) id delegate; 00502 00503 // On iOS 4 and later, the fetch may optionally continue while the app is in the 00504 // background until finished or stopped by OS expiration 00505 // 00506 // The default value is NO 00507 // 00508 // For Mac OS X, background fetches are always supported, and this property 00509 // is ignored 00510 @property (assign) BOOL shouldFetchInBackground; 00511 00512 // The delegate's optional sentData selector may be used to monitor upload 00513 // progress. It should have a signature like: 00514 // - (void)myFetcher:(GTMHTTPFetcher *)fetcher 00515 // didSendBytes:(NSInteger)bytesSent 00516 // totalBytesSent:(NSInteger)totalBytesSent 00517 // totalBytesExpectedToSend:(NSInteger)totalBytesExpectedToSend; 00518 // 00519 // +doesSupportSentDataCallback indicates if this delegate method is supported 00520 + (BOOL)doesSupportSentDataCallback; 00521 00522 @property (assign) SEL sentDataSelector; 00523 00524 // The delegate's optional receivedData selector may be used to monitor download 00525 // progress. It should have a signature like: 00526 // - (void)myFetcher:(GTMHTTPFetcher *)fetcher 00527 // receivedData:(NSData *)dataReceivedSoFar; 00528 // 00529 // The dataReceived argument will be nil when downloading to a path or to a 00530 // file handle. 00531 // 00532 // Applications should not use this method to accumulate the received data; 00533 // the callback method or block supplied to the beginFetch call will have 00534 // the complete NSData received. 00535 @property (assign) SEL receivedDataSelector; 00536 00537 #if NS_BLOCKS_AVAILABLE 00538 // The full interface to the block is provided rather than just a typedef for 00539 // its parameter list in order to get more useful code completion in the Xcode 00540 // editor 00541 @property (copy) void (^sentDataBlock)(NSInteger bytesSent, NSInteger totalBytesSent, NSInteger bytesExpectedToSend); 00542 00543 // The dataReceived argument will be nil when downloading to a path or to 00544 // a file handle 00545 @property (copy) void (^receivedDataBlock)(NSData *dataReceivedSoFar); 00546 #endif 00547 00548 // retrying; see comments at the top of the file. Calling 00549 // setRetryEnabled(YES) resets the min and max retry intervals. 00550 @property (assign, getter=isRetryEnabled) BOOL retryEnabled; 00551 00552 // Retry selector or block is optional for retries. 00553 // 00554 // If present, it should have the signature: 00555 // -(BOOL)fetcher:(GTMHTTPFetcher *)fetcher willRetry:(BOOL)suggestedWillRetry forError:(NSError *)error 00556 // and return YES to cause a retry. See comments at the top of this file. 00557 @property (assign) SEL retrySelector; 00558 00559 #if NS_BLOCKS_AVAILABLE 00560 @property (copy) BOOL (^retryBlock)(BOOL suggestedWillRetry, NSError *error); 00561 #endif 00562 00563 // Retry intervals must be strictly less than maxRetryInterval, else 00564 // they will be limited to maxRetryInterval and no further retries will 00565 // be attempted. Setting maxRetryInterval to 0.0 will reset it to the 00566 // default value, 600 seconds. 00567 00568 @property (assign) NSTimeInterval maxRetryInterval; 00569 00570 // Starting retry interval. Setting minRetryInterval to 0.0 will reset it 00571 // to a random value between 1.0 and 2.0 seconds. Clients should normally not 00572 // call this except for unit testing. 00573 @property (assign) NSTimeInterval minRetryInterval; 00574 00575 // Multiplier used to increase the interval between retries, typically 2.0. 00576 // Clients should not need to call this. 00577 @property (assign) double retryFactor; 00578 00579 // Number of retries attempted 00580 @property (readonly) NSUInteger retryCount; 00581 00582 // interval delay to precede next retry 00583 @property (readonly) NSTimeInterval nextRetryInterval; 00584 00585 // Begin fetching the request 00586 // 00587 // The delegate can optionally implement the finished selectors or pass NULL 00588 // for it. 00589 // 00590 // Returns YES if the fetch is initiated. The delegate is retained between 00591 // the beginFetch call until after the finish callback. 00592 // 00593 // An error is passed to the callback for server statuses 300 or 00594 // higher, with the status stored as the error object's code. 00595 // 00596 // finishedSEL has a signature like: 00597 // - (void)fetcher:(GTMHTTPFetcher *)fetcher finishedWithData:(NSData *)data error:(NSError *)error; 00598 // 00599 // If the application has specified a downloadPath or downloadFileHandle 00600 // for the fetcher, the data parameter passed to the callback will be nil. 00601 00602 - (BOOL)beginFetchWithDelegate:(id)delegate 00603 didFinishSelector:(SEL)finishedSEL; 00604 00605 #if NS_BLOCKS_AVAILABLE 00606 - (BOOL)beginFetchWithCompletionHandler:(void (^)(NSData *data, NSError *error))handler; 00607 #endif 00608 00609 00610 // Returns YES if this is in the process of fetching a URL 00611 - (BOOL)isFetching; 00612 00613 // Cancel the fetch of the request that's currently in progress 00614 - (void)stopFetching; 00615 00616 // Return the status code from the server response 00617 @property (readonly) NSInteger statusCode; 00618 00619 // Return the http headers from the response 00620 @property (retain, readonly) NSDictionary *responseHeaders; 00621 00622 // The response, once it's been received 00623 @property (retain) NSURLResponse *response; 00624 00625 // Bytes downloaded so far 00626 @property (readonly) unsigned long long downloadedLength; 00627 00628 // Buffer of currently-downloaded data 00629 @property (readonly, retain) NSData *downloadedData; 00630 00631 // Path in which to non-atomically create a file for storing the downloaded data 00632 // 00633 // The path must be set before fetching begins. The download file handle 00634 // will be created for the path, and can be used to monitor progress. If a file 00635 // already exists at the path, it will be overwritten. 00636 @property (copy) NSString *downloadPath; 00637 00638 // If downloadFileHandle is set, data received is immediately appended to 00639 // the file handle rather than being accumulated in the downloadedData property 00640 // 00641 // The file handle supplied must allow writing and support seekToFileOffset:, 00642 // and must be set before fetching begins. Setting a download path will 00643 // override the file handle property. 00644 @property (retain) NSFileHandle *downloadFileHandle; 00645 00646 // The optional fetchHistory object is used for a sequence of fetchers to 00647 // remember ETags, cache ETagged data, and store cookies. Typically, this 00648 // is set by a GTMFetcherService object when it creates a fetcher. 00649 // 00650 // Side effect: setting fetch history implicitly calls setCookieStorageMethod: 00651 @property (retain) id <GTMHTTPFetchHistoryProtocol> fetchHistory; 00652 00653 // userData is retained for the convenience of the caller 00654 @property (retain) id userData; 00655 00656 // Stored property values are retained for the convenience of the caller 00657 @property (copy) NSMutableDictionary *properties; 00658 00659 - (void)setProperty:(id)obj forKey:(NSString *)key; // pass nil obj to remove property 00660 - (id)propertyForKey:(NSString *)key; 00661 00662 - (void)addPropertiesFromDictionary:(NSDictionary *)dict; 00663 00664 // Comments are useful for logging 00665 @property (copy) NSString *comment; 00666 00667 - (void)setCommentWithFormat:(id)format, ...; 00668 00669 // Log of request and response, if logging is enabled 00670 @property (copy) NSString *log; 00671 00672 // Using the fetcher while a modal dialog is displayed requires setting the 00673 // run-loop modes to include NSModalPanelRunLoopMode 00674 @property (retain) NSArray *runLoopModes; 00675 00676 // Users who wish to replace GTMHTTPFetcher's use of NSURLConnection 00677 // can do so globally here. The replacement should be a subclass of 00678 // NSURLConnection. 00679 + (Class)connectionClass; 00680 + (void)setConnectionClass:(Class)theClass; 00681 00682 // Spin the run loop, discarding events, until the fetch has completed 00683 // 00684 // This is only for use in testing or in tools without a user interface. 00685 // 00686 // Synchronous fetches should never be done by shipping apps; they are 00687 // sufficient reason for rejection from the app store. 00688 - (void)waitForCompletionWithTimeout:(NSTimeInterval)timeoutInSeconds; 00689 00690 #if STRIP_GTM_FETCH_LOGGING 00691 // if logging is stripped, provide a stub for the main method 00692 // for controlling logging 00693 + (void)setLoggingEnabled:(BOOL)flag; 00694 #endif // STRIP_GTM_FETCH_LOGGING 00695 00696 @end