Skip to content
This repository has been archived by the owner on Feb 19, 2020. It is now read-only.

Fix/access applicationstate on main thread #484

Closed
12 changes: 7 additions & 5 deletions Classes/BITAuthenticator.m
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#import "BITAuthenticationViewController.h"
#import "BITHockeyAppClient.h"
#import "BITHockeyHelper.h"
#import "BITHockeyHelper+Application.h"
#import "BITHockeyBaseManagerPrivate.h"

#include <sys/stat.h>
Expand Down Expand Up @@ -105,12 +106,13 @@ - (void)authenticateInstallation {
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(authenticateInstallation) object:nil];
[self performSelector:@selector(authenticateInstallation) withObject:nil afterDelay:0.1];
} else {
switch ([[UIApplication sharedApplication] applicationState]) {
case UIApplicationStateActive:
switch ([BITHockeyHelper applicationState]) {
case BITApplicationStateActive:
[self authenticate];
break;
case UIApplicationStateBackground:
case UIApplicationStateInactive:
case BITApplicationStateBackground:
case BITApplicationStateInactive:
case BITApplicationStateUnknown:
// do nothing, wait for active state
break;
}
Expand Down Expand Up @@ -743,7 +745,7 @@ + (void)email:(NSString *__autoreleasing *)email andIUID:(NSString *__autoreleas
#pragma mark - Private helpers

- (void)alertOnFailureStoringTokenInKeychain {
if ([[UIApplication sharedApplication] applicationState] != UIApplicationStateActive) {
if ([BITHockeyHelper applicationState] != BITApplicationStateActive) {
return;
}

Expand Down
21 changes: 4 additions & 17 deletions Classes/BITChannel.m
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#import "BITHockeyManager.h"
#import "BITChannelPrivate.h"
#import "BITHockeyHelper.h"
#import "BITHockeyHelper+Application.h"
#import "BITTelemetryContext.h"
#import "BITTelemetryData.h"
#import "BITEnvelope.h"
Expand Down Expand Up @@ -287,10 +288,11 @@ - (void)enqueueTelemetryItem:(BITTelemetryData *)item {
@synchronized(self) {
NSDictionary *dict = [strongSelf dictionaryForTelemetryData:item];
[strongSelf appendDictionaryToEventBuffer:dict];
// If the app is running in the background.
UIApplication *application = [UIApplication sharedApplication];
UIApplicationState state = [self checkApplicationStateForApplication:application];
BOOL applicationIsInBackground = ([BITHockeyHelper applicationState] == BITApplicationStateBackground) ? YES : NO;
if (strongSelf.dataItemCount >= strongSelf.maxBatchSize ||
(application && state == UIApplicationStateBackground)) {
(application && applicationIsInBackground)) {

Choose a reason for hiding this comment

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

Just applicationIsInBackground, no need to check application here


// Case 2: Max batch count has been reached or the app is running in the background, so write queue to disk and delete all items.
[strongSelf persistDataItemQueue:&BITTelemetryEventBuffer];
Expand All @@ -305,21 +307,6 @@ - (void)enqueueTelemetryItem:(BITTelemetryData *)item {
});
}

- (UIApplicationState)checkApplicationStateForApplication:(UIApplication *)application {
__block UIApplicationState state;
dispatch_block_t block = ^{
state = application.applicationState;
};

if ([NSThread isMainThread]) {
block();
} else {
dispatch_sync(dispatch_get_main_queue(), block);
}

return state;
}

#pragma mark - Envelope telemerty items

- (NSDictionary *)dictionaryForTelemetryData:(BITTelemetryData *) telemetryData {
Expand Down
6 changes: 3 additions & 3 deletions Classes/BITCrashManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@

#import "HockeySDKPrivate.h"
#import "BITHockeyHelper.h"
#import "BITHockeyHelper+Application.h"
#import "BITHockeyAppClient.h"

#import "BITCrashManager.h"
Expand Down Expand Up @@ -1052,8 +1053,7 @@ - (void)triggerDelayedProcessing {
*/
- (void)invokeDelayedProcessing {
#if !defined (HOCKEYSDK_CONFIGURATION_ReleaseCrashOnlyExtensions)
if (!bit_isRunningInAppExtension() &&
[[UIApplication sharedApplication] applicationState] != UIApplicationStateActive) {
if ([BITHockeyHelper applicationState] != BITApplicationStateActive) {
return;
}
#endif
Expand Down Expand Up @@ -1277,7 +1277,7 @@ - (void)startManager {
}

#if !defined (HOCKEYSDK_CONFIGURATION_ReleaseCrashOnlyExtensions)
if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateActive) {
if ([BITHockeyHelper applicationState] != BITApplicationStateActive) {
[self appEnteredForeground];
}
#else
Expand Down
12 changes: 7 additions & 5 deletions Classes/BITFeedbackManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@

#import "HockeySDKNullability.h"
#import "BITHockeyHelper.h"
#import "BITHockeyHelper+Application.h"
#import "BITHockeyAppClient.h"

#define kBITFeedbackUserDataAsked @"HockeyFeedbackUserDataAsked"
Expand Down Expand Up @@ -131,7 +132,7 @@ - (void)didBecomeActiveActions {
- (void)didEnterBackgroundActions {
self.didEnterBackgroundState = NO;

if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateBackground) {
if ([BITHockeyHelper applicationState] == BITApplicationStateBackground) {
self.didEnterBackgroundState = YES;
}
}
Expand Down Expand Up @@ -270,15 +271,16 @@ - (void)startManager {
[self isiOS10PhotoPolicySet];

// we are already delayed, so the notification already came in and this won't invoked twice
switch ([[UIApplication sharedApplication] applicationState]) {
case UIApplicationStateActive:
switch ([BITHockeyHelper applicationState]) {
case BITApplicationStateActive:
// we did startup, so yes we are coming from background
self.didEnterBackgroundState = YES;

[self didBecomeActiveActions];
break;
case UIApplicationStateBackground:
case UIApplicationStateInactive:
case BITApplicationStateBackground:
case BITApplicationStateInactive:
case BITApplicationStateUnknown:
// do nothing, wait for active state
break;
}
Expand Down
48 changes: 48 additions & 0 deletions Classes/BITHockeyHelper+Application.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

#import "BITHockeyHelper.h"
/*
* Workaround for exporting symbols from category object files.
*/
extern NSString *BITHockeyHelperApplicationCategory;

/**
* App states
*/
typedef NS_ENUM(NSInteger, BITApplicationState) {

/**
* Application is active.
*/
BITApplicationStateActive = UIApplicationStateActive,

/**
* Application is inactive.
*/
BITApplicationStateInactive = UIApplicationStateInactive,

/**
* Application is in background.
*/
BITApplicationStateBackground = UIApplicationStateBackground,

/**
* Application state can't be determined.
*/
BITApplicationStateUnknown
};

@interface BITHockeyHelper (Application)

/**
* Get current application state.
*
* @return Current state of the application or BITApplicationStateUnknown while the state can't be determined.
*
* @discussion The application state may not be available everywhere. Application extensions doesn't have it for instance,
* in that case the BITApplicationStateUnknown value is returned.
*/
+ (BITApplicationState)applicationState;

@end
52 changes: 52 additions & 0 deletions Classes/BITHockeyHelper+Application.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#import "BITHockeyHelper+Application.h"

/*
* Workaround for exporting symbols from category object files.
*/
NSString *BITHockeyHelperApplicationCategory;

@implementation BITHockeyHelper (Application)

/**
* @discussion
* Workaround for exporting symbols from category object files.
* See article https://medium.com/ios-os-x-development/categories-in-static-libraries-78e41f8ddb96#.aedfl1kl0
*/
__attribute__((used)) static void importCategories() {

Choose a reason for hiding this comment

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

Doesn't work. #486 fixes it.

[NSString stringWithFormat:@"%@", BITHockeyHelperApplicationCategory];
}

+ (BITApplicationState)applicationState {

// App extensions must not access sharedApplication.
if (!bit_isRunningInAppExtension()) {

__block BITApplicationState state;
dispatch_block_t block = ^{
state = (BITApplicationState)[[self class] sharedAppState];
};

if ([NSThread isMainThread]) {
block();
} else {
dispatch_sync(dispatch_get_main_queue(), block);
}

return state;
}
return BITApplicationStateUnknown;
}

+ (UIApplication *)sharedApplication {

// Compute selector at runtime for more discretion.
SEL sharedAppSel = NSSelectorFromString(@"sharedApplication");
return ((UIApplication * (*)(id, SEL))[[UIApplication class] methodForSelector:sharedAppSel])([UIApplication class],
sharedAppSel);
}

+ (UIApplicationState)sharedAppState {
return [[[[self class] sharedApplication] valueForKey:@"applicationState"] longValue];
}

@end
6 changes: 4 additions & 2 deletions Classes/BITMetricsManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#import "BITTelemetryContext.h"
#import "BITMetricsManagerPrivate.h"
#import "BITHockeyHelper.h"
#import "BITHockeyHelper+Application.h"
#import "HockeySDKPrivate.h"
#import "BITChannelPrivate.h"
#import "BITEventData.h"
Expand Down Expand Up @@ -197,7 +198,8 @@ - (void)trackEventWithName:(nonnull NSString *)eventName {

// If the app is running in the background.
UIApplication *application = [UIApplication sharedApplication];
if (application && application.applicationState == UIApplicationStateBackground) {
BOOL applicationIsInBackground = ([BITHockeyHelper applicationState] == BITApplicationStateBackground) ? YES : NO;

Choose a reason for hiding this comment

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

Remove ? YES : NO

if (application && applicationIsInBackground) {
[self.channel createBackgroundTask:application withWaitingGroup:group];
}
}
Expand All @@ -222,7 +224,7 @@ - (void)trackEventWithName:(nonnull NSString *)eventName properties:(nullable NS

// If the app is running in the background.
UIApplication *application = [UIApplication sharedApplication];
if (application && application.applicationState == UIApplicationStateBackground) {
BOOL applicationIsInBackground = ([BITHockeyHelper applicationState] == BITApplicationStateBackground) ? YES : NO; if (application && applicationIsInBackground) {

Choose a reason for hiding this comment

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

Remove ? YES : NO
Missing line break

[self.channel createBackgroundTask:application withWaitingGroup:group];
}
}
Expand Down
10 changes: 6 additions & 4 deletions Classes/BITStoreUpdateManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@

#import "HockeySDKPrivate.h"
#import "BITHockeyHelper.h"
#import "BITHockeyHelper+Application.h"

#import "BITHockeyBaseManagerPrivate.h"
#import "BITStoreUpdateManagerPrivate.h"
Expand Down Expand Up @@ -416,12 +417,13 @@ - (void)startManager {
[self registerObservers];

// we are already delayed, so the notification already came in and this won't invoked twice
switch ([[UIApplication sharedApplication] applicationState]) {
case UIApplicationStateActive:
switch ([BITHockeyHelper applicationState]) {
case BITApplicationStateActive:
[self didBecomeActiveActions];
break;
case UIApplicationStateBackground:
case UIApplicationStateInactive:
case BITApplicationStateBackground:
case BITApplicationStateInactive:
case BITApplicationStateUnknown:
// do nothing, wait for active state
break;
}
Expand Down
5 changes: 3 additions & 2 deletions Classes/BITUpdateManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@

#import "HockeySDKPrivate.h"
#import "BITHockeyHelper.h"
#import "BITHockeyHelper+Application.h"

#import "BITHockeyBaseManagerPrivate.h"
#import "BITUpdateManagerPrivate.h"
Expand Down Expand Up @@ -141,7 +142,7 @@ - (void)didBecomeActiveActions {
- (void)didEnterBackgroundActions {
self.didEnterBackgroundState = NO;

if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateBackground) {
if ([BITHockeyHelper applicationState] == BITApplicationStateBackground) {
self.didEnterBackgroundState = YES;
}
}
Expand Down Expand Up @@ -867,7 +868,7 @@ - (void)startManager {
[self checkExpiryDateReached];
if (![self expiryDateReached]) {
if ([self isCheckForUpdateOnLaunch] && [self shouldCheckForUpdates]) {
if ([[UIApplication sharedApplication] applicationState] != UIApplicationStateActive) return;
if ([BITHockeyHelper applicationState] != BITApplicationStateActive) return;

[self performSelector:@selector(checkForUpdate) withObject:nil afterDelay:1.0];
}
Expand Down
10 changes: 10 additions & 0 deletions Support/HockeySDK.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,9 @@
97F0F9FE18ABAECD00EF50AA /* iconCamera@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 97F0F9FC18ABAECD00EF50AA /* iconCamera@2x.png */; };
97F0FA0518B2294D00EF50AA /* BITFeedbackMessageAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = 97F0FA0318AE5AED00EF50AA /* BITFeedbackMessageAttachment.m */; };
B2156DD51D9DED7F0001DDDC /* AppIconPlaceHolder.png in Resources */ = {isa = PBXBuildFile; fileRef = B2156DD01D9DED7F0001DDDC /* AppIconPlaceHolder.png */; };
B2B2DB0A1FD9E47B00FB7FF2 /* BITHockeyHelper+Application.h in Headers */ = {isa = PBXBuildFile; fileRef = B2B2DB081FD9E47B00FB7FF2 /* BITHockeyHelper+Application.h */; };
B2B2DB0B1FD9E47B00FB7FF2 /* BITHockeyHelper+Application.m in Sources */ = {isa = PBXBuildFile; fileRef = B2B2DB091FD9E47B00FB7FF2 /* BITHockeyHelper+Application.m */; };
B2B2DB0C1FD9E48000FB7FF2 /* BITHockeyHelper+Application.h in Headers */ = {isa = PBXBuildFile; fileRef = B2B2DB081FD9E47B00FB7FF2 /* BITHockeyHelper+Application.h */; };
B2D1CE5E1D9DE55900CA74A8 /* FeedbackPlaceholder.png in Resources */ = {isa = PBXBuildFile; fileRef = B2D1CE5D1D9DE4F700CA74A8 /* FeedbackPlaceholder.png */; };
E405266217A2AD300096359C /* BITFeedbackManagerDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = E405266117A2AD300096359C /* BITFeedbackManagerDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; };
E40E0B0917DA19DC005E38C1 /* BITHockeyAppClientTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E40E0B0817DA19DC005E38C1 /* BITHockeyAppClientTests.m */; };
Expand Down Expand Up @@ -762,6 +765,8 @@
B29855421D85EB5D007FF452 /* allfeatures.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = allfeatures.xcconfig; sourceTree = "<group>"; };
B29855431D85EBAC007FF452 /* module_allfeatures.modulemap */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.module-map"; path = module_allfeatures.modulemap; sourceTree = "<group>"; };
B2B04C141FBFB1D100EC12F5 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/HockeySDK.strings; sourceTree = "<group>"; };
B2B2DB081FD9E47B00FB7FF2 /* BITHockeyHelper+Application.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "BITHockeyHelper+Application.h"; sourceTree = "<group>"; };
B2B2DB091FD9E47B00FB7FF2 /* BITHockeyHelper+Application.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "BITHockeyHelper+Application.m"; sourceTree = "<group>"; };
B2D1CE5D1D9DE4F700CA74A8 /* FeedbackPlaceholder.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = FeedbackPlaceholder.png; sourceTree = "<group>"; };
BEE0207C16C5107E004426EA /* hu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hu; path = hu.lproj/HockeySDK.strings; sourceTree = "<group>"; };
E328A2FB1C88B344008BB527 /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/HockeySDK.strings; sourceTree = "<group>"; };
Expand Down Expand Up @@ -959,6 +964,8 @@
1E49A4A4161222B900463151 /* BITHockeyBaseViewController.m */,
1E49A4A5161222B900463151 /* BITHockeyHelper.h */,
1E49A4A6161222B900463151 /* BITHockeyHelper.m */,
B2B2DB081FD9E47B00FB7FF2 /* BITHockeyHelper+Application.h */,
B2B2DB091FD9E47B00FB7FF2 /* BITHockeyHelper+Application.m */,
8080576B1C5818AE00BB319D /* BITHockeyLogger.h */,
8042A7F41CC507B700B603FE /* BITHockeyLoggerPrivate.h */,
8080576C1C5818AE00BB319D /* BITHockeyLogger.m */,
Expand Down Expand Up @@ -1398,6 +1405,7 @@
1E49A4B5161222B900463151 /* BITHockeyBaseManagerPrivate.h in Headers */,
9774BCFF192CB20A00085EB5 /* BITActivityIndicatorButton.h in Headers */,
8034E6961BA3214300D83A30 /* BITCategoryContainer.h in Headers */,
B2B2DB0A1FD9E47B00FB7FF2 /* BITHockeyHelper+Application.h in Headers */,
1E49A4BE161222B900463151 /* BITHockeyHelper.h in Headers */,
973EC8BB18BDE29800DBFFBB /* BITArrowImageAnnotation.h in Headers */,
1E49A4C4161222B900463151 /* BITAppStoreHeader.h in Headers */,
Expand Down Expand Up @@ -1432,6 +1440,7 @@
1EB617731B0A30E90035A986 /* BITAuthenticator.h in Headers */,
1EB617751B0A30F50035A986 /* BITCrashManager.h in Headers */,
8034E62C1BA31AD600D83A30 /* BITTelemetryData.h in Headers */,
B2B2DB0C1FD9E48000FB7FF2 /* BITHockeyHelper+Application.h in Headers */,
1EB6176D1B0A30CC0035A986 /* BITWebTableViewCell.h in Headers */,
8034E68A1BA31D7C00D83A30 /* BITUser.h in Headers */,
80668C751C8CD93B00A133D3 /* BITEventData.h in Headers */,
Expand Down Expand Up @@ -1842,6 +1851,7 @@
1EB92E741955C38C0093C8B6 /* BITHockeyAttachment.m in Sources */,
E48A3DED17B3ED1C00924C3D /* BITAuthenticator.m in Sources */,
1E49A4DB161222D400463151 /* HockeySDKPrivate.m in Sources */,
B2B2DB0B1FD9E47B00FB7FF2 /* BITHockeyHelper+Application.m in Sources */,
1E754E5D1621FBB70070AB92 /* BITCrashManager.m in Sources */,
1E754E611621FBB70070AB92 /* BITCrashReportTextFormatter.m in Sources */,
1EF95CA7162CB037000AE3AD /* BITFeedbackActivity.m in Sources */,
Expand Down