GDTCORTransformer.m 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /*
  2. * Copyright 2018 Google
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #import "GoogleDataTransport/GDTCORLibrary/Private/GDTCORTransformer.h"
  17. #import "GoogleDataTransport/GDTCORLibrary/Private/GDTCORTransformer_Private.h"
  18. #import "GoogleDataTransport/GDTCORLibrary/Internal/GDTCORAssert.h"
  19. #import "GoogleDataTransport/GDTCORLibrary/Internal/GDTCORLifecycle.h"
  20. #import "GoogleDataTransport/GDTCORLibrary/Internal/GDTCORStorageProtocol.h"
  21. #import "GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCORConsoleLogger.h"
  22. #import "GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCOREvent.h"
  23. #import "GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCOREventTransformer.h"
  24. #import "GoogleDataTransport/GDTCORLibrary/Private/GDTCOREvent_Private.h"
  25. #import "GoogleDataTransport/GDTCORLibrary/Private/GDTCORRegistrar_Private.h"
  26. @implementation GDTCORTransformer
  27. + (instancetype)sharedInstance {
  28. static GDTCORTransformer *eventTransformer;
  29. static dispatch_once_t onceToken;
  30. dispatch_once(&onceToken, ^{
  31. eventTransformer = [[self alloc] init];
  32. });
  33. return eventTransformer;
  34. }
  35. - (instancetype)init {
  36. return [self initWithApplication:[GDTCORApplication sharedApplication]];
  37. }
  38. - (instancetype)initWithApplication:(id<GDTCORApplicationProtocol>)application {
  39. self = [super init];
  40. if (self) {
  41. _eventWritingQueue =
  42. dispatch_queue_create("com.google.GDTCORTransformer", DISPATCH_QUEUE_SERIAL);
  43. _application = application;
  44. }
  45. return self;
  46. }
  47. - (void)transformEvent:(GDTCOREvent *)event
  48. withTransformers:(NSArray<id<GDTCOREventTransformer>> *)transformers
  49. onComplete:(void (^_Nullable)(BOOL wasWritten, NSError *_Nullable error))completion {
  50. GDTCORAssert(event, @"You can't write a nil event");
  51. __block GDTCORBackgroundIdentifier bgID = GDTCORBackgroundIdentifierInvalid;
  52. __auto_type __weak weakApplication = self.application;
  53. bgID = [self.application beginBackgroundTaskWithName:@"GDTTransformer"
  54. expirationHandler:^{
  55. [weakApplication endBackgroundTask:bgID];
  56. bgID = GDTCORBackgroundIdentifierInvalid;
  57. }];
  58. __auto_type completionWrapper = ^(BOOL wasWritten, NSError *_Nullable error) {
  59. if (completion) {
  60. completion(wasWritten, error);
  61. }
  62. // The work is done, cancel the background task if it's valid.
  63. [weakApplication endBackgroundTask:bgID];
  64. bgID = GDTCORBackgroundIdentifierInvalid;
  65. };
  66. dispatch_async(_eventWritingQueue, ^{
  67. GDTCOREvent *transformedEvent = event;
  68. for (id<GDTCOREventTransformer> transformer in transformers) {
  69. if ([transformer respondsToSelector:@selector(transform:)]) {
  70. GDTCORLogDebug(@"Applying a transformer to event %@", event);
  71. transformedEvent = [transformer transform:transformedEvent];
  72. if (!transformedEvent) {
  73. completionWrapper(NO, nil);
  74. return;
  75. }
  76. } else {
  77. GDTCORLogError(GDTCORMCETransformerDoesntImplementTransform,
  78. @"Transformer doesn't implement transform: %@", transformer);
  79. completionWrapper(NO, nil);
  80. return;
  81. }
  82. }
  83. id<GDTCORStorageProtocol> storage =
  84. [GDTCORRegistrar sharedInstance].targetToStorage[@(event.target)];
  85. [storage storeEvent:transformedEvent onComplete:completionWrapper];
  86. });
  87. }
  88. #pragma mark - GDTCORLifecycleProtocol
  89. - (void)appWillTerminate:(GDTCORApplication *)application {
  90. // Flush the queue immediately.
  91. dispatch_sync(_eventWritingQueue, ^{
  92. });
  93. }
  94. @end