/core/externals/update-engine/externals/gdata-objectivec-client/Source/HTTPFetcher/GTMHTTPFetcher.h
C++ Header | 767 lines | 239 code | 106 blank | 422 comment | 1 complexity | 9f8ba41fffe2e8c94700c35468c04fb9 MD5 | raw file
1/* Copyright (c) 2011 Google Inc. 2 * 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16// 17// GTMHTTPFetcher.h 18// 19 20// This is essentially a wrapper around NSURLConnection for POSTs and GETs. 21// If setPostData: is called, then POST is assumed. 22// 23// When would you use this instead of NSURLConnection? 24// 25// - When you just want the result from a GET, POST, or PUT 26// - When you want the "standard" behavior for connections (redirection handling 27// an so on) 28// - When you want automatic retry on failures 29// - When you want to avoid cookie collisions with Safari and other applications 30// - When you are fetching resources with ETags and want to avoid the overhead 31// of repeated fetches of unchanged data 32// - When you need to set a credential for the http operation 33// 34// This is assumed to be a one-shot fetch request; don't reuse the object 35// for a second fetch. 36// 37// The fetcher may be created auto-released, in which case it will release 38// itself after the fetch completion callback. The fetcher is implicitly 39// retained as long as a connection is pending. 40// 41// But if you may need to cancel the fetcher, retain it and have the delegate 42// release the fetcher in the callbacks. 43// 44// Sample usage: 45// 46// NSURLRequest *request = [NSURLRequest requestWithURL:myURL]; 47// GTMHTTPFetcher* myFetcher = [GTMHTTPFetcher fetcherWithRequest:request]; 48// 49// // optional upload body data 50// [myFetcher setPostData:[postString dataUsingEncoding:NSUTF8StringEncoding]]; 51// 52// [myFetcher beginFetchWithDelegate:self 53// didFinishSelector:@selector(myFetcher:finishedWithData:error:)]; 54// 55// Upon fetch completion, the callback selector is invoked; it should have 56// this signature (you can use any callback method name you want so long as 57// the signature matches this): 58// 59// - (void)myFetcher:(GTMHTTPFetcher *)fetcher finishedWithData:(NSData *)retrievedData error:(NSError *)error; 60// 61// The block callback version looks like: 62// 63// [myFetcher beginFetchWithCompletionHandler:^(NSData *retrievedData, NSError *error) { 64// if (error != nil) { 65// // status code or network error 66// } else { 67// // succeeded 68// } 69// }]; 70 71// 72// NOTE: Fetches may retrieve data from the server even though the server 73// returned an error. The failure selector is called when the server 74// status is >= 300, with an NSError having domain 75// kGTMHTTPFetcherStatusDomain and code set to the server status. 76// 77// Status codes are at <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html> 78// 79// 80// Threading and queue support: 81// 82// Callbacks require either that the thread used to start the fetcher have a run 83// loop spinning (typically the main thread), or that an NSOperationQueue be 84// provided upon which the delegate callbacks will be called. Starting with 85// iOS 6 and Mac OS X 10.7, clients may simply create an operation queue for 86// callbacks on a background thread: 87// 88// NSOperationQueue *queue = [[[NSOperationQueue alloc] init] autorelease]; 89// [queue setMaxConcurrentOperationCount:1]; 90// fetcher.delegateQueue = queue; 91// 92// or specify the main queue for callbacks on the main thread: 93// 94// fetcher.delegateQueue = [NSOperationQueue mainQueue]; 95// 96// The client may also re-dispatch from the callbacks and notifications to 97// a known dispatch queue: 98// 99// [myFetcher beginFetchWithCompletionHandler:^(NSData *retrievedData, NSError *error) { 100// if (error == nil) { 101// dispatch_async(myDispatchQueue, ^{ 102// ... 103// }); 104// } 105// }]; 106// 107// 108// 109// Downloading to disk: 110// 111// To have downloaded data saved directly to disk, specify either a path for the 112// downloadPath property, or a file handle for the downloadFileHandle property. 113// When downloading to disk, callbacks will be passed a nil for the NSData* 114// arguments. 115// 116// 117// HTTP methods and headers: 118// 119// Alternative HTTP methods, like PUT, and custom headers can be specified by 120// creating the fetcher with an appropriate NSMutableURLRequest 121// 122// 123// Proxies: 124// 125// Proxy handling is invisible so long as the system has a valid credential in 126// the keychain, which is normally true (else most NSURL-based apps would have 127// difficulty.) But when there is a proxy authetication error, the the fetcher 128// will call the failedWithError: method with the NSURLChallenge in the error's 129// userInfo. The error method can get the challenge info like this: 130// 131// NSURLAuthenticationChallenge *challenge 132// = [[error userInfo] objectForKey:kGTMHTTPFetcherErrorChallengeKey]; 133// BOOL isProxyChallenge = [[challenge protectionSpace] isProxy]; 134// 135// If a proxy error occurs, you can ask the user for the proxy username/password 136// and call fetcher's setProxyCredential: to provide those for the 137// next attempt to fetch. 138// 139// 140// Cookies: 141// 142// There are three supported mechanisms for remembering cookies between fetches. 143// 144// By default, GTMHTTPFetcher uses a mutable array held statically to track 145// cookies for all instantiated fetchers. This avoids server cookies being set 146// by servers for the application from interfering with Safari cookie settings, 147// and vice versa. The fetcher cookies are lost when the application quits. 148// 149// To rely instead on WebKit's global NSHTTPCookieStorage, call 150// setCookieStorageMethod: with kGTMHTTPFetcherCookieStorageMethodSystemDefault. 151// 152// If the fetcher is created from a GTMHTTPFetcherService object 153// then the cookie storage mechanism is set to use the cookie storage in the 154// service object rather than the static storage. 155// 156// 157// Fetching for periodic checks: 158// 159// The fetcher object tracks ETag headers from responses and 160// provide an "If-None-Match" header. This allows the server to save 161// bandwidth by providing a status message instead of repeated response 162// data. 163// 164// To get this behavior, create the fetcher from an GTMHTTPFetcherService object 165// and look for a fetch callback error with code 304 166// (kGTMHTTPFetcherStatusNotModified) like this: 167// 168// - (void)myFetcher:(GTMHTTPFetcher *)fetcher finishedWithData:(NSData *)data error:(NSError *)error { 169// if ([error code] == kGTMHTTPFetcherStatusNotModified) { 170// // |data| is empty; use the data from the previous finishedWithData: for this URL 171// } else { 172// // handle other server status code 173// } 174// } 175// 176// 177// Monitoring received data 178// 179// The optional received data selector can be set with setReceivedDataSelector: 180// and should have the signature 181// 182// - (void)myFetcher:(GTMHTTPFetcher *)fetcher receivedData:(NSData *)dataReceivedSoFar; 183// 184// The number bytes received so far is available as [fetcher downloadedLength]. 185// This number may go down if a redirect causes the download to begin again from 186// a new server. 187// 188// If supplied by the server, the anticipated total download size is available 189// as [[myFetcher response] expectedContentLength] (and may be -1 for unknown 190// download sizes.) 191// 192// 193// Automatic retrying of fetches 194// 195// The fetcher can optionally create a timer and reattempt certain kinds of 196// fetch failures (status codes 408, request timeout; 503, service unavailable; 197// 504, gateway timeout; networking errors NSURLErrorTimedOut and 198// NSURLErrorNetworkConnectionLost.) The user may set a retry selector to 199// customize the type of errors which will be retried. 200// 201// Retries are done in an exponential-backoff fashion (that is, after 1 second, 202// 2, 4, 8, and so on.) 203// 204// Enabling automatic retries looks like this: 205// [myFetcher setRetryEnabled:YES]; 206// 207// With retries enabled, the success or failure callbacks are called only 208// when no more retries will be attempted. Calling the fetcher's stopFetching 209// method will terminate the retry timer, without the finished or failure 210// selectors being invoked. 211// 212// Optionally, the client may set the maximum retry interval: 213// [myFetcher setMaxRetryInterval:60.0]; // in seconds; default is 60 seconds 214// // for downloads, 600 for uploads 215// 216// Also optionally, the client may provide a callback selector to determine 217// if a status code or other error should be retried. 218// [myFetcher setRetrySelector:@selector(myFetcher:willRetry:forError:)]; 219// 220// If set, the retry selector should have the signature: 221// -(BOOL)fetcher:(GTMHTTPFetcher *)fetcher willRetry:(BOOL)suggestedWillRetry forError:(NSError *)error 222// and return YES to set the retry timer or NO to fail without additional 223// fetch attempts. 224// 225// The retry method may return the |suggestedWillRetry| argument to get the 226// default retry behavior. Server status codes are present in the 227// error argument, and have the domain kGTMHTTPFetcherStatusDomain. The 228// user's method may look something like this: 229// 230// -(BOOL)myFetcher:(GTMHTTPFetcher *)fetcher willRetry:(BOOL)suggestedWillRetry forError:(NSError *)error { 231// 232// // perhaps examine [error domain] and [error code], or [fetcher retryCount] 233// // 234// // return YES to start the retry timer, NO to proceed to the failure 235// // callback, or |suggestedWillRetry| to get default behavior for the 236// // current error domain and code values. 237// return suggestedWillRetry; 238// } 239 240 241 242#pragma once 243 244#import <Foundation/Foundation.h> 245 246#if defined(GTL_TARGET_NAMESPACE) 247 // we're using target namespace macros 248 #import "GTLDefines.h" 249#elif defined(GDATA_TARGET_NAMESPACE) 250 #import "GDataDefines.h" 251#else 252 #if TARGET_OS_IPHONE 253 #ifndef GTM_FOUNDATION_ONLY 254 #define GTM_FOUNDATION_ONLY 1 255 #endif 256 #ifndef GTM_IPHONE 257 #define GTM_IPHONE 1 258 #endif 259 #endif 260#endif 261 262#if TARGET_OS_IPHONE && (__IPHONE_OS_VERSION_MAX_ALLOWED >= 40000) 263 #define GTM_BACKGROUND_FETCHING 1 264#endif 265 266#ifdef __cplusplus 267extern "C" { 268#endif 269 270// notifications 271// 272// fetch started and stopped, and fetch retry delay started and stopped 273extern NSString *const kGTMHTTPFetcherStartedNotification; 274extern NSString *const kGTMHTTPFetcherStoppedNotification; 275extern NSString *const kGTMHTTPFetcherRetryDelayStartedNotification; 276extern NSString *const kGTMHTTPFetcherRetryDelayStoppedNotification; 277 278// callback constants 279extern NSString *const kGTMHTTPFetcherErrorDomain; 280extern NSString *const kGTMHTTPFetcherStatusDomain; 281extern NSString *const kGTMHTTPFetcherErrorChallengeKey; 282extern NSString *const kGTMHTTPFetcherStatusDataKey; // data returned with a kGTMHTTPFetcherStatusDomain error 283 284#ifdef __cplusplus 285} 286#endif 287 288enum { 289 kGTMHTTPFetcherErrorDownloadFailed = -1, 290 kGTMHTTPFetcherErrorAuthenticationChallengeFailed = -2, 291 kGTMHTTPFetcherErrorChunkUploadFailed = -3, 292 kGTMHTTPFetcherErrorFileHandleException = -4, 293 kGTMHTTPFetcherErrorBackgroundExpiration = -6, 294 295 // The code kGTMHTTPFetcherErrorAuthorizationFailed (-5) has been removed; 296 // look for status 401 instead. 297 298 kGTMHTTPFetcherStatusNotModified = 304, 299 kGTMHTTPFetcherStatusBadRequest = 400, 300 kGTMHTTPFetcherStatusUnauthorized = 401, 301 kGTMHTTPFetcherStatusForbidden = 403, 302 kGTMHTTPFetcherStatusPreconditionFailed = 412 303}; 304 305// cookie storage methods 306enum { 307 kGTMHTTPFetcherCookieStorageMethodStatic = 0, 308 kGTMHTTPFetcherCookieStorageMethodFetchHistory = 1, 309 kGTMHTTPFetcherCookieStorageMethodSystemDefault = 2, 310 kGTMHTTPFetcherCookieStorageMethodNone = 3 311}; 312 313#ifdef __cplusplus 314extern "C" { 315#endif 316 317void GTMAssertSelectorNilOrImplementedWithArgs(id obj, SEL sel, ...); 318 319// Utility functions for applications self-identifying to servers via a 320// user-agent header 321 322// Make a proper app name without whitespace from the given string, removing 323// whitespace and other characters that may be special parsed marks of 324// the full user-agent string. 325NSString *GTMCleanedUserAgentString(NSString *str); 326 327// Make an identifier like "MacOSX/10.7.1" or "iPod_Touch/4.1" 328NSString *GTMSystemVersionString(void); 329 330// Make a generic name and version for the current application, like 331// com.example.MyApp/1.2.3 relying on the bundle identifier and the 332// CFBundleShortVersionString or CFBundleVersion. 333// 334// The bundle ID may be overridden as the base identifier string by 335// adding to the bundle's Info.plist a "GTMUserAgentID" key. 336// 337// If no bundle ID or override is available, the process name preceded 338// by "proc_" is used. 339NSString *GTMApplicationIdentifier(NSBundle *bundle); 340 341#ifdef __cplusplus 342} // extern "C" 343#endif 344 345@class GTMHTTPFetcher; 346 347@protocol GTMCookieStorageProtocol <NSObject> 348// This protocol allows us to call into the service without requiring 349// GTMCookieStorage sources in this project 350// 351// The public interface for cookie handling is the GTMCookieStorage class, 352// accessible from a fetcher service object's fetchHistory or from the fetcher's 353// +staticCookieStorage method. 354- (NSArray *)cookiesForURL:(NSURL *)theURL; 355- (void)setCookies:(NSArray *)newCookies; 356@end 357 358@protocol GTMHTTPFetchHistoryProtocol <NSObject> 359// This protocol allows us to call the fetch history object without requiring 360// GTMHTTPFetchHistory sources in this project 361- (void)updateRequest:(NSMutableURLRequest *)request isHTTPGet:(BOOL)isHTTPGet; 362- (BOOL)shouldCacheETaggedData; 363- (NSData *)cachedDataForRequest:(NSURLRequest *)request; 364- (id <GTMCookieStorageProtocol>)cookieStorage; 365- (void)updateFetchHistoryWithRequest:(NSURLRequest *)request 366 response:(NSURLResponse *)response 367 downloadedData:(NSData *)downloadedData; 368- (void)removeCachedDataForRequest:(NSURLRequest *)request; 369@end 370 371@protocol GTMHTTPFetcherServiceProtocol <NSObject> 372// This protocol allows us to call into the service without requiring 373// GTMHTTPFetcherService sources in this project 374 375@property (retain) NSOperationQueue *delegateQueue; 376 377- (BOOL)fetcherShouldBeginFetching:(GTMHTTPFetcher *)fetcher; 378- (void)fetcherDidStop:(GTMHTTPFetcher *)fetcher; 379 380- (GTMHTTPFetcher *)fetcherWithRequest:(NSURLRequest *)request; 381- (BOOL)isDelayingFetcher:(GTMHTTPFetcher *)fetcher; 382@end 383 384@protocol GTMFetcherAuthorizationProtocol <NSObject> 385@required 386// This protocol allows us to call the authorizer without requiring its sources 387// in this project. 388- (void)authorizeRequest:(NSMutableURLRequest *)request 389 delegate:(id)delegate 390 didFinishSelector:(SEL)sel; 391 392- (void)stopAuthorization; 393 394- (void)stopAuthorizationForRequest:(NSURLRequest *)request; 395 396- (BOOL)isAuthorizingRequest:(NSURLRequest *)request; 397 398- (BOOL)isAuthorizedRequest:(NSURLRequest *)request; 399 400@property (retain, readonly) NSString *userEmail; 401 402@optional 403 404// Indicate if authorization may be attempted. Even if this succeeds, 405// authorization may fail if the user's permissions have been revoked. 406@property (readonly) BOOL canAuthorize; 407 408// For development only, allow authorization of non-SSL requests, allowing 409// transmission of the bearer token unencrypted. 410@property (assign) BOOL shouldAuthorizeAllRequests; 411 412#if NS_BLOCKS_AVAILABLE 413- (void)authorizeRequest:(NSMutableURLRequest *)request 414 completionHandler:(void (^)(NSError *error))handler; 415#endif 416 417@property (assign) id <GTMHTTPFetcherServiceProtocol> fetcherService; // WEAK 418 419- (BOOL)primeForRefresh; 420 421@end 422 423// GTMHTTPFetcher objects are used for async retrieval of an http get or post 424// 425// See additional comments at the beginning of this file 426@interface GTMHTTPFetcher : NSObject { 427 @protected 428 NSMutableURLRequest *request_; 429 NSURLConnection *connection_; 430 NSMutableData *downloadedData_; 431 NSString *downloadPath_; 432 NSString *temporaryDownloadPath_; 433 NSFileHandle *downloadFileHandle_; 434 unsigned long long downloadedLength_; 435 NSURLCredential *credential_; // username & password 436 NSURLCredential *proxyCredential_; // credential supplied to proxy servers 437 NSData *postData_; 438 NSInputStream *postStream_; 439 NSMutableData *loggedStreamData_; 440 NSURLResponse *response_; // set in connection:didReceiveResponse: 441 id delegate_; 442 SEL finishedSel_; // should by implemented by delegate 443 SEL sentDataSel_; // optional, set with setSentDataSelector 444 SEL receivedDataSel_; // optional, set with setReceivedDataSelector 445#if NS_BLOCKS_AVAILABLE 446 void (^completionBlock_)(NSData *, NSError *); 447 void (^receivedDataBlock_)(NSData *); 448 void (^sentDataBlock_)(NSInteger, NSInteger, NSInteger); 449 BOOL (^retryBlock_)(BOOL, NSError *); 450#elif !__LP64__ 451 // placeholders: for 32-bit builds, keep the size of the object's ivar section 452 // the same with and without blocks 453 id completionPlaceholder_; 454 id receivedDataPlaceholder_; 455 id sentDataPlaceholder_; 456 id retryPlaceholder_; 457#endif 458 BOOL hasConnectionEnded_; // set if the connection need not be cancelled 459 BOOL isCancellingChallenge_; // set only when cancelling an auth challenge 460 BOOL isStopNotificationNeeded_; // set when start notification has been sent 461 BOOL shouldFetchInBackground_; 462#if GTM_BACKGROUND_FETCHING 463 NSUInteger backgroundTaskIdentifer_; // UIBackgroundTaskIdentifier 464#endif 465 id userData_; // retained, if set by caller 466 NSMutableDictionary *properties_; // more data retained for caller 467 NSArray *runLoopModes_; // optional 468 NSOperationQueue *delegateQueue_; // optional; available iOS 6/10.7 and later 469 id <GTMHTTPFetchHistoryProtocol> fetchHistory_; // if supplied by the caller, used for Last-Modified-Since checks and cookies 470 NSInteger cookieStorageMethod_; // constant from above 471 id <GTMCookieStorageProtocol> cookieStorage_; 472 473 id <GTMFetcherAuthorizationProtocol> authorizer_; 474 475 // the service object that created and monitors this fetcher, if any 476 id <GTMHTTPFetcherServiceProtocol> service_; 477 NSString *serviceHost_; 478 NSInteger servicePriority_; 479 NSThread *thread_; 480 481 BOOL isRetryEnabled_; // user wants auto-retry 482 SEL retrySel_; // optional; set with setRetrySelector 483 NSTimer *retryTimer_; 484 NSUInteger retryCount_; 485 NSTimeInterval maxRetryInterval_; // default 600 seconds 486 NSTimeInterval minRetryInterval_; // random between 1 and 2 seconds 487 NSTimeInterval retryFactor_; // default interval multiplier is 2 488 NSTimeInterval lastRetryInterval_; 489 NSDate *initialRequestDate_; 490 BOOL hasAttemptedAuthRefresh_; 491 492 NSString *comment_; // comment for log 493 NSString *log_; 494#if !STRIP_GTM_FETCH_LOGGING 495 NSURL *redirectedFromURL_; 496 NSString *logRequestBody_; 497 NSString *logResponseBody_; 498 BOOL hasLoggedError_; 499 BOOL shouldDeferResponseBodyLogging_; 500#endif 501} 502 503// Create a fetcher 504// 505// fetcherWithRequest will return an autoreleased fetcher, but if 506// the connection is successfully created, the connection should retain the 507// fetcher for the life of the connection as well. So the caller doesn't have 508// to retain the fetcher explicitly unless they want to be able to cancel it. 509+ (GTMHTTPFetcher *)fetcherWithRequest:(NSURLRequest *)request; 510 511// Convenience methods that make a request, like +fetcherWithRequest 512+ (GTMHTTPFetcher *)fetcherWithURL:(NSURL *)requestURL; 513+ (GTMHTTPFetcher *)fetcherWithURLString:(NSString *)requestURLString; 514 515// Designated initializer 516- (id)initWithRequest:(NSURLRequest *)request; 517 518// Fetcher request 519// 520// The underlying request is mutable and may be modified by the caller 521@property (retain) NSMutableURLRequest *mutableRequest; 522 523// Setting the credential is optional; it is used if the connection receives 524// an authentication challenge 525@property (retain) NSURLCredential *credential; 526 527// Setting the proxy credential is optional; it is used if the connection 528// receives an authentication challenge from a proxy 529@property (retain) NSURLCredential *proxyCredential; 530 531// If post data or stream is not set, then a GET retrieval method is assumed 532@property (retain) NSData *postData; 533@property (retain) NSInputStream *postStream; 534 535// The default cookie storage method is kGTMHTTPFetcherCookieStorageMethodStatic 536// without a fetch history set, and kGTMHTTPFetcherCookieStorageMethodFetchHistory 537// with a fetch history set 538// 539// Applications needing control of cookies across a sequence of fetches should 540// create fetchers from a GTMHTTPFetcherService object (which encapsulates 541// fetch history) for a well-defined cookie store 542@property (assign) NSInteger cookieStorageMethod; 543 544+ (id <GTMCookieStorageProtocol>)staticCookieStorage; 545 546// Object to add authorization to the request, if needed 547@property (retain) id <GTMFetcherAuthorizationProtocol> authorizer; 548 549// The service object that created and monitors this fetcher, if any 550@property (retain) id <GTMHTTPFetcherServiceProtocol> service; 551 552// The host, if any, used to classify this fetcher in the fetcher service 553@property (copy) NSString *serviceHost; 554 555// The priority, if any, used for starting fetchers in the fetcher service 556// 557// Lower values are higher priority; the default is 0, and values may 558// be negative or positive. This priority affects only the start order of 559// fetchers that are being delayed by a fetcher service. 560@property (assign) NSInteger servicePriority; 561 562// The thread used to run this fetcher in the fetcher service when no operation 563// queue is provided. 564@property (retain) NSThread *thread; 565 566// The delegate is retained during the connection 567@property (retain) id delegate; 568 569// On iOS 4 and later, the fetch may optionally continue while the app is in the 570// background until finished or stopped by OS expiration 571// 572// The default value is NO 573// 574// For Mac OS X, background fetches are always supported, and this property 575// is ignored 576@property (assign) BOOL shouldFetchInBackground; 577 578// The delegate's optional sentData selector may be used to monitor upload 579// progress. It should have a signature like: 580// - (void)myFetcher:(GTMHTTPFetcher *)fetcher 581// didSendBytes:(NSInteger)bytesSent 582// totalBytesSent:(NSInteger)totalBytesSent 583// totalBytesExpectedToSend:(NSInteger)totalBytesExpectedToSend; 584// 585// +doesSupportSentDataCallback indicates if this delegate method is supported 586+ (BOOL)doesSupportSentDataCallback; 587 588@property (assign) SEL sentDataSelector; 589 590// The delegate's optional receivedData selector may be used to monitor download 591// progress. It should have a signature like: 592// - (void)myFetcher:(GTMHTTPFetcher *)fetcher 593// receivedData:(NSData *)dataReceivedSoFar; 594// 595// The dataReceived argument will be nil when downloading to a path or to a 596// file handle. 597// 598// Applications should not use this method to accumulate the received data; 599// the callback method or block supplied to the beginFetch call will have 600// the complete NSData received. 601@property (assign) SEL receivedDataSelector; 602 603#if NS_BLOCKS_AVAILABLE 604// The full interface to the block is provided rather than just a typedef for 605// its parameter list in order to get more useful code completion in the Xcode 606// editor 607@property (copy) void (^sentDataBlock)(NSInteger bytesSent, NSInteger totalBytesSent, NSInteger bytesExpectedToSend); 608 609// The dataReceived argument will be nil when downloading to a path or to 610// a file handle 611@property (copy) void (^receivedDataBlock)(NSData *dataReceivedSoFar); 612#endif 613 614// retrying; see comments at the top of the file. Calling 615// setRetryEnabled(YES) resets the min and max retry intervals. 616@property (assign, getter=isRetryEnabled) BOOL retryEnabled; 617 618// Retry selector or block is optional for retries. 619// 620// If present, it should have the signature: 621// -(BOOL)fetcher:(GTMHTTPFetcher *)fetcher willRetry:(BOOL)suggestedWillRetry forError:(NSError *)error 622// and return YES to cause a retry. See comments at the top of this file. 623@property (assign) SEL retrySelector; 624 625#if NS_BLOCKS_AVAILABLE 626@property (copy) BOOL (^retryBlock)(BOOL suggestedWillRetry, NSError *error); 627#endif 628 629// Retry intervals must be strictly less than maxRetryInterval, else 630// they will be limited to maxRetryInterval and no further retries will 631// be attempted. Setting maxRetryInterval to 0.0 will reset it to the 632// default value, 600 seconds. 633 634@property (assign) NSTimeInterval maxRetryInterval; 635 636// Starting retry interval. Setting minRetryInterval to 0.0 will reset it 637// to a random value between 1.0 and 2.0 seconds. Clients should normally not 638// call this except for unit testing. 639@property (assign) NSTimeInterval minRetryInterval; 640 641// Multiplier used to increase the interval between retries, typically 2.0. 642// Clients should not need to call this. 643@property (assign) double retryFactor; 644 645// Number of retries attempted 646@property (readonly) NSUInteger retryCount; 647 648// interval delay to precede next retry 649@property (readonly) NSTimeInterval nextRetryInterval; 650 651// Begin fetching the request 652// 653// The delegate can optionally implement the finished selectors or pass NULL 654// for it. 655// 656// Returns YES if the fetch is initiated. The delegate is retained between 657// the beginFetch call until after the finish callback. 658// 659// An error is passed to the callback for server statuses 300 or 660// higher, with the status stored as the error object's code. 661// 662// finishedSEL has a signature like: 663// - (void)fetcher:(GTMHTTPFetcher *)fetcher finishedWithData:(NSData *)data error:(NSError *)error; 664// 665// If the application has specified a downloadPath or downloadFileHandle 666// for the fetcher, the data parameter passed to the callback will be nil. 667 668- (BOOL)beginFetchWithDelegate:(id)delegate 669 didFinishSelector:(SEL)finishedSEL; 670 671#if NS_BLOCKS_AVAILABLE 672- (BOOL)beginFetchWithCompletionHandler:(void (^)(NSData *data, NSError *error))handler; 673#endif 674 675 676// Returns YES if this is in the process of fetching a URL 677- (BOOL)isFetching; 678 679// Cancel the fetch of the request that's currently in progress 680- (void)stopFetching; 681 682// Return the status code from the server response 683@property (readonly) NSInteger statusCode; 684 685// Return the http headers from the response 686@property (retain, readonly) NSDictionary *responseHeaders; 687 688// The response, once it's been received 689@property (retain) NSURLResponse *response; 690 691// Bytes downloaded so far 692@property (readonly) unsigned long long downloadedLength; 693 694// Buffer of currently-downloaded data 695@property (readonly, retain) NSData *downloadedData; 696 697// Path in which to non-atomically create a file for storing the downloaded data 698// 699// The path must be set before fetching begins. The download file handle 700// will be created for the path, and can be used to monitor progress. If a file 701// already exists at the path, it will be overwritten. 702@property (copy) NSString *downloadPath; 703 704// If downloadFileHandle is set, data received is immediately appended to 705// the file handle rather than being accumulated in the downloadedData property 706// 707// The file handle supplied must allow writing and support seekToFileOffset:, 708// and must be set before fetching begins. Setting a download path will 709// override the file handle property. 710@property (retain) NSFileHandle *downloadFileHandle; 711 712// The optional fetchHistory object is used for a sequence of fetchers to 713// remember ETags, cache ETagged data, and store cookies. Typically, this 714// is set by a GTMFetcherService object when it creates a fetcher. 715// 716// Side effect: setting fetch history implicitly calls setCookieStorageMethod: 717@property (retain) id <GTMHTTPFetchHistoryProtocol> fetchHistory; 718 719// userData is retained for the convenience of the caller 720@property (retain) id userData; 721 722// Stored property values are retained for the convenience of the caller 723@property (copy) NSMutableDictionary *properties; 724 725- (void)setProperty:(id)obj forKey:(NSString *)key; // pass nil obj to remove property 726- (id)propertyForKey:(NSString *)key; 727 728- (void)addPropertiesFromDictionary:(NSDictionary *)dict; 729 730// Comments are useful for logging 731@property (copy) NSString *comment; 732 733- (void)setCommentWithFormat:(NSString *)format, ... NS_FORMAT_FUNCTION(1, 2); 734 735// Log of request and response, if logging is enabled 736@property (copy) NSString *log; 737 738// Callbacks can be invoked on an operation queue rather than via the run loop, 739// starting on 10.7 and iOS 6. If a delegate queue is supplied. the run loop 740// modes are ignored. 741@property (retain) NSOperationQueue *delegateQueue; 742 743// Using the fetcher while a modal dialog is displayed requires setting the 744// run-loop modes to include NSModalPanelRunLoopMode 745@property (retain) NSArray *runLoopModes; 746 747// Users who wish to replace GTMHTTPFetcher's use of NSURLConnection 748// can do so globally here. The replacement should be a subclass of 749// NSURLConnection. 750+ (Class)connectionClass; 751+ (void)setConnectionClass:(Class)theClass; 752 753// Spin the run loop, discarding events, until the fetch has completed 754// 755// This is only for use in testing or in tools without a user interface. 756// 757// Synchronous fetches should never be done by shipping apps; they are 758// sufficient reason for rejection from the app store. 759- (void)waitForCompletionWithTimeout:(NSTimeInterval)timeoutInSeconds; 760 761#if STRIP_GTM_FETCH_LOGGING 762// if logging is stripped, provide a stub for the main method 763// for controlling logging 764+ (void)setLoggingEnabled:(BOOL)flag; 765#endif // STRIP_GTM_FETCH_LOGGING 766 767@end