From 09e85a7c7b571411590707e497b4c56197abc94b Mon Sep 17 00:00:00 2001 From: Anna Kocheshkova Date: Fri, 7 Aug 2020 11:21:04 +0300 Subject: [PATCH] Fix sending logs from applicationWillTerminate --- .../Internals/Channel/MSChannelGroupDefault.m | 31 +++++++++++++++++ .../Channel/MSChannelGroupDefaultPrivate.h | 13 ++++++++ .../MSChannelGroupDefaultTests.m | 33 +++++++++++++++++++ CHANGELOG.md | 4 +++ 4 files changed, 81 insertions(+) diff --git a/AppCenter/AppCenter/Internals/Channel/MSChannelGroupDefault.m b/AppCenter/AppCenter/Internals/Channel/MSChannelGroupDefault.m index 1e381d46c3..be68974fdb 100644 --- a/AppCenter/AppCenter/Internals/Channel/MSChannelGroupDefault.m +++ b/AppCenter/AppCenter/Internals/Channel/MSChannelGroupDefault.m @@ -13,6 +13,12 @@ @implementation MSChannelGroupDefault +#if !TARGET_OS_OSX + +@synthesize delayedProcessingSemaphore = _delayedProcessingSemaphore; + +#endif + #pragma mark - Initialization - (instancetype)initWithHttpClient:(id)httpClient installId:(NSUUID *)installId logUrl:(NSString *)logUrl { @@ -32,6 +38,9 @@ - (instancetype)initWithIngestion:(nullable MSAppCenterIngestion *)ingestion { if (ingestion) { _ingestion = ingestion; } +#if !TARGET_OS_OSX + _delayedProcessingSemaphore = dispatch_semaphore_create(0); +#endif } return self; } @@ -177,6 +186,17 @@ - (void)channel:(id)channel didResumeWithIdentifyingObject:(i - (void)setEnabled:(BOOL)isEnabled andDeleteDataOnDisabled:(BOOL)deleteData { +#if !TARGET_OS_OSX + if (isEnabled) { + [MS_NOTIFICATION_CENTER addObserver:self + selector:@selector(applicationWillTerminate:) + name:UIApplicationWillTerminateNotification + object:nil]; + } else { + [MS_NOTIFICATION_CENTER removeObserver:self]; + } +#endif + // Propagate to ingestion. [self.ingestion setEnabled:isEnabled andDeleteDataOnDisabled:deleteData]; @@ -199,6 +219,17 @@ - (void)setEnabled:(BOOL)isEnabled andDeleteDataOnDisabled:(BOOL)deleteData { */ } +#if !TARGET_OS_OSX +- (void)applicationWillTerminate:(__unused UIApplication *)application { + + // Block logs queue so that it isn't killed before app termination. + dispatch_async(self.logsDispatchQueue, ^{ + dispatch_semaphore_signal(self.delayedProcessingSemaphore); + }); + dispatch_semaphore_wait(self.delayedProcessingSemaphore, dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC)); +} +#endif + #pragma mark - Pause / Resume - (void)pauseWithIdentifyingObject:(id)identifyingObject { diff --git a/AppCenter/AppCenter/Internals/Channel/MSChannelGroupDefaultPrivate.h b/AppCenter/AppCenter/Internals/Channel/MSChannelGroupDefaultPrivate.h index befe90615b..f3c1547b4d 100644 --- a/AppCenter/AppCenter/Internals/Channel/MSChannelGroupDefaultPrivate.h +++ b/AppCenter/AppCenter/Internals/Channel/MSChannelGroupDefaultPrivate.h @@ -18,6 +18,19 @@ NS_ASSUME_NONNULL_BEGIN */ - (instancetype)initWithIngestion:(nullable MSAppCenterIngestion *)ingestion; +#if !TARGET_OS_OSX +/** + * Semaphore for blocking logs queue on applicationWillTerminate. + */ +@property dispatch_semaphore_t delayedProcessingSemaphore; + +/** + * Called when applciation is terminating. + */ +- (void)applicationWillTerminate:(__unused UIApplication *)application; + +#endif + @end NS_ASSUME_NONNULL_END diff --git a/AppCenter/AppCenterTests/MSChannelGroupDefaultTests.m b/AppCenter/AppCenterTests/MSChannelGroupDefaultTests.m index 2ebc787b03..8e7c709bc4 100644 --- a/AppCenter/AppCenterTests/MSChannelGroupDefaultTests.m +++ b/AppCenter/AppCenterTests/MSChannelGroupDefaultTests.m @@ -1,6 +1,11 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +#import "TargetConditionals.h" +#if !TARGET_OS_OSX +#import +#endif + #import "MSAbstractLogInternal.h" #import "MSAppCenterIngestion.h" #import "MSChannelDelegate.h" @@ -61,6 +66,34 @@ - (void)tearDown { [super tearDown]; } +#if !TARGET_OS_OSX +- (void)testAppIsKilled { + + // If + [self.sut setEnabled:YES andDeleteDataOnDisabled:YES]; + id sut = OCMPartialMock(self.sut); + + // When + [[NSNotificationCenter defaultCenter] postNotificationName:UIApplicationWillTerminateNotification object:sut]; + + // Then + OCMVerify([sut applicationWillTerminate:OCMOCK_ANY]); + XCTAssertNotNil(self.sut.logsDispatchQueue); + + // If + [self.sut setEnabled:NO andDeleteDataOnDisabled:YES]; + OCMReject([sut applicationWillTerminate:OCMOCK_ANY]); + + // When + [[NSNotificationCenter defaultCenter] postNotificationName:UIApplicationWillTerminateNotification object:sut]; + + // Then + self.sut.logsDispatchQueue = nil; + OCMVerifyAll(sut); + [sut stopMocking]; +} +#endif + #pragma mark - Tests - (void)testNewInstanceWasInitialisedCorrectly { diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ea91d3b3b..0455282854 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ * **[Fix]** Fix compatibility with Xcode 12 beta when integrating SDK from sources. +### App Center Analytics + +* **[Fix]** Fix sending logs from `applicationWillTerminate`. + ___ ## Version 3.3.2