PageRenderTime 71ms CodeModel.GetById 12ms app.highlight 54ms RepoModel.GetById 1ms app.codeStats 0ms

/Source/externals/GData/Source/BaseClasses/GDataServiceBase.h

http://google-email-uploader-mac.googlecode.com/
C++ Header | 584 lines | 253 code | 122 blank | 209 comment | 0 complexity | 8b1c8d7f36307e3dca7342dcdb57602c MD5 | raw file
  1/* Copyright (c) 2007 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//  GDataServiceBase.h
 18//
 19
 20#import "GTMHTTPFetcherService.h"
 21
 22#import "GDataEntryBase.h"
 23#import "GDataFeedBase.h"
 24#import "GDataQuery.h"
 25
 26#undef _EXTERN
 27#undef _INITIALIZE_AS
 28#ifdef GDATASERVICEBASE_DEFINE_GLOBALS
 29#define _EXTERN
 30#define _INITIALIZE_AS(x) =x
 31#else
 32#define _EXTERN GDATA_EXTERN
 33#define _INITIALIZE_AS(x)
 34#endif
 35
 36_EXTERN Class const kGDataUseRegisteredClass _INITIALIZE_AS(nil);
 37
 38_EXTERN NSString* const kGDataServiceErrorDomain _INITIALIZE_AS(@"com.google.GDataServiceDomain");
 39
 40_EXTERN NSUInteger const kGDataStandardUploadChunkSize _INITIALIZE_AS(NSUIntegerMax);
 41
 42// we'll consistently store the server error string in the userInfo under
 43// this key
 44_EXTERN NSString* const kGDataServerErrorStringKey     _INITIALIZE_AS(@"error");
 45
 46
 47// when servers return us structured XML errors, the NSError will
 48// contain a GDataErrorGroup in the userInfo dictionary under the key
 49// kGDataStructuredErrorsKey
 50_EXTERN NSString* const kGDataStructuredErrorsKey _INITIALIZE_AS(@"serverErrors");
 51
 52// when specifying an ETag for updating or deleting a single entry, use
 53// kGDataETagWildcard to tell the server to replace the current value
 54// unconditionally.  Do not use this in entries in a batch feed.
 55_EXTERN NSString* const kGDataETagWildcard _INITIALIZE_AS(@"*");
 56
 57// notifications when parsing of a fetcher feed or entry begins or ends
 58_EXTERN NSString* const kGDataServiceTicketParsingStartedNotification _INITIALIZE_AS(@"kGDataServiceTicketParsingStartedNotification");
 59_EXTERN NSString* const kGDataServiceTicketParsingStoppedNotification _INITIALIZE_AS(@"kGDataServiceTicketParsingStoppedNotification");
 60
 61enum {
 62  kGDataCouldNotConstructObjectError = -100,
 63};
 64
 65@class GDataServiceTicketBase;
 66
 67// block types used for fetch callbacks
 68//
 69// these typedefs are not used in the header file method declarations
 70// since it's more useful when code sense expansions show the argument
 71// types rather than the typedefs
 72
 73#if NS_BLOCKS_AVAILABLE
 74typedef void (^GDataServiceCompletionHandler)(GDataServiceTicketBase *ticket, id object, NSError *error);
 75typedef void (^GDataServiceFeedBaseCompletionHandler)(GDataServiceTicketBase *ticket, GDataFeedBase *feed, NSError *error);
 76typedef void (^GDataServiceEntryBaseCompletionHandler)(GDataServiceTicketBase *ticket, GDataEntryBase *entry, NSError *error);
 77
 78typedef void (^GDataServiceUploadProgressHandler)(GDataServiceTicketBase *ticket, unsigned long long numberOfBytesRead, unsigned long long dataLength);
 79#else
 80typedef void *GDataServiceCompletionHandler;
 81typedef void *GDataServiceFeedBaseCompletionHandler;
 82typedef void *GDataServiceEntryBaseCompletionHandler;
 83
 84typedef void *GDataServiceUploadProgressHandler;
 85#endif // NS_BLOCKS_AVAILABLE
 86
 87@class GDataServiceBase;
 88
 89//
 90// ticket base class
 91//
 92@interface GDataServiceTicketBase : NSObject {
 93 @protected
 94  GDataServiceBase *service_;
 95
 96  id userData_;
 97  NSMutableDictionary *ticketProperties_;
 98  NSDictionary *surrogates_;
 99
100  GTMHTTPFetcher *currentFetcher_; // object or auth fetcher if mid-fetch
101  GTMHTTPFetcher *objectFetcher_;
102  SEL uploadProgressSelector_;
103  BOOL shouldFollowNextLinks_;
104  BOOL shouldFeedsIgnoreUnknowns_;
105  BOOL isRetryEnabled_;
106  SEL retrySEL_;
107  NSTimeInterval maxRetryInterval_;
108
109#if NS_BLOCKS_AVAILABLE
110  GDataServiceUploadProgressHandler uploadProgressBlock_;
111#elif !__LP64__
112  // placeholders: for 32-bit builds, keep the size of the object's ivar section
113  // the same with and without blocks
114  id uploadProgressPlaceholder_;
115#endif
116
117  GDataObject *postedObject_;
118  GDataObject *fetchedObject_;
119  GDataFeedBase *accumulatedFeed_;
120  NSError *fetchError_;
121  BOOL hasCalledCallback_;
122  NSUInteger nextLinksFollowedCounter_;
123
124  NSOperation *parseOperation_;
125
126  // OAuth support
127  id authorizer_;
128}
129
130+ (id)ticketForService:(GDataServiceBase *)service;
131
132- (id)initWithService:(GDataServiceBase *)service;
133
134// if cancelTicket is called, the fetch is stopped if it is in progress,
135// the callbacks will not be called, and the ticket will no longer be useful
136// (though the client must still release the ticket if it retained the ticket)
137- (void)cancelTicket;
138
139// chunked upload tickets may be paused
140- (void)pauseUpload;
141- (void)resumeUpload;
142- (BOOL)isUploadPaused;
143
144- (id)service;
145
146- (id)userData;
147- (void)setUserData:(id)obj;
148
149// Properties are supported for client convenience.
150//
151// Property keys beginning with _ are reserved by the library.
152- (void)setProperties:(NSDictionary *)dict;
153- (NSDictionary *)properties;
154
155- (void)setProperty:(id)obj forKey:(NSString *)key; // pass nil obj to remove property
156- (id)propertyForKey:(NSString *)key;
157
158- (NSDictionary *)surrogates;
159- (void)setSurrogates:(NSDictionary *)dict;
160
161- (GTMHTTPFetcher *)currentFetcher; // object or auth fetcher, if active
162- (void)setCurrentFetcher:(GTMHTTPFetcher *)fetcher;
163
164- (GTMHTTPFetcher *)objectFetcher;
165- (void)setObjectFetcher:(GTMHTTPFetcher *)fetcher;
166
167- (void)setUploadProgressSelector:(SEL)progressSelector;
168- (SEL)uploadProgressSelector;
169
170#if NS_BLOCKS_AVAILABLE
171- (void)setUploadProgressHandler:(void (^) (GDataServiceTicketBase *ticket, unsigned long long numberOfBytesRead, unsigned long long dataLength))handler;
172- (GDataServiceUploadProgressHandler)uploadProgressHandler;
173#endif
174
175- (BOOL)shouldFollowNextLinks;
176- (void)setShouldFollowNextLinks:(BOOL)flag;
177
178- (BOOL)shouldFeedsIgnoreUnknowns;
179- (void)setShouldFeedsIgnoreUnknowns:(BOOL)flag;
180
181- (BOOL)isRetryEnabled;
182- (void)setIsRetryEnabled:(BOOL)flag;
183
184- (SEL)retrySelector;
185- (void)setRetrySelector:(SEL)theSel;
186
187- (NSTimeInterval)maxRetryInterval;
188- (void)setMaxRetryInterval:(NSTimeInterval)secs;
189
190- (BOOL)hasCalledCallback;
191- (void)setHasCalledCallback:(BOOL)flag;
192
193- (void)setPostedObject:(GDataObject *)obj;
194- (id)postedObject;
195
196- (void)setFetchedObject:(GDataObject *)obj;
197- (GDataObject *)fetchedObject;
198
199- (void)setFetchError:(NSError *)error;
200- (NSError *)fetchError;
201
202- (void)setAccumulatedFeed:(GDataFeedBase *)feed;
203- (GDataFeedBase *)accumulatedFeed;
204
205// accumulateFeed is used by the service to append an incomplete feed
206// to the ticket when shouldFollowNextLinks is enabled
207- (void)accumulateFeed:(GDataFeedBase *)newFeed;
208
209- (void)setNextLinksFollowedCounter:(NSUInteger)val;
210- (NSUInteger)nextLinksFollowedCounter;
211
212- (NSInteger)statusCode;  // server status from object fetch
213
214- (NSOperation *)parseOperation;
215- (void)setParseOperation:(NSOperation *)op;
216
217// OAuth support
218- (id)authorizer;
219- (void)setAuthorizer:(id)obj;
220
221@end
222
223
224// category to provide opaque access to tickets stored in fetcher properties
225@interface GTMHTTPFetcher (GDataServiceTicketAdditions)
226- (id)ticket;
227@end
228
229
230//
231// service base class
232//
233
234@interface GDataServiceBase : NSObject {
235  NSOperationQueue *operationQueue_;
236
237  NSString *serviceVersion_;
238  NSString *userAgent_;
239  GTMHTTPFetcherService *fetcherService_;
240
241  NSString *username_;
242  NSMutableData *password_;
243
244  NSString *serviceUserData_; // initial value for userData in future tickets
245  NSMutableDictionary *serviceProperties_; // initial values for properties in future tickets
246
247  NSDictionary *serviceSurrogates_; // initial value for surrogates in future tickets
248
249  BOOL shouldServiceFeedsIgnoreUnknowns_; // YES when feeds should ignore unknown XML
250
251  SEL serviceUploadProgressSelector_; // optional
252
253#if NS_BLOCKS_AVAILABLE
254  GDataServiceUploadProgressHandler serviceUploadProgressBlock_;
255#elif !__LP64__
256  // placeholders: for 32-bit builds, keep the size of the object's ivar section
257  // the same with and without blocks
258  id serviceUploadProgressPlaceholder_;
259#endif
260
261  NSUInteger uploadChunkSize_;      // zero when uploading via multi-part MIME http body
262
263  BOOL isServiceRetryEnabled_;      // user allows auto-retries
264  SEL serviceRetrySEL_;             // optional; set with setServiceRetrySelector
265  NSTimeInterval serviceMaxRetryInterval_; // default to 600. seconds
266
267  NSInteger cookieStorageMethod_;   // constant from GTMHTTPFetcher.h
268  BOOL serviceShouldFollowNextLinks_;
269}
270
271// Applications should call setUserAgent: with a string of the form
272// CompanyName-AppName-AppVersion (without whitespace or punctuation
273// other than dashes and periods)
274- (NSString *)userAgent;
275- (void)setUserAgent:(NSString *)userAgent;
276
277// Run loop modes are used for scheduling NSURLConnections on 10.5 and later.
278//
279// The default value, nil, schedules connections using the current run
280// loop mode.  To use the service during a modal dialog, specify
281// an array with NSRunLoopCommonModes.
282//
283// These methods just call through to the fetcher service object's
284// runLoopModes property.
285- (NSArray *)runLoopModes;
286- (void)setRunLoopModes:(NSArray *)modes;
287
288// On iOS 4 and later, the fetch may optionally continue in the background
289// until finished or stopped by OS expiration
290//
291// The default value is NO
292//
293// For Mac OS X, background fetches are always supported, and this property
294// is ignored
295- (BOOL)shouldFetchInBackground;
296- (void)setShouldFetchInBackground:(BOOL)flag;
297
298// The request user agent includes the library and OS version appended to the
299// base userAgent
300- (NSString *)requestUserAgent;
301
302// Users may call requestForURL:httpMethod to get a request with the proper
303// user-agent and authentication token
304//
305// For http method, pass nil (for default GET method), POST, PUT, or DELETE
306- (NSMutableURLRequest *)requestForURL:(NSURL *)url
307                                  ETag:(NSString *)etag
308                            httpMethod:(NSString *)httpMethod;
309
310- (NSMutableURLRequest *)requestForURL:(NSURL *)url
311                                  ETag:(NSString *)etag
312                            httpMethod:(NSString *)httpMethod
313                                ticket:(GDataServiceTicketBase *)ticket;
314
315// objectRequestForURL returns an NSMutableURLRequest for an XML GData object
316//
317//
318// the object is the object being sent to the server, or nil;
319// the http method may be nil for get, or POST, PUT, DELETE
320- (NSMutableURLRequest *)objectRequestForURL:(NSURL *)url
321                                      object:(GDataObject *)object
322                                        ETag:(NSString *)etag
323                                  httpMethod:(NSString *)httpMethod
324                                      ticket:(GDataServiceTicketBase *)ticket;
325
326//
327// Fetch methods
328//
329//  fetchPublicFeed/fetchPublicEntry/fetchPublicFeedWithQuery (GET)
330//  fetchPublicEntryByInsertingEntry (POST)
331//  fetchPublicEntryByUpdatingEntry (PUT)
332//  deleteEntry/deleteResourceURL (DELETE)
333//
334//   NOTE:
335// These base class methods are for unauthenticated fetches to public feeds.
336//
337// To make authenticated fetches to a user's account, use the methods in the
338// service's GDataServiceXxxx class, or in the GDataServiceGoogle class.
339//
340
341// finishedSelector has a signature like:
342//
343//   - (void)serviceTicket:(GDataServiceTicketBase *)ticket
344//      finishedWithObject:(GDataObject *)object          // a feed or an entry
345//                   error:(NSError *)error
346//
347// If an error occurred, the error parameter will be non-nil.  Otherwise,
348// the object parameter will point to a feed or entry, if any was returned by
349// the fetch.  (Delete fetches return no object, so the second parameter will
350// be nil.)
351
352- (GDataServiceTicketBase *)fetchPublicFeedWithURL:(NSURL *)feedURL
353                                         feedClass:(Class)feedClass
354                                          delegate:(id)delegate
355                                 didFinishSelector:(SEL)finishedSelector;
356
357- (GDataServiceTicketBase *)fetchPublicFeedWithQuery:(GDataQuery *)query
358                                           feedClass:(Class)feedClass
359                                            delegate:(id)delegate
360                                   didFinishSelector:(SEL)finishedSelector;
361
362- (GDataServiceTicketBase *)fetchPublicEntryWithURL:(NSURL *)entryURL
363                                         entryClass:(Class)entryClass
364                                           delegate:(id)delegate
365                                  didFinishSelector:(SEL)finishedSelector;
366
367- (GDataServiceTicketBase *)fetchPublicFeedWithBatchFeed:(GDataFeedBase *)batchFeed
368                                              forFeedURL:(NSURL *)feedURL
369                                                delegate:(id)delegate
370                                       didFinishSelector:(SEL)finishedSelector;
371
372#if NS_BLOCKS_AVAILABLE
373- (GDataServiceTicketBase *)fetchPublicFeedWithURL:(NSURL *)feedURL
374                                         feedClass:(Class)feedClass
375                                 completionHandler:(void (^)(GDataServiceTicketBase *ticket, GDataFeedBase *feed, NSError *error))handler;
376
377- (GDataServiceTicketBase *)fetchPublicFeedWithQuery:(GDataQuery *)query
378                                           feedClass:(Class)feedClass
379                                   completionHandler:(void (^)(GDataServiceTicketBase *ticket, GDataFeedBase *feed, NSError *error))handler;
380
381- (GDataServiceTicketBase *)fetchPublicEntryWithURL:(NSURL *)entryURL
382                                         entryClass:(Class)entryClass
383                                  completionHandler:(void (^)(GDataServiceTicketBase *ticket, GDataEntryBase *entry, NSError *error))handler;
384
385- (GDataServiceTicketBase *)fetchPublicFeedWithBatchFeed:(GDataFeedBase *)batchFeed
386                                              forFeedURL:(NSURL *)feedURL
387                                       completionHandler:(void (^)(GDataServiceTicketBase *ticket, GDataFeedBase *feed, NSError *error))handler;
388#endif
389
390// reset the response cache to avoid getting a Not Modified status
391// based on prior queries
392- (void)clearResponseDataCache;
393
394// Turn on data caching to receive a copy of previously-retrieved objects.
395// Otherwise, fetches may return status 304 (Not Modifier) rather than actual
396// data
397- (void)setShouldCacheResponseData:(BOOL)flag;
398- (BOOL)shouldCacheResponseData;
399
400// If dated data caching is on, this specifies the capacity of the cache.
401// Default is 15MB for Mac and 1 MB for iPhone.
402- (void)setResponseDataCacheCapacity:(NSUInteger)totalBytes;
403- (NSUInteger)responseDataCacheCapacity;
404
405// Fetcher service, if necessary for sharing cookies and dated data
406// cache with standalone http fetchers
407- (void)setFetcherService:(GTMHTTPFetcherService *)obj;
408- (GTMHTTPFetcherService *)fetcherService;
409
410// Default storage for cookies is in the service object's fetchHistory.
411//
412// Apps that want to share cookies between all standalone fetchers and the
413// service object may specify static application-wide cookie storage,
414// kGTMHTTPFetcherCookieStorageMethodStatic.
415- (void)setCookieStorageMethod:(NSInteger)method;
416- (NSInteger)cookieStorageMethod;
417
418// For feed requests, where the feed requires following "next" links to retrieve
419// all entries, the service can optionally do the additional fetches using the
420// original ticket, calling the client's finish selector only when a complete
421// feed has been obtained.  During the fetch, the feed accumulated so far is
422// available from the ticket.
423//
424// Note that the final feed may be a combination of multiple partial feeds,
425// so is not exactly a genuine feed. In particular, it will not have a valid
426// "self" link, as it does not represent an object with a distinct URL.
427//
428// Default value is NO.
429- (BOOL)serviceShouldFollowNextLinks;
430- (void)setServiceShouldFollowNextLinks:(BOOL)flag;
431
432// set a non-zero value to enable uploading via chunked fetches
433// (resumable uploads); typically this defaults to kGDataStandardUploadChunkSize
434// for service subclasses that support chunked uploads
435- (NSUInteger)serviceUploadChunkSize;
436- (void)setServiceUploadChunkSize:(NSUInteger)val;
437
438// service subclasses may specify their own default chunk size
439+ (NSUInteger)defaultServiceUploadChunkSize;
440
441// The service userData becomes the initial value for each future ticket's
442// userData.
443//
444// Since the network transactions may begin before the client has been
445// returned the ticket by the fetch call, it's preferable to call
446// setServiceUserData before the ticket is created rather than call the
447// ticket's setUserData:.  Either way, the ticket's userData:
448// method will return the value.
449- (void)setServiceUserData:(id)userData;
450- (id)serviceUserData;
451
452// Properties are supported for client convenience.
453//
454// Property keys beginning with _ are reserved by the library.
455//
456// The service properties dictionary is copied to become the initial property
457// dictionary for each ticket.
458- (void)setServiceProperties:(NSDictionary *)dict;
459- (NSDictionary *)serviceProperties;
460
461- (void)setServiceProperty:(id)obj forKey:(NSString *)key; // pass nil obj to remove property
462- (id)servicePropertyForKey:(NSString *)key;
463
464
465// Set the surrogates to be used for future tickets.  Surrogates are subclasses
466// to be used instead of standard classes when creating objects from the XML.
467// For example, this code will make the framework generate objects
468// using MyCalendarEntrySubclass instead of GDataEntryCalendar and
469// MyCalendarEventSubclass instead of GDataEntryCalendarEvent.
470//
471//  NSDictionary *surrogates = [NSDictionary dictionaryWithObjectsAndKeys:
472//    [MyCalendarEntrySubclass class], [GDataEntryCalendar class],
473//    [MyCalendarEventSubclass class], [GDataEntryCalendarEvent class],
474//    nil];
475//  [calendarService setServiceSurrogates:surrogates];
476//
477- (NSDictionary *)serviceSurrogates;
478- (void)setServiceSurrogates:(NSDictionary *)dict;
479
480// Set if feeds fetched (and the entries and elements contained in the feeds)
481// keep track of unparsed XML elements.  Setting this to YES offers a
482// performance and memory improvement, particularly for iPhone apps.  However,
483// the entries in those feeds cannot be updated (as the unparsed XML inside the
484// entries has been lost, so cannot be sent back to the server.)  An entry
485// can be re-fetched singly for updating.  Default is NO.  iPhone
486// apps retrieving large feeds should probably set this to YES.
487//
488- (BOOL)shouldServiceFeedsIgnoreUnknowns;
489- (void)setShouldServiceFeedsIgnoreUnknowns:(BOOL)flag;
490
491// The service uploadProgressSelector becomes the initial value for each future
492// ticket's uploadProgressSelector.
493//
494// The optional uploadProgressSelector will be called in the delegate as bytes
495// are uploaded to the server.  It should have a signature matching
496//
497// - (void)ticket:(GDataServiceTicketBase *)ticket
498//   hasDeliveredByteCount:(unsigned long long)numberOfBytesRead
499//        ofTotalByteCount:(unsigned long long)dataLength;
500- (void)setServiceUploadProgressSelector:(SEL)progressSelector;
501- (SEL)serviceUploadProgressSelector;
502
503#if NS_BLOCKS_AVAILABLE
504- (void)setServiceUploadProgressHandler:(void (^) (GDataServiceTicketBase *ticket, unsigned long long numberOfBytesRead, unsigned long long dataLength))handler;
505- (GDataServiceUploadProgressHandler)serviceUploadProgressHandler;
506#endif
507
508
509// retrying; see comments on retry support at the top of GTMHTTPFetcher.
510- (BOOL)isServiceRetryEnabled;
511- (void)setIsServiceRetryEnabled:(BOOL)flag;
512
513// retry selector is optional for retries.
514//
515// If present, it should have the signature:
516//   -(BOOL)ticket:(GDataServiceTicketBase *)ticket willRetry:(BOOL)suggestedWillRetry forError:(NSError *)error
517// and return YES to cause a retry.  Note that unlike the GTMHTTPFetcher retry
518// selector, this selector's first argument is a ticket, not a fetcher.
519// The current fetcher can be retrived with [ticket currentFetcher]
520
521- (SEL)serviceRetrySelector;
522- (void)setServiceRetrySelector:(SEL)theSel;
523
524- (NSTimeInterval)serviceMaxRetryInterval;
525- (void)setServiceMaxRetryInterval:(NSTimeInterval)secs;
526
527// access to the parsing operation queue, for clients wanting to manage the
528// queue explicitly
529- (id)operationQueue;
530- (void)setOperationQueue:(id)queue;
531
532// credentials
533- (void)setUserCredentialsWithUsername:(NSString *)username
534                              password:(NSString *)password;
535- (NSString *)username;
536- (NSString *)password;
537
538// OAuth support
539- (id)authorizer;
540- (void)setAuthorizer:(id)obj;
541
542// Subclasses typically override defaultServiceVersion to specify the expected
543// version of the feed, but clients may also explicitly set the version
544// if they are using an instance of the base class directly.
545+ (NSString *)defaultServiceVersion;
546
547- (NSString *)serviceVersion;
548- (void)setServiceVersion:(NSString *)str;
549
550// Wait synchronously for fetch to complete (strongly discouraged)
551//
552// This just runs the current event loop until the fetch completes
553// or the timout limit is reached.  This may discard unexpected events
554// that occur while spinning, so it's really not appropriate for use
555// in serious applications.
556//
557// Returns true if an object was successfully fetched.  If the wait
558// timed out, returns false and the returned error is nil.
559//
560// The returned object or error, if any, will be already autoreleased
561//
562// This routine will likely be removed in some future releases of the library.
563- (BOOL)waitForTicket:(GDataServiceTicketBase *)ticket
564              timeout:(NSTimeInterval)timeoutInSeconds
565        fetchedObject:(GDataObject **)outObjectOrNil
566                error:(NSError **)outErrorOrNil;
567
568//
569// internal utilities
570//
571
572- (void)addAuthenticationToFetcher:(GTMHTTPFetcher *)fetcher;
573
574- (void)objectFetcher:(GTMHTTPFetcher *)fetcher finishedWithData:(NSData *)data error:(NSError *)error;
575
576+ (NSString *)defaultApplicationIdentifier;
577
578+ (NSString *)systemVersionString;
579
580- (BOOL)invokeRetrySelector:(SEL)retrySelector delegate:(id)delegate ticket:(GDataServiceTicketBase *)ticket willRetry:(BOOL)willRetry error:(NSError *)error;
581
582+ (void)invokeCallback:(SEL)callbackSel target:(id)target ticket:(id)ticket object:(id)object error:(id)error;
583
584@end