GTLRService.h 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889
  1. /* Copyright (c) 2016 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. // Service object documentation:
  16. // https://github.com/google/google-api-objectivec-client-for-rest/blob/main/USING.md#services-and-tickets
  17. #import <Foundation/Foundation.h>
  18. #import "GTLRBatchQuery.h"
  19. #import "GTLRBatchResult.h"
  20. #import "GTLRDateTime.h"
  21. #import "GTLRDuration.h"
  22. #import "GTLRErrorObject.h"
  23. #import "GTLRObject.h"
  24. #import "GTLRQuery.h"
  25. // TODO: Simplify when the 2.0 SessionFetcher is the min dependency.
  26. #if __has_include(<GTMSessionFetcher/GTMSessionFetcher.h>) // 2.x & CocoaPods
  27. #import <GTMSessionFetcher/GTMSessionFetcher.h>
  28. #import <GTMSessionFetcher/GTMSessionFetcherService.h>
  29. #else // SwiftPM 1.x
  30. // #import "../GTMSessionFetcher.h"
  31. // #import "../GTMSessionFetcherService.h"
  32. #import "GTMSessionFetcher.h"
  33. #import "GTMSessionFetcherService.h"
  34. #endif
  35. NS_ASSUME_NONNULL_BEGIN
  36. /**
  37. * The domain used used for NSErrors created by GTLRService query execution.
  38. */
  39. FOUNDATION_EXTERN NSString *const kGTLRServiceErrorDomain;
  40. typedef NS_ENUM(NSInteger, GTLRServiceError) {
  41. GTLRServiceErrorQueryResultMissing = -3000,
  42. GTLRServiceErrorBatchResponseUnexpected = -3001,
  43. GTLRServiceErrorBatchResponseStatusCode = -3002
  44. };
  45. /**
  46. * The kGTLRServiceErrorDomain userInfo key for the server response body.
  47. */
  48. FOUNDATION_EXTERN NSString *const kGTLRServiceErrorBodyDataKey;
  49. /**
  50. * The kGTLRServiceErrorDomain userInfo key for the response content ID, if appropriate.
  51. */
  52. FOUNDATION_EXTERN NSString *const kGTLRServiceErrorContentIDKey;
  53. /**
  54. * The domain used for foundation errors created from GTLRErrorObjects that
  55. * were not originally foundation errors.
  56. */
  57. FOUNDATION_EXTERN NSString *const kGTLRErrorObjectDomain;
  58. /**
  59. * The userInfo key for a GTLRErrorObject for errors with domain kGTLRErrorObjectDomain
  60. * when the error was created from a structured JSON error response body.
  61. */
  62. FOUNDATION_EXTERN NSString *const kGTLRStructuredErrorKey;
  63. /**
  64. * A constant ETag for when updating or deleting a single entry, telling
  65. * the server to replace the current value unconditionally.
  66. *
  67. * Do not use this in entries in a batch feed.
  68. */
  69. FOUNDATION_EXTERN NSString *const kGTLRETagWildcard;
  70. /**
  71. * Notification of a ticket starting. The notification object is the ticket.
  72. * This is posted on the main thread.
  73. *
  74. * Use the stopped notification to log all requests made by the library.
  75. */
  76. FOUNDATION_EXTERN NSString *const kGTLRServiceTicketStartedNotification;
  77. /**
  78. * Notification of a ticket stopping. The notification object is the ticket.
  79. * This is posted on the main thread.
  80. */
  81. FOUNDATION_EXTERN NSString *const kGTLRServiceTicketStoppedNotification;
  82. /**
  83. * Notifications when parsing of a server response or entry begins.
  84. * This is posted on the main thread.
  85. */
  86. FOUNDATION_EXTERN NSString *const kGTLRServiceTicketParsingStartedNotification;
  87. /**
  88. * Notifications when parsing of a server response or entry ends.
  89. * This is posted on the main thread.
  90. */
  91. FOUNDATION_EXTERN NSString *const kGTLRServiceTicketParsingStoppedNotification;
  92. /**
  93. * The header name used to send an Application's Bundle Identifier.
  94. * For more information on adding API restrictions see the docs:
  95. * https://cloud.google.com/docs/authentication/api-keys#api_key_restrictions
  96. */
  97. FOUNDATION_EXTERN NSString *const kXIosBundleIdHeader;
  98. /**
  99. * Callback block for query execution.
  100. *
  101. * @param callbackTicket The ticket that tracked query execution.
  102. * @param object The result of query execution. This will be derived from
  103. * GTLRObject. The object may be nil for operations such as DELETE which
  104. * do not return an object. The object will be a GTLRBatchResult for
  105. * batch operations, and GTLRDataObject for media downloads.
  106. * @param callbackError If non-nil, the query execution failed. For batch requests,
  107. * this may be nil even if individual queries in the batch have failed.
  108. */
  109. typedef void (^GTLRServiceCompletionHandler)(GTLRServiceTicket *callbackTicket,
  110. id _Nullable object,
  111. NSError * _Nullable callbackError);
  112. /**
  113. * Callback block for upload of query data.
  114. *
  115. * @param progressTicket The ticket that tracks query execution.
  116. * @param totalBytesUploaded Number of bytes uploaded so far.
  117. * @param totalBytesExpectedToUpload Number of bytes expected to be uploaded.
  118. */
  119. typedef void (^GTLRServiceUploadProgressBlock)(GTLRServiceTicket *progressTicket,
  120. unsigned long long totalBytesUploaded,
  121. unsigned long long totalBytesExpectedToUpload);
  122. /**
  123. * Callback block invoked when an eror occurs during query execution.
  124. *
  125. * @param retryTicket The ticket that tracks query execution.
  126. * @param suggestedWillRetry Flag indicating if the library would retry this without a retry block.
  127. * @param fetchError The error that occurred. If the domain is
  128. * kGTMSessionFetcherStatusDomain then the error's code is the server
  129. * response status. Details on the error from the server are available
  130. * in the userInfo via the keys kGTLRStructuredErrorKey and
  131. * NSLocalizedDescriptionKey.
  132. *
  133. * @return YES if the request should be retried.
  134. */
  135. typedef BOOL (^GTLRServiceRetryBlock)(GTLRServiceTicket *retryTicket,
  136. BOOL suggestedWillRetry,
  137. NSError * _Nullable fetchError);
  138. /**
  139. * Block to be invoked by a test block.
  140. *
  141. * @param object The faked object, if any, to be passed to the test code's completion handler.
  142. * @param error The faked error if any, to be passed to the test code's completion handler.
  143. */
  144. typedef void (^GTLRServiceTestResponse)(id _Nullable object, NSError *_Nullable error);
  145. /**
  146. * A test block enables testing of query execution without any network activity.
  147. *
  148. * The test block must finish by calling the response block, passing either an object
  149. * (GTLRObject or GTLRBatchResult) or an NSError.
  150. *
  151. * The query is available to the test block code as testTicket.originalQuery.
  152. *
  153. * Because query execution is asynchronous, the test code must wait for a callback,
  154. * either with GTLRService's waitForTicket:timeout:fetchedObject:error: or with
  155. * XCTestCase's waitForExpectationsWithTimeout:
  156. *
  157. * Example usage is available in GTLRServiceTest.
  158. *
  159. * @param testTicket The ticket that tracks query execution.
  160. * @param testResponse A block that must be invoked by the test block. This may be invoked
  161. * synchronously or asynchornously.
  162. */
  163. typedef void (^GTLRServiceTestBlock)(GTLRServiceTicket *testTicket,
  164. GTLRServiceTestResponse testResponse);
  165. #pragma mark -
  166. /**
  167. * Base class for the service that executes queries and manages tickets.
  168. *
  169. * Client apps will typically use a generated subclass of GTLRService.
  170. */
  171. @interface GTLRService : NSObject
  172. #pragma mark Query Execution
  173. /**
  174. * Executes the supplied query
  175. *
  176. * Success is indicated in the completion handler by a nil error parameter, not by a non-nil
  177. * object parameter.
  178. *
  179. * The callback block is invoked exactly once unless the ticket is cancelled.
  180. * The callback will be called on the service's callback queue.
  181. *
  182. * Various execution parameters will be taken from the service's properties, unless overridden
  183. * in the query's @c executionParameters property.
  184. *
  185. * A query may only be executed a single time. To reuse a query, make a copy before executing
  186. * it.
  187. *
  188. * To get a NSURLRequest that represents the query, use @c -[GTLRService requestForQuery:]
  189. *
  190. * @param query The API query, either a subclass of GTLRQuery, or a GTLRBatchQuery.
  191. * @param handler The execution callback block.
  192. *
  193. * @return A ticket for tracking or canceling query execution.
  194. */
  195. - (GTLRServiceTicket *)executeQuery:(id<GTLRQueryProtocol>)query
  196. completionHandler:(nullable GTLRServiceCompletionHandler)handler;
  197. /**
  198. * Executes the supplied query
  199. *
  200. * The callback is invoked exactly once unless the ticket is cancelled.
  201. * The callback will be called on the service's callbackQueue.
  202. * Various execution parameters will be taken from the service's properties, unless overridden
  203. * in the query's @c executionParameters property.
  204. *
  205. * The selector should have a signature matching:
  206. * @code
  207. * - (void)serviceTicket:(GTLRServiceTicket *)callbackTicket
  208. * finishedWithObject:(GTLRObject *)object
  209. * error:(NSError *)callbackError
  210. * @endcode
  211. *
  212. * @param query The API query, either a subclass of GTLRQuery, or a GTLRBatchQuery.
  213. * @param delegate The object to be with the selector to be invoked upon completion.
  214. * @param finishedSelector The selector to be invoked upon completion.
  215. *
  216. * @return A ticket for tracking or canceling query execution.
  217. */
  218. - (GTLRServiceTicket *)executeQuery:(id<GTLRQueryProtocol>)query
  219. delegate:(nullable id)delegate
  220. didFinishSelector:(nullable SEL)finishedSelector;
  221. /**
  222. * Enable automatic pagination.
  223. *
  224. * A ticket can optionally do a sequence of fetches for queries where repeated requests
  225. * with a @c nextPageToken query parameter is required to retrieve all pages of
  226. * the response collection. The client's callback is invoked only when all items have
  227. * been retrieved, or an error has occurred.
  228. *
  229. * The final object may be a combination of multiple page responses
  230. * so it may not be the same as if all results had been returned in a single
  231. * page. Some fields of the response may reflect only the final page's values.
  232. *
  233. * Automatic page fetches will return an error if more than 25 page fetches are
  234. * required. For debug builds, this will log a warning to the console when more
  235. * than 2 page fetches occur, as a reminder that the query's @c maxResults parameter
  236. * should probably be increased to specify more items returned per page.
  237. *
  238. * Automatic page accumulation is available for query result objects that are derived
  239. * from GTLRCollectionObject.
  240. *
  241. * This may also be specified for a single query in the query's @c executionParameters property.
  242. *
  243. * Default value is NO.
  244. */
  245. @property(nonatomic, assign) BOOL shouldFetchNextPages;
  246. /**
  247. * Some services require a developer key for quotas and limits.
  248. *
  249. * If you have enabled the iOS API Key Restriction, you will want
  250. * to manually set the @c APIKeyRestrictionBundleID property, or
  251. * use -setMainBundleIDRestrictionWithAPIKey: to set your API key
  252. * and set the restriction to the main bundle's bundle id.
  253. */
  254. @property(nonatomic, copy, nullable) NSString *APIKey;
  255. /**
  256. * The Bundle Identifier to use for the API key restriction. This will be
  257. * sent in an X-Ios-Bundle-Identifier header; for more information see
  258. * the API key documentation
  259. * https://cloud.google.com/docs/authentication/api-keys#api_key_restrictions
  260. */
  261. @property(nonatomic, copy, nullable) NSString *APIKeyRestrictionBundleID;
  262. /**
  263. * Helper method to set the @c APIKey to the given value and set the
  264. * @c APIKeyRestrictionBundleID to the main bundle's bundle identifier.
  265. */
  266. - (void)setMainBundleIDRestrictionWithAPIKey:(NSString *)apiKey;
  267. // Avoid the warnings for GTMFetcherAuthorizationProtocol in newer
  268. // GTMSessionFetcher headers. Updating requires a new minimum, and
  269. // holding of on raising it that current for the moment.
  270. #pragma clang diagnostic push
  271. #pragma clang diagnostic ignored "-Wdeprecated"
  272. /**
  273. * An authorizer adds user authentication headers to the request as needed.
  274. *
  275. * This may be overridden on individual queries with the @c shouldSkipAuthorization property.
  276. */
  277. @property(nonatomic, retain, nullable) id <GTMFetcherAuthorizationProtocol> authorizer;
  278. #pragma clang diagnostic pop
  279. /**
  280. * Enable fetcher retry support. See the explanation of retry support in @c GTMSessionFetcher.h
  281. *
  282. * Default value is NO, but retry is also enabled if the retryBlock is not nil.
  283. *
  284. * This may also be specified for a single query in the query's @c executionParameters property.
  285. */
  286. @property(nonatomic, assign, getter=isRetryEnabled) BOOL retryEnabled;
  287. /**
  288. * A retry block may be provided to inspect and change retry criteria.
  289. *
  290. * This may also be specified for a single query in the query's @c executionParameters property.
  291. */
  292. @property(atomic, copy, nullable) GTLRServiceRetryBlock retryBlock;
  293. /**
  294. * The maximum retry interval. Retries occur at increasing intervals, up to the specified maximum.
  295. *
  296. * This may also be specified for a single query in the query's @c executionParameters property.
  297. */
  298. @property(nonatomic, assign) NSTimeInterval maxRetryInterval;
  299. #pragma mark Fetch Object by Resource URL
  300. /**
  301. * Fetch an object given the resource URL. This is appropriate when the object's
  302. * full link is known, such as from a selfLink response property.
  303. *
  304. * @param resourceURL The URL of the object to be fetched.
  305. * @param objectClass The GTLRObject subclass to be instantiated. If nil, the library
  306. * will try to infer the class from the object's "kind" string property.
  307. * @param executionParameters Values to override the service's properties when executing the
  308. * ticket.
  309. * @param handler The execution callback block.
  310. *
  311. * @return A ticket for tracking or canceling query execution.
  312. */
  313. - (GTLRServiceTicket *)fetchObjectWithURL:(NSURL *)resourceURL
  314. objectClass:(nullable Class)objectClass
  315. executionParameters:(nullable GTLRServiceExecutionParameters *)executionParameters
  316. completionHandler:(nullable GTLRServiceCompletionHandler)handler;
  317. #pragma mark Support for Client Tests
  318. /**
  319. * A test block can be provided to test service calls without any network activity.
  320. *
  321. * See the description of @c GTLRServiceTestBlock for additional details.
  322. *
  323. * This may also be specified for a single query in the query's @c executionParameters property.
  324. *
  325. * A service instance for testing can also be created with @c +mockServiceWithFakedObject
  326. */
  327. @property(nonatomic, copy, nullable) GTLRServiceTestBlock testBlock;
  328. #pragma mark Converting a Query to an NSURLRequest
  329. /**
  330. * Creates a NSURLRequest from the query object and from properties on this service
  331. * (additionalHTTPHeaders, additionalURLQueryParameters, APIKey) without executing
  332. * it. This can be useful for using @c GTMSessionFetcher or @c NSURLSession to
  333. * perform the fetch.
  334. *
  335. * For requests to non-public resources, the request will not yet be authorized;
  336. * that can be done using the GTLR service's authorizer. Creating a @c GTMSessionFetcher
  337. * from the GTLRService's @c fetcherService will take care of authorization as well.
  338. *
  339. * This works only for GET queries, and only for an individual query, not a batch query.
  340. *
  341. * @note @c Unlike executeQuery:, requestForQuery: does not release the query's callback blocks.
  342. *
  343. * @param query The query used to create the request.
  344. *
  345. * @return A request suitable for use with @c GTMSessionFetcher or @c NSURLSession
  346. */
  347. - (NSMutableURLRequest *)requestForQuery:(GTLRQuery *)query;
  348. #pragma mark User Properties
  349. /**
  350. * The service properties dictionary is copied to become the initial property dictionary
  351. * for each ticket, augmented by a query's execution parameter's properties.
  352. */
  353. @property(nonatomic, copy, nullable) NSDictionary<NSString *, id> *serviceProperties;
  354. #pragma mark JSON to GTLRObject Mapping
  355. /**
  356. * Specifies subclasses to be created instead of standard library objects, allowing
  357. * an app to add properties and methods to GTLR objects.
  358. *
  359. * This is just a helper method that sets the service's objectClassResolver:.
  360. *
  361. * Example:
  362. * @code
  363. * NSDictionary *surrogates = @{
  364. * [MyDriveFile class] : [GTLRDrive_File_Surrogate class],
  365. * [MyDriveFileList class] : [GTLRDrive_FileList_Surrogate class]
  366. * };
  367. * [service setSurrogates:surrogates];
  368. * @endcode
  369. */
  370. - (void)setSurrogates:(NSDictionary <Class, Class>*)surrogates;
  371. /**
  372. * Used to decide what GTLRObject subclass to make from the received JSON.
  373. *
  374. * This defaults to a resolver that will use any kindStringToClassMap the service
  375. * provides.
  376. *
  377. * To use a standard resolver with a surrogates dictionary, invoke setSurrogates: instead
  378. * of setting this property.
  379. */
  380. @property(nonatomic, strong) id<GTLRObjectClassResolver> objectClassResolver;
  381. /**
  382. * A dictionary mapping "kind" strings to the GTLObject subclasses that should
  383. * be created for JSON with the given kind.
  384. */
  385. + (NSDictionary<NSString *, Class> *)kindStringToClassMap;
  386. #pragma mark Request Settings
  387. /**
  388. * The queue used to invoked callbacks. By default, the main queue is used for callbacks.
  389. */
  390. @property(nonatomic, retain) dispatch_queue_t callbackQueue;
  391. /**
  392. * Allows the application to make non-SSL and localhost requests for testing.
  393. *
  394. * Default value is NO.
  395. */
  396. @property(nonatomic, assign) BOOL allowInsecureQueries;
  397. /**
  398. * The fetcher service creates the fetcher instances for this API service.
  399. *
  400. * Applications may set this to an authorized fetcher service created elsewhere
  401. * in the app, or may take the fetcher service created by this GTLRService and use it
  402. * to create fetchers independent of this service.
  403. */
  404. @property(nonatomic, retain) GTMSessionFetcherService *fetcherService;
  405. #pragma mark Custom User Agents
  406. /**
  407. * Applications needing an additional identifier in the server logs may specify one
  408. * through this property and it will be added to the existing UserAgent. It should
  409. * already be a valid identifier as no cleaning/validation is done.
  410. */
  411. @property(nonatomic, copy, nullable) NSString *userAgentAddition;
  412. /**
  413. * A base user-agent based on the application signature in the Info.plist settings.
  414. *
  415. * Most applications should not explicitly set this property. Any string provided will
  416. * be cleaned of inappropriate characters.
  417. */
  418. @property(nonatomic, copy, nullable) NSString *userAgent;
  419. /**
  420. * The request user agent includes the library and OS version appended to the
  421. * base userAgent, along with the optional addition string.
  422. */
  423. @property(nonatomic, readonly, nullable) NSString *requestUserAgent;
  424. /**
  425. * A precise base userAgent string identifying the application. No cleaning of characters
  426. * is done. Library-specific details will be appended.
  427. *
  428. * @param userAgent A wire-ready user agent string.
  429. */
  430. - (void)setExactUserAgent:(nullable NSString *)userAgent;
  431. /**
  432. * A precise userAgent string to send on requests; no cleaning is done. When
  433. * set, requestUserAgent will be exactly this, no library or system information
  434. * will be auto added.
  435. *
  436. * @param requestUserAgent A wire-ready user agent string.
  437. */
  438. - (void)overrideRequestUserAgent:(nullable NSString *)requestUserAgent;
  439. /**
  440. * Any additional URL query parameters for the queries executed by this service.
  441. *
  442. * Individual queries may have additionalURLQueryParameters specified as well.
  443. */
  444. @property(atomic, copy, nullable) NSDictionary<NSString *, NSString *> *additionalURLQueryParameters;
  445. /**
  446. * Any additional HTTP headers for this queries executed by this service.
  447. *
  448. * Individual queries may have additionalHTTPHeaders specified as well.
  449. */
  450. @property(atomic, copy, nullable) NSDictionary<NSString *, NSString *> *additionalHTTPHeaders;
  451. #pragma mark Request URL Construction
  452. /*
  453. * The URL for where to send a Query is built out of these parts
  454. * ( https://developers.google.com/discovery/v1/using#build-compose ) :
  455. *
  456. * service.rootURLString + service.servicePath + query.pathURITemplate
  457. *
  458. * Note: odds are these both should end in a '/', so make sure any value you
  459. * provide will combine correctly with the above rules.
  460. */
  461. /**
  462. * The scheme and host for the API server. This may be modified to point at a test server.
  463. */
  464. @property(nonatomic, copy) NSString *rootURLString;
  465. /**
  466. * The path for the specific API service instance, relative to the rootURLString.
  467. */
  468. @property(nonatomic, copy) NSString *servicePath;
  469. /**
  470. * A path fragment added in to URLs before "servicePath" to build
  471. * the full URL used for resumable media uploads.
  472. */
  473. @property(nonatomic, copy) NSString *resumableUploadPath;
  474. /**
  475. * A path fragment added in to URLs before "servicePath" to build
  476. * the full URL used for simple and multipart media uploads.
  477. */
  478. @property(nonatomic, copy) NSString *simpleUploadPath;
  479. /**
  480. * A path fragment added in to URLs before "servicePath" to build
  481. * the full URL used for batch requests.
  482. */
  483. @property(nonatomic, copy) NSString *batchPath;
  484. #pragma mark Resumable Uploads
  485. /**
  486. * A block called to track upload progress.
  487. *
  488. * A query's service execution parameters may be used to override this.
  489. */
  490. @property(nonatomic, copy, nullable) GTLRServiceUploadProgressBlock uploadProgressBlock;
  491. /**
  492. * The default chunk size for resumable uploads. This defaults to kGTLRStandardUploadChunkSize
  493. * for service subclasses that support chunked uploads.
  494. */
  495. @property(nonatomic, assign) NSUInteger serviceUploadChunkSize;
  496. /**
  497. * Service subclasses may override this to specify their own default chunk size for
  498. * resumable uploads.
  499. */
  500. + (NSUInteger)defaultServiceUploadChunkSize;
  501. #pragma mark Internal
  502. /////////////////////////////////////////////////////////////////////////////////////////////
  503. //
  504. // Properties below are used by the library and should not typically be set by client apps.
  505. //
  506. /////////////////////////////////////////////////////////////////////////////////////////////
  507. /**
  508. * The queue used for parsing JSON responses.
  509. *
  510. * Applications should typically not change this.
  511. */
  512. @property(nonatomic, retain) dispatch_queue_t parseQueue;
  513. /**
  514. * If this service supports pretty printing the JSON on the wire, these are
  515. * the names of the query params that enable it. If there are any values,
  516. * the library disables pretty printing to save on bandwidth.
  517. *
  518. * Applications should typically not need change this; the ServiceGenerator
  519. * will set this up when generating the custom subclass.
  520. */
  521. @property(nonatomic, strong, nullable) NSArray<NSString *> *prettyPrintQueryParameterNames;
  522. /**
  523. * This indicates if the API requires a "data" JSON element to wrap the payload
  524. * on requests and responses.
  525. *
  526. * Applications should typically not change this.
  527. */
  528. @property(nonatomic, assign, getter=isDataWrapperRequired) BOOL dataWrapperRequired;
  529. @end
  530. @interface GTLRService (TestingSupport)
  531. /**
  532. * Convenience method to create a mock GTLR service just for testing.
  533. *
  534. * Queries executed by this mock service will not perform any network operation,
  535. * but will invoke callbacks and provide the supplied object or error to the
  536. * completion handler.
  537. *
  538. * You can make more customized mocks by setting the test block property of a service
  539. * or a query's execution parameters. The test block can inspect the query as ticket.originalQuery
  540. * to customize test behavior.
  541. *
  542. * See the description of @c GTLRServiceTestBlock for more details on customized testing.
  543. *
  544. * Example usage is in the unit test method @c testService_MockService_Succeeding
  545. *
  546. * @param object An object derived from GTLRObject to be passed to query completion handlers.
  547. * @param error An error to be passed to query completion handlers.
  548. *
  549. * @return A mock instance of the service, suitable for unit testing.
  550. */
  551. + (instancetype)mockServiceWithFakedObject:(nullable id)object
  552. fakedError:(nullable NSError *)error;
  553. /**
  554. * Wait synchronously for fetch to complete (strongly discouraged)
  555. *
  556. * This method is intended for use only in unit tests and command-line tools.
  557. * Unit tests may also use XCTest's waitForExpectationsWithTimeout: instead of
  558. * or after this method.
  559. *
  560. * This method just runs the current event loop until the fetch completes
  561. * or the timout limit is reached. This may discard unexpected events
  562. * that occur while spinning, so it's really not appropriate for use
  563. * in serious applications.
  564. *
  565. * Returns YES if an object was successfully fetched. If the wait
  566. * timed out, returns NO and the returned error is nil.
  567. *
  568. * @param ticket The ticket being executed.
  569. * @param timeoutInSeconds Maximum duration to wait.
  570. *
  571. * @return YES if the ticket completed or was cancelled; NO if the wait timed out.
  572. */
  573. - (BOOL)waitForTicket:(GTLRServiceTicket *)ticket
  574. timeout:(NSTimeInterval)timeoutInSeconds;
  575. @end
  576. #pragma mark -
  577. /**
  578. * Service execution parameters may be set on an individual query
  579. * to alter the service's settings.
  580. */
  581. @interface GTLRServiceExecutionParameters : NSObject<NSCopying>
  582. /**
  583. * Override the service's property @c shouldFetchNextPages for automatic pagination.
  584. *
  585. * A BOOL value should be specified.
  586. */
  587. @property(atomic, strong, nullable) NSNumber *shouldFetchNextPages;
  588. /**
  589. * Override the service's property @c shouldFetchNextPages for enabling automatic retries.
  590. *
  591. * A BOOL value should be specified.
  592. *
  593. * Retry is also enabled if the retryBlock is not nil
  594. */
  595. @property(atomic, strong, nullable, getter=isRetryEnabled) NSNumber *retryEnabled;
  596. /**
  597. * Override the service's property @c retryBlock for customizing automatic retries.
  598. */
  599. @property(atomic, copy, nullable) GTLRServiceRetryBlock retryBlock;
  600. /**
  601. * Override the service's property @c maxRetryInterval for customizing automatic retries.
  602. *
  603. * A NSTimeInterval (double) value should be specified.
  604. */
  605. @property(atomic, strong, nullable) NSNumber *maxRetryInterval;
  606. /**
  607. * Override the service's property @c uploadProgressBlock for monitoring upload progress.
  608. */
  609. @property(atomic, copy, nullable) GTLRServiceUploadProgressBlock uploadProgressBlock;
  610. /**
  611. * Override the service's property @c callbackQueue for invoking callbacks.
  612. */
  613. @property(atomic, retain, nullable) dispatch_queue_t callbackQueue;
  614. /**
  615. * Override the service's property @c testBlock for simulating query execution.
  616. *
  617. * See the description of @c GTLRServiceTestBlock for additional details.
  618. */
  619. @property(atomic, copy, nullable) GTLRServiceTestBlock testBlock;
  620. /**
  621. * Override the service's property @c objectClassResolver for controlling object class selection.
  622. */
  623. @property(atomic, strong, nullable) id<GTLRObjectClassResolver> objectClassResolver;
  624. /**
  625. * The ticket's properties are the service properties, with the execution parameter's
  626. * ticketProperties added (replacing any keys already present from the service.)
  627. */
  628. @property(atomic, copy, nullable) NSDictionary<NSString *, id> *ticketProperties;
  629. /**
  630. * Indicates if any of the execution parameters properties are set.
  631. */
  632. @property(nonatomic, readonly) BOOL hasParameters;
  633. @end
  634. /**
  635. * A ticket tracks the progress of a query being executed.
  636. */
  637. @interface GTLRServiceTicket : NSObject
  638. - (instancetype)init NS_UNAVAILABLE;
  639. /**
  640. * The service that issued this ticket.
  641. *
  642. * This method may be invoked from any thread.
  643. */
  644. @property(atomic, readonly) GTLRService *service;
  645. #pragma mark Execution Control
  646. /**
  647. * Invoking cancelTicket stops the fetch if it is in progress. The query callbacks
  648. * will not be invoked.
  649. *
  650. * This method may be invoked from any thread.
  651. */
  652. - (void)cancelTicket;
  653. /**
  654. * The time the ticket was created.
  655. */
  656. @property(atomic, readonly) NSDate *creationDate;
  657. /**
  658. * Pause the ticket execution. This is valid only for chunked, resumable upload queries.
  659. */
  660. - (void)pauseUpload;
  661. /**
  662. * Resume the ticket execution. This is valid only for chunked, resumable upload queries.
  663. */
  664. - (void)resumeUpload;
  665. /**
  666. * Checks if the ticket execution is paused.
  667. */
  668. @property(nonatomic, readonly, getter=isUploadPaused) BOOL uploadPaused;
  669. /**
  670. * The request being fetched for the query.
  671. */
  672. @property(nonatomic, readonly, nullable) NSURLRequest *fetchRequest;
  673. /**
  674. * The fetcher being used for the query request.
  675. */
  676. @property(atomic, readonly, nullable) GTMSessionFetcher *objectFetcher;
  677. /**
  678. * The queue used for query callbacks.
  679. */
  680. @property(atomic, readonly) dispatch_queue_t callbackQueue;
  681. /**
  682. * The API key used for the query requeat.
  683. */
  684. @property(atomic, readonly, nullable) NSString *APIKey;
  685. /**
  686. * The Bundle Identifier to use for the API key restriciton.
  687. */
  688. @property(atomic, readonly, nullable) NSString *APIKeyRestrictionBundleID;
  689. #pragma mark Status
  690. /**
  691. * The server's response status for the query's fetch, if available.
  692. */
  693. @property(nonatomic, readonly) NSInteger statusCode;
  694. /**
  695. * The error resulting from the query's fetch, if available.
  696. */
  697. @property(nonatomic, readonly, nullable) NSError *fetchError;
  698. /**
  699. * A flag indicating if the query's callbacks have been invoked.
  700. */
  701. @property(nonatomic, readonly) BOOL hasCalledCallback;
  702. /**
  703. * A flag indicating if the query execution was cancelled by the client app.
  704. */
  705. @property(atomic, readonly, getter=isCancelled) BOOL cancelled;
  706. #pragma mark Pagination
  707. /**
  708. * A flag indicating if automatic pagination is enabled for the query.
  709. */
  710. @property(nonatomic, readonly) BOOL shouldFetchNextPages;
  711. /**
  712. * The number of pages fetched, if automatic pagination is enabled for the query and multiple
  713. * pages have been fetched.
  714. */
  715. @property(nonatomic, readonly) NSUInteger pagesFetchedCounter;
  716. #pragma mark User Properties
  717. /**
  718. * Ticket properties a way to pass values via the ticket for the convenience of the client app.
  719. *
  720. * Ticket properties are initialized from serviceProperties and augmented by the ticketProperties
  721. * of the query's execution parameters.
  722. */
  723. @property(nonatomic, readonly, nullable) NSDictionary<NSString *, id> *ticketProperties;
  724. #pragma mark Payload
  725. /**
  726. * The object being uploaded via POST, PUT, or PATCH.
  727. */
  728. @property(nonatomic, readonly, nullable) GTLRObject *postedObject;
  729. /**
  730. * The object downloaded for the query, after parsing.
  731. */
  732. @property(nonatomic, readonly, nullable) GTLRObject *fetchedObject;
  733. /**
  734. * The query currently being fetched by this ticket. This may not be the original query when
  735. * fetching a second or later pages.
  736. */
  737. @property(atomic, readonly, nullable) id<GTLRQueryProtocol> executingQuery;
  738. /**
  739. * The query used to create this ticket
  740. */
  741. @property(atomic, readonly, nullable) id<GTLRQueryProtocol> originalQuery;
  742. /**
  743. * The @c GTLRObjectClassResolver for controlling object class selection.
  744. */
  745. @property(atomic, readonly, strong) id<GTLRObjectClassResolver> objectClassResolver;
  746. /**
  747. * The query from within the ticket's batch request with the given ID.
  748. *
  749. * @param requestID The desired ticket's request ID.
  750. *
  751. * @return The query with the specified ID, if found.
  752. */
  753. - (nullable GTLRQuery *)queryForRequestID:(NSString *)requestID;
  754. @end
  755. /**
  756. * The library doesn't use GTLRObjectCollectionImpl, but it provides a concrete implementation
  757. * so the methods do not cause private method errors in Xcode/AppStore review.
  758. */
  759. @interface GTLRObjectCollectionImpl : GTLRObject
  760. @property(nonatomic, copy) NSString *nextPageToken;
  761. @end
  762. NS_ASSUME_NONNULL_END