GDTCOREvent.m 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  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/Public/GoogleDataTransport/GDTCOREvent.h"
  17. #import "GoogleDataTransport/GDTCORLibrary/Internal/GDTCORAssert.h"
  18. #import "GoogleDataTransport/GDTCORLibrary/Internal/GDTCORPlatform.h"
  19. #import "GoogleDataTransport/GDTCORLibrary/Internal/GDTCORStorageProtocol.h"
  20. #import "GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCORClock.h"
  21. #import "GoogleDataTransport/GDTCORLibrary/Public/GoogleDataTransport/GDTCORConsoleLogger.h"
  22. #import "GoogleDataTransport/GDTCORLibrary/Private/GDTCOREvent_Private.h"
  23. @implementation GDTCOREvent
  24. + (NSString *)nextEventID {
  25. // TODO: Consider a way to make the eventIDs incremental without introducing a storage dependency
  26. // to the object.
  27. //
  28. // Replace special non-alphanumeric characters to avoid potential conflicts with storage logic.
  29. return [[NSUUID UUID].UUIDString stringByReplacingOccurrencesOfString:@"-" withString:@""];
  30. }
  31. - (nullable instancetype)initWithMappingID:(NSString *)mappingID target:(GDTCORTarget)target {
  32. GDTCORAssert(mappingID.length > 0, @"Please give a valid mapping ID");
  33. GDTCORAssert(target > 0, @"A target cannot be negative or 0");
  34. if (mappingID.length == 0 || target <= 0) {
  35. return nil;
  36. }
  37. self = [super init];
  38. if (self) {
  39. _eventID = [GDTCOREvent nextEventID];
  40. _mappingID = mappingID;
  41. _target = target;
  42. _qosTier = GDTCOREventQosDefault;
  43. _expirationDate = [NSDate dateWithTimeIntervalSinceNow:604800]; // 7 days.
  44. GDTCORLogDebug(@"Event %@ created. ID:%@ mappingID: %@ target:%ld", self, _eventID, mappingID,
  45. (long)target);
  46. }
  47. return self;
  48. }
  49. - (instancetype)copy {
  50. GDTCOREvent *copy = [[GDTCOREvent alloc] initWithMappingID:_mappingID target:_target];
  51. copy->_eventID = _eventID;
  52. copy.dataObject = _dataObject;
  53. copy.qosTier = _qosTier;
  54. copy.clockSnapshot = _clockSnapshot;
  55. copy.customBytes = _customBytes;
  56. GDTCORLogDebug(@"Copying event %@ to event %@", self, copy);
  57. return copy;
  58. }
  59. - (NSUInteger)hash {
  60. // This loses some precision, but it's probably fine.
  61. NSUInteger eventIDHash = [_eventID hash];
  62. NSUInteger mappingIDHash = [_mappingID hash];
  63. NSUInteger timeHash = [_clockSnapshot hash];
  64. NSInteger serializedBytesHash = [_serializedDataObjectBytes hash];
  65. return eventIDHash ^ mappingIDHash ^ _target ^ _qosTier ^ timeHash ^ serializedBytesHash;
  66. }
  67. - (BOOL)isEqual:(id)object {
  68. return [self hash] == [object hash];
  69. }
  70. #pragma mark - Property overrides
  71. - (void)setDataObject:(id<GDTCOREventDataObject>)dataObject {
  72. // If you're looking here because of a performance issue in -transportBytes slowing the assignment
  73. // of -dataObject, one way to address this is to add a queue to this class,
  74. // dispatch_(barrier_ if concurrent)async here, and implement the getter with a dispatch_sync.
  75. if (dataObject != _dataObject) {
  76. _dataObject = dataObject;
  77. }
  78. self->_serializedDataObjectBytes = [dataObject transportBytes];
  79. }
  80. #pragma mark - NSSecureCoding and NSCoding Protocols
  81. /** NSCoding key for eventID property. */
  82. static NSString *kEventIDKey = @"GDTCOREventEventIDKey";
  83. /** NSCoding key for mappingID property. */
  84. static NSString *kMappingIDKey = @"GDTCOREventMappingIDKey";
  85. /** NSCoding key for target property. */
  86. static NSString *kTargetKey = @"GDTCOREventTargetKey";
  87. /** NSCoding key for qosTier property. */
  88. static NSString *kQoSTierKey = @"GDTCOREventQoSTierKey";
  89. /** NSCoding key for clockSnapshot property. */
  90. static NSString *kClockSnapshotKey = @"GDTCOREventClockSnapshotKey";
  91. /** NSCoding key for expirationDate property. */
  92. static NSString *kExpirationDateKey = @"GDTCOREventExpirationDateKey";
  93. /** NSCoding key for serializedDataObjectBytes property. */
  94. static NSString *kSerializedDataObjectBytes = @"GDTCOREventSerializedDataObjectBytesKey";
  95. /** NSCoding key for customData property. */
  96. static NSString *kCustomDataKey = @"GDTCOREventCustomDataKey";
  97. + (BOOL)supportsSecureCoding {
  98. return YES;
  99. }
  100. - (id)initWithCoder:(NSCoder *)aDecoder {
  101. self = [self init];
  102. if (self) {
  103. _mappingID = [aDecoder decodeObjectOfClass:[NSString class] forKey:kMappingIDKey];
  104. _target = [aDecoder decodeIntegerForKey:kTargetKey];
  105. _eventID = [aDecoder decodeObjectOfClass:[NSString class] forKey:kEventIDKey]
  106. ?: [GDTCOREvent nextEventID];
  107. _qosTier = [aDecoder decodeIntegerForKey:kQoSTierKey];
  108. _clockSnapshot = [aDecoder decodeObjectOfClass:[GDTCORClock class] forKey:kClockSnapshotKey];
  109. _customBytes = [aDecoder decodeObjectOfClass:[NSData class] forKey:kCustomDataKey];
  110. _expirationDate = [aDecoder decodeObjectOfClass:[NSDate class] forKey:kExpirationDateKey];
  111. _serializedDataObjectBytes = [aDecoder decodeObjectOfClass:[NSData class]
  112. forKey:kSerializedDataObjectBytes];
  113. if (!_serializedDataObjectBytes) {
  114. return nil;
  115. }
  116. }
  117. return self;
  118. }
  119. - (void)encodeWithCoder:(NSCoder *)aCoder {
  120. [aCoder encodeObject:_eventID forKey:kEventIDKey];
  121. [aCoder encodeObject:_mappingID forKey:kMappingIDKey];
  122. [aCoder encodeInteger:_target forKey:kTargetKey];
  123. [aCoder encodeInteger:_qosTier forKey:kQoSTierKey];
  124. [aCoder encodeObject:_clockSnapshot forKey:kClockSnapshotKey];
  125. [aCoder encodeObject:_customBytes forKey:kCustomDataKey];
  126. [aCoder encodeObject:_expirationDate forKey:kExpirationDateKey];
  127. [aCoder encodeObject:self.serializedDataObjectBytes forKey:kSerializedDataObjectBytes];
  128. }
  129. @end