Skip to content

Build GDT for Catalyst #3525

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Aug 12, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 45 additions & 8 deletions GoogleDataTransport/GDTLibrary/GDTStorage.m
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,16 @@ - (void)storeEvent:(GDTEvent *)event {

// If running in the background, save state to disk and end the associated background task.
if (bgID != GDTBackgroundIdentifierInvalid) {
[NSKeyedArchiver archiveRootObject:self toFile:[GDTStorage archivePath]];
if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:self
requiringSecureCoding:YES
error:nil];
[data writeToFile:[GDTStorage archivePath] atomically:YES];
} else {
#if !defined(TARGET_OS_MACCATALYST)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it possible for TARGET_OS_MACCATALYST to ever be defined when !@available(macOS 10.13)?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep. It's not executed, but it still tries to compile and fails when building for Catalyst.

[NSKeyedArchiver archiveRootObject:self toFile:[GDTStorage archivePath]];
#endif
}
[[GDTApplication sharedApplication] endBackgroundTask:bgID];
}
});
Expand Down Expand Up @@ -193,13 +202,29 @@ - (void)addEventToTrackingCollections:(GDTStoredEvent *)event {
#pragma mark - GDTLifecycleProtocol

- (void)appWillForeground:(GDTApplication *)app {
[NSKeyedUnarchiver unarchiveObjectWithFile:[GDTStorage archivePath]];
if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
NSData *data = [NSData dataWithContentsOfFile:[GDTStorage archivePath]];
[NSKeyedUnarchiver unarchivedObjectOfClass:[GDTStorage class] fromData:data error:nil];
} else {
#if !defined(TARGET_OS_MACCATALYST)
[NSKeyedUnarchiver unarchiveObjectWithFile:[GDTStorage archivePath]];
#endif
}
self->_runningInBackground = NO;
}

- (void)appWillBackground:(GDTApplication *)app {
self->_runningInBackground = YES;
[NSKeyedArchiver archiveRootObject:self toFile:[GDTStorage archivePath]];
if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:self
requiringSecureCoding:YES
error:nil];
[data writeToFile:[GDTStorage archivePath] atomically:YES];
} else {
#if !defined(TARGET_OS_MACCATALYST)
[NSKeyedArchiver archiveRootObject:self toFile:[GDTStorage archivePath]];
#endif
}
// Create an immediate background task to run until the end of the current queue of work.
__block GDTBackgroundIdentifier bgID = [app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:bgID];
Expand All @@ -210,7 +235,16 @@ - (void)appWillBackground:(GDTApplication *)app {
}

- (void)appWillTerminate:(GDTApplication *)application {
[NSKeyedArchiver archiveRootObject:self toFile:[GDTStorage archivePath]];
if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:self
requiringSecureCoding:YES
error:nil];
[data writeToFile:[GDTStorage archivePath] atomically:YES];
} else {
#if !defined(TARGET_OS_MACCATALYST)
[NSKeyedArchiver archiveRootObject:self toFile:[GDTStorage archivePath]];
#endif
}
}

#pragma mark - NSSecureCoding
Expand All @@ -232,11 +266,14 @@ - (instancetype)initWithCoder:(NSCoder *)aDecoder {
// Create the singleton and populate its ivars.
GDTStorage *sharedInstance = [self.class sharedInstance];
dispatch_sync(sharedInstance.storageQueue, ^{
sharedInstance->_storedEvents = [aDecoder decodeObjectOfClass:[NSMutableOrderedSet class]
forKey:kGDTStorageStoredEventsKey];
NSSet *classes =
[NSSet setWithObjects:[NSMutableOrderedSet class], [GDTStoredEvent class], nil];
sharedInstance->_storedEvents = [aDecoder decodeObjectOfClasses:classes
forKey:kGDTStorageStoredEventsKey];
classes = [NSSet setWithObjects:[NSMutableDictionary class], [NSMutableSet class],
[GDTStoredEvent class], nil];
sharedInstance->_targetToEventSet =
[aDecoder decodeObjectOfClass:[NSMutableDictionary class]
forKey:kGDTStorageTargetToEventSetKey];
[aDecoder decodeObjectOfClasses:classes forKey:kGDTStorageTargetToEventSetKey];
sharedInstance->_uploadCoordinator =
[aDecoder decodeObjectOfClass:[GDTUploadCoordinator class]
forKey:kGDTStorageUploadCoordinatorKey];
Expand Down
8 changes: 5 additions & 3 deletions GoogleDataTransport/GDTLibrary/GDTUploadPackage.m
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#import <GoogleDataTransport/GDTClock.h>
#import <GoogleDataTransport/GDTConsoleLogger.h>
#import <GoogleDataTransport/GDTStoredEvent.h>

#import "GDTLibrary/Private/GDTStorage_Private.h"
#import "GDTLibrary/Private/GDTUploadCoordinator.h"
Expand Down Expand Up @@ -140,11 +141,12 @@ - (nullable instancetype)initWithCoder:(nonnull NSCoder *)aDecoder {
GDTTarget target = [aDecoder decodeIntegerForKey:kTargetKey];
self = [self initWithTarget:target];
if (self) {
_events = [aDecoder decodeObjectOfClass:[NSSet class] forKey:kEventsKey];
NSSet *classes = [NSSet setWithObjects:[NSSet class], [GDTStoredEvent class], nil];
_events = [aDecoder decodeObjectOfClasses:classes forKey:kEventsKey];
_deliverByTime = [aDecoder decodeObjectOfClass:[GDTClock class] forKey:kDeliverByTimeKey];
_isHandled = [aDecoder decodeBoolForKey:kIsHandledKey];
// Isn't technically NSSecureCoding, because we don't know the class of this object.
_handler = [aDecoder decodeObjectForKey:kHandlerKey];
// _handler isn't technically NSSecureCoding, because we don't know the class of this object.
// but it gets decoded anyway.
}
return self;
}
Expand Down
16 changes: 14 additions & 2 deletions GoogleDataTransport/GDTTests/Unit/GDTClockTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,20 @@ - (void)testSupportsSecureEncoding {
/** Tests encoding and decoding a clock using a keyed archiver. */
- (void)testEncoding {
GDTClock *clock = [GDTClock snapshot];
NSData *clockData = [NSKeyedArchiver archivedDataWithRootObject:clock];
GDTClock *unarchivedClock = [NSKeyedUnarchiver unarchiveObjectWithData:clockData];
GDTClock *unarchivedClock;
if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
NSData *clockData = [NSKeyedArchiver archivedDataWithRootObject:clock
requiringSecureCoding:YES
error:nil];
unarchivedClock = [NSKeyedUnarchiver unarchivedObjectOfClass:[GDTClock class]
fromData:clockData
error:nil];
} else {
#if !defined(TARGET_OS_MACCATALYST)
NSData *clockData = [NSKeyedArchiver archivedDataWithRootObject:clock];
unarchivedClock = [NSKeyedUnarchiver unarchiveObjectWithData:clockData];
#endif
}
XCTAssertEqual([clock hash], [unarchivedClock hash]);
XCTAssertEqualObjects(clock, unarchivedClock);
}
Expand Down
24 changes: 20 additions & 4 deletions GoogleDataTransport/GDTTests/Unit/GDTEventTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,28 @@ - (void)testArchiving {
event.qosTier = GDTEventQoSTelemetry;
event.clockSnapshot = clockSnapshot;

NSData *archiveData = [NSKeyedArchiver archivedDataWithRootObject:event];

NSData *archiveData;
if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
archiveData = [NSKeyedArchiver archivedDataWithRootObject:event
requiringSecureCoding:YES
error:nil];
} else {
#if !defined(TARGET_OS_MACCATALYST)
archiveData = [NSKeyedArchiver archivedDataWithRootObject:event];
#endif
}
// To ensure that all the objects being retained by the original event are dealloc'd.
event = nil;

GDTEvent *decodedEvent = [NSKeyedUnarchiver unarchiveObjectWithData:archiveData];
GDTEvent *decodedEvent;
if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
decodedEvent = [NSKeyedUnarchiver unarchivedObjectOfClass:[GDTEvent class]
fromData:archiveData
error:nil];
} else {
#if !defined(TARGET_OS_MACCATALYST)
decodedEvent = [NSKeyedUnarchiver unarchiveObjectWithData:archiveData];
#endif
}
XCTAssertEqualObjects(decodedEvent.mappingID, @"testID");
XCTAssertEqual(decodedEvent.target, 42);
XCTAssertEqualObjects(decodedEvent.dataObjectTransportBytes,
Expand Down
54 changes: 47 additions & 7 deletions GoogleDataTransport/GDTTests/Unit/GDTStorageTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ - (void)testStoreEvent {
@autoreleasepool {
GDTEvent *event = [[GDTEvent alloc] initWithMappingID:@"404" target:target];
event.dataObjectTransportBytes = [@"testString" dataUsingEncoding:NSUTF8StringEncoding];
event.clockSnapshot = [GDTClock snapshot];
XCTAssertNoThrow([[GDTStorage sharedInstance] storeEvent:event]);
}
dispatch_sync([GDTStorage sharedInstance].storageQueue, ^{
Expand All @@ -103,6 +104,7 @@ - (void)testRemoveEvent {
@autoreleasepool {
GDTEvent *event = [[GDTEvent alloc] initWithMappingID:@"404" target:target];
event.dataObjectTransportBytes = [@"testString" dataUsingEncoding:NSUTF8StringEncoding];
event.clockSnapshot = [GDTClock snapshot];
XCTAssertNoThrow([[GDTStorage sharedInstance] storeEvent:event]);
}
__block NSURL *eventFile;
Expand Down Expand Up @@ -223,7 +225,7 @@ - (void)testEventDeallocationIsEnforced {
GDTEvent *event = [[GDTEvent alloc] initWithMappingID:@"404" target:target];
weakEvent = event;
event.dataObjectTransportBytes = [@"testString" dataUsingEncoding:NSUTF8StringEncoding];

event.clockSnapshot = [GDTClock snapshot];
// Store the event and wait for the expectation.
[[GDTStorage sharedInstance] storeEvent:event];
GDTDataFuture *dataFuture =
Expand Down Expand Up @@ -256,38 +258,75 @@ - (void)testEventDeallocationIsEnforced {
- (void)testNSSecureCoding {
XCTAssertTrue([GDTStorage supportsSecureCoding]);
GDTEvent *event = [[GDTEvent alloc] initWithMappingID:@"404" target:target];
event.clockSnapshot = [GDTClock snapshot];
event.dataObjectTransportBytes = [@"testString" dataUsingEncoding:NSUTF8StringEncoding];
XCTAssertNoThrow([[GDTStorage sharedInstance] storeEvent:event]);
event = nil;
NSData *storageData = [NSKeyedArchiver archivedDataWithRootObject:[GDTStorage sharedInstance]];
NSData *storageData;
if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
storageData = [NSKeyedArchiver archivedDataWithRootObject:[GDTStorage sharedInstance]
requiringSecureCoding:YES
error:nil];
} else {
#if !defined(TARGET_OS_MACCATALYST)
storageData = [NSKeyedArchiver archivedDataWithRootObject:[GDTStorage sharedInstance]];
#endif
}
dispatch_sync([GDTStorage sharedInstance].storageQueue, ^{
XCTAssertNotNil([[GDTStorage sharedInstance].storedEvents lastObject]);
});
[[GDTStorage sharedInstance] removeEvents:[GDTStorage sharedInstance].storedEvents.set];
dispatch_sync([GDTStorage sharedInstance].storageQueue, ^{
XCTAssertNil([[GDTStorage sharedInstance].storedEvents lastObject]);
});

GDTStorage *unarchivedStorage = [NSKeyedUnarchiver unarchiveObjectWithData:storageData];
GDTStorage *unarchivedStorage;
NSError *error;
if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
unarchivedStorage = [NSKeyedUnarchiver unarchivedObjectOfClass:[GDTStorage class]
fromData:storageData
error:&error];
} else {
#if !defined(TARGET_OS_MACCATALYST)
unarchivedStorage = [NSKeyedUnarchiver unarchiveObjectWithData:storageData];
#endif
}
XCTAssertNotNil([unarchivedStorage.storedEvents lastObject]);
}

/** Tests encoding and decoding the storage singleton when calling -sharedInstance. */
- (void)testNSSecureCodingWithSharedInstance {
GDTEvent *event = [[GDTEvent alloc] initWithMappingID:@"404" target:target];
event.dataObjectTransportBytes = [@"testString" dataUsingEncoding:NSUTF8StringEncoding];
event.clockSnapshot = [GDTClock snapshot];
XCTAssertNoThrow([[GDTStorage sharedInstance] storeEvent:event]);
event = nil;
NSData *storageData = [NSKeyedArchiver archivedDataWithRootObject:[GDTStorage sharedInstance]];
NSData *storageData;
if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
storageData = [NSKeyedArchiver archivedDataWithRootObject:[GDTStorage sharedInstance]
requiringSecureCoding:YES
error:nil];
} else {
#if !defined(TARGET_OS_MACCATALYST)
storageData = [NSKeyedArchiver archivedDataWithRootObject:[GDTStorage sharedInstance]];
#endif
}
dispatch_sync([GDTStorage sharedInstance].storageQueue, ^{
XCTAssertNotNil([[GDTStorage sharedInstance].storedEvents lastObject]);
});
[[GDTStorage sharedInstance] removeEvents:[GDTStorage sharedInstance].storedEvents.set];
dispatch_sync([GDTStorage sharedInstance].storageQueue, ^{
XCTAssertNil([[GDTStorage sharedInstance].storedEvents lastObject]);
});

GDTStorage *unarchivedStorage = [NSKeyedUnarchiver unarchiveObjectWithData:storageData];
GDTStorage *unarchivedStorage;
if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
unarchivedStorage = [NSKeyedUnarchiver unarchivedObjectOfClass:[GDTStorage class]
fromData:storageData
error:nil];
} else {
#if !defined(TARGET_OS_MACCATALYST)
unarchivedStorage = [NSKeyedUnarchiver unarchiveObjectWithData:storageData];
#endif
}
XCTAssertNotNil([unarchivedStorage.storedEvents lastObject]);
}

Expand All @@ -298,6 +337,7 @@ - (void)testQoSTierFast {
GDTEvent *event = [[GDTEvent alloc] initWithMappingID:@"404" target:target];
event.dataObjectTransportBytes = [@"testString" dataUsingEncoding:NSUTF8StringEncoding];
event.qosTier = GDTEventQoSFast;
event.clockSnapshot = [GDTClock snapshot];
XCTAssertFalse(self.uploaderFake.forceUploadCalled);
XCTAssertNoThrow([[GDTStorage sharedInstance] storeEvent:event]);
}
Expand Down
20 changes: 17 additions & 3 deletions GoogleDataTransport/GDTTests/Unit/GDTUploadPackageTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,23 @@ - (void)testEncoding {
NSMutableSet<GDTStoredEvent *> *set = [GDTEventGenerator generate3StoredEvents];
uploadPackage.events = set;
uploadPackage.handler = self;

NSData *packageData = [NSKeyedArchiver archivedDataWithRootObject:uploadPackage];
GDTUploadPackage *recreatedPackage = [NSKeyedUnarchiver unarchiveObjectWithData:packageData];
GDTUploadPackage *recreatedPackage;
NSError *error;

if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
NSData *packageData = [NSKeyedArchiver archivedDataWithRootObject:uploadPackage
requiringSecureCoding:YES
error:&error];
recreatedPackage = [NSKeyedUnarchiver unarchivedObjectOfClass:[GDTUploadPackage class]
fromData:packageData
error:&error];
XCTAssertNil(error);
} else {
#if !defined(TARGET_OS_MACCATALYST)
NSData *packageData = [NSKeyedArchiver archivedDataWithRootObject:uploadPackage];
recreatedPackage = [NSKeyedUnarchiver unarchiveObjectWithData:packageData];
#endif
}
XCTAssertEqualObjects(uploadPackage, recreatedPackage);
}

Expand Down