Skip to content

Commit

Permalink
Merge pull request #1132 from OneSignal/fix/xcode_14_warnings_and_bui…
Browse files Browse the repository at this point in the history
…ld_fail

Fix xcode 14 warnings and build failure
  • Loading branch information
emawby authored Oct 17, 2022
2 parents 80ab08d + 0102f9a commit 1f5ae96
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 74 deletions.
22 changes: 20 additions & 2 deletions iOS_SDK/OneSignalSDK/OneSignal.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -2701,7 +2701,6 @@
ALWAYS_SEARCH_USER_PATHS = NO;
ARCHS = (
"$(ARCHS_STANDARD)",
armv7s,
x86_64h,
x86_64,
);
Expand Down Expand Up @@ -2765,6 +2764,11 @@
CA2951B82167F4120064227A /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = (
"$(ARCHS_STANDARD)",
x86_64h,
x86_64,
);
CLANG_ANALYZER_NONNULL = YES;
CLANG_ENABLE_CODE_COVERAGE = NO;
CLANG_ENABLE_MODULES = YES;
Expand Down Expand Up @@ -2859,7 +2863,6 @@
ALWAYS_SEARCH_USER_PATHS = NO;
ARCHS = (
"$(ARCHS_STANDARD)",
armv7s,
x86_64h,
x86_64,
);
Expand Down Expand Up @@ -2923,6 +2926,11 @@
CA2951C42167FB950064227A /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = (
"$(ARCHS_STANDARD)",
x86_64h,
x86_64,
);
CLANG_ANALYZER_NONNULL = YES;
CLANG_ENABLE_CODE_COVERAGE = NO;
CLANG_ENABLE_MODULES = YES;
Expand Down Expand Up @@ -3016,6 +3024,11 @@
isa = XCBuildConfiguration;
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = YES;
ARCHS = (
"$(ARCHS_STANDARD)",
x86_64h,
x86_64,
);
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
Expand Down Expand Up @@ -3072,6 +3085,11 @@
isa = XCBuildConfiguration;
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = YES;
ARCHS = (
"$(ARCHS_STANDARD)",
x86_64h,
x86_64,
);
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
Expand Down
155 changes: 83 additions & 72 deletions iOS_SDK/OneSignalSDK/Source/OneSignalLocation.m
Original file line number Diff line number Diff line change
Expand Up @@ -200,81 +200,92 @@ + (void)sendCurrentAuthStatusToListeners {
}

+ (void)internalGetLocation:(bool)prompt fallbackToSettings:(BOOL)fallback {
fallbackToSettings = fallback;
id clLocationManagerClass = NSClassFromString(@"CLLocationManager");

// On the application init we are always calling this method
// If location permissions was not asked "started" will never be true
if ([self started]) {
// We evaluate the following cases after permissions were asked (denied or given)
CLAuthorizationStatus permissionStatus = [clLocationManagerClass performSelector:@selector(authorizationStatus)];
BOOL showSettings = prompt && fallback && permissionStatus == kCLAuthorizationStatusDenied;
[OneSignal onesignalLog:ONE_S_LL_DEBUG message:[NSString stringWithFormat:@"internalGetLocation called showSettings: %@", showSettings ? @"YES" : @"NO"]];
// Fallback to settings alert view when the following condition are true:
// - On a prompt flow
// - Fallback to settings is enabled
// - Permission were denied
if (showSettings)
[self showLocationSettingsAlertController];
else
[self sendCurrentAuthStatusToListeners];
return;
}

// Check for location in plist
if (![clLocationManagerClass performSelector:@selector(locationServicesEnabled)]) {
[OneSignal onesignalLog:ONE_S_LL_DEBUG message:@"CLLocationManager locationServices Disabled."];
[self sendAndClearLocationListener:ERROR];
return;
}

CLAuthorizationStatus permissionStatus = [clLocationManagerClass performSelector:@selector(authorizationStatus)];
// return if permission not determined and should not prompt
if (permissionStatus == kCLAuthorizationStatusNotDetermined && !prompt) {
[OneSignal onesignalLog:ONE_S_LL_DEBUG message:@"internalGetLocation kCLAuthorizationStatusNotDetermined."];
return;
}

[self sendCurrentAuthStatusToListeners];
locationManager = [[clLocationManagerClass alloc] init];
[locationManager setValue:[self sharedInstance] forKey:@"delegate"];

/*
Do permission checking on a background thread to resolve locationServicesEnabled warning.
*/
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
fallbackToSettings = fallback;
id clLocationManagerClass = NSClassFromString(@"CLLocationManager");

//Check info plist for request descriptions
//LocationAlways > LocationWhenInUse > No entry (Log error)
//Location Always requires: Location Background Mode + NSLocationAlwaysUsageDescription
NSArray* backgroundModes = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"UIBackgroundModes"];
NSString* alwaysDescription = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationAlwaysUsageDescription"] ?: [[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationAlwaysAndWhenInUseUsageDescription"];
// use background location updates if always permission granted or prompt allowed
BOOL backgroundLocationEnable = backgroundModes && [backgroundModes containsObject:@"location"] && alwaysDescription;
BOOL permissionEnable = permissionStatus == kCLAuthorizationStatusAuthorizedAlways || prompt;

[OneSignal onesignalLog:ONE_S_LL_DEBUG message:[NSString stringWithFormat:@"internalGetLocation called backgroundLocationEnable: %@ permissionEnable: %@", backgroundLocationEnable ? @"YES" : @"NO", permissionEnable ? @"YES" : @"NO"]];

if (backgroundLocationEnable && permissionEnable) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
[locationManager performSelector:NSSelectorFromString(@"requestAlwaysAuthorization")];
#pragma clang diagnostic pop
if ([OneSignalHelper isIOSVersionGreaterThanOrEqual:@"9.0"])
[locationManager setValue:@YES forKey:@"allowsBackgroundLocationUpdates"];
}

else if ([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationWhenInUseUsageDescription"]) {
if (permissionStatus == kCLAuthorizationStatusNotDetermined)
[locationManager performSelector:@selector(requestWhenInUseAuthorization)];
}

else {
[OneSignal onesignalLog:ONE_S_LL_ERROR message:@"Include a privacy NSLocationAlwaysUsageDescription or NSLocationWhenInUseUsageDescription in your info.plist to request location permissions."];
[self sendAndClearLocationListener:LOCATION_PERMISSIONS_MISSING_INFO_PLIST];
}
// On the application init we are always calling this method
// If location permissions was not asked "started" will never be true
if ([self started]) {
// We evaluate the following cases after permissions were asked (denied or given)
CLAuthorizationStatus permissionStatus = [clLocationManagerClass performSelector:@selector(authorizationStatus)];
BOOL showSettings = prompt && fallback && permissionStatus == kCLAuthorizationStatusDenied;
[OneSignal onesignalLog:ONE_S_LL_DEBUG message:[NSString stringWithFormat:@"internalGetLocation called showSettings: %@", showSettings ? @"YES" : @"NO"]];
// Fallback to settings alert view when the following condition are true:
// - On a prompt flow
// - Fallback to settings is enabled
// - Permission were denied
if (showSettings)
[self showLocationSettingsAlertController];
else
[self sendCurrentAuthStatusToListeners];
return;
}

// This method is used for getting the location manager to obtain an initial location fix
// and will notify your delegate by calling its locationManager:didUpdateLocations: method
[locationManager performSelector:@selector(startUpdatingLocation)];
// Check for location in plist
if (![clLocationManagerClass performSelector:@selector(locationServicesEnabled)]) {
[OneSignal onesignalLog:ONE_S_LL_DEBUG message:@"CLLocationManager locationServices Disabled."];
[self sendAndClearLocationListener:ERROR];
return;
}

CLAuthorizationStatus permissionStatus = [clLocationManagerClass performSelector:@selector(authorizationStatus)];
// return if permission not determined and should not prompt
if (permissionStatus == kCLAuthorizationStatusNotDetermined && !prompt) {
[OneSignal onesignalLog:ONE_S_LL_DEBUG message:@"internalGetLocation kCLAuthorizationStatusNotDetermined."];
return;
}

[self sendCurrentAuthStatusToListeners];
/*
The location manager must be created on a thread with a run loop so we will go back to the main thread.
*/
dispatch_async(dispatch_get_main_queue(), ^{
locationManager = [[clLocationManagerClass alloc] init];
[locationManager setValue:[self sharedInstance] forKey:@"delegate"];


//Check info plist for request descriptions
//LocationAlways > LocationWhenInUse > No entry (Log error)
//Location Always requires: Location Background Mode + NSLocationAlwaysUsageDescription
NSArray* backgroundModes = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"UIBackgroundModes"];
NSString* alwaysDescription = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationAlwaysUsageDescription"] ?: [[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationAlwaysAndWhenInUseUsageDescription"];
// use background location updates if always permission granted or prompt allowed
BOOL backgroundLocationEnable = backgroundModes && [backgroundModes containsObject:@"location"] && alwaysDescription;
BOOL permissionEnable = permissionStatus == kCLAuthorizationStatusAuthorizedAlways || prompt;

[OneSignal onesignalLog:ONE_S_LL_DEBUG message:[NSString stringWithFormat:@"internalGetLocation called backgroundLocationEnable: %@ permissionEnable: %@", backgroundLocationEnable ? @"YES" : @"NO", permissionEnable ? @"YES" : @"NO"]];

if (backgroundLocationEnable && permissionEnable) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
[locationManager performSelector:NSSelectorFromString(@"requestAlwaysAuthorization")];
#pragma clang diagnostic pop
if ([OneSignalHelper isIOSVersionGreaterThanOrEqual:@"9.0"])
[locationManager setValue:@YES forKey:@"allowsBackgroundLocationUpdates"];
}

else if ([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationWhenInUseUsageDescription"]) {
if (permissionStatus == kCLAuthorizationStatusNotDetermined)
[locationManager performSelector:@selector(requestWhenInUseAuthorization)];
}

else {
[OneSignal onesignalLog:ONE_S_LL_ERROR message:@"Include a privacy NSLocationAlwaysUsageDescription or NSLocationWhenInUseUsageDescription in your info.plist to request location permissions."];
[self sendAndClearLocationListener:LOCATION_PERMISSIONS_MISSING_INFO_PLIST];
}

// This method is used for getting the location manager to obtain an initial location fix
// and will notify your delegate by calling its locationManager:didUpdateLocations: method

[locationManager performSelector:@selector(startUpdatingLocation)];
started = true;
});
});

started = true;
}

+ (void)showLocationSettingsAlertController {
Expand Down
3 changes: 3 additions & 0 deletions iOS_SDK/OneSignalSDK/UnitTests/RemoteParamsTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ - (void)testLocationPromptAcceptedWithSetLocationShared_iOS9_WhenInUseUsage {
[OneSignal setLocationShared:true];
// Simulate user granting location services
[OneSignalLocationOverrider grantLocationServices];
[UnitTestCommonMethods runLongBackgroundThreads];
// Last location should exist since we are sharing location
XCTAssertTrue([OneSignalLocation lastLocation]);
}
Expand All @@ -108,6 +109,7 @@ - (void)testLocationPromptAcceptedWithSetLocationSharedTrueFromRemoteParams_iOS9
XCTAssertFalse([OneSignalLocation lastLocation]);
// Simulate user granting location services
[OneSignalLocationOverrider grantLocationServices];
[UnitTestCommonMethods runLongBackgroundThreads];
// Last location should exist since we are sharing location
XCTAssertTrue([OneSignalLocation lastLocation]);
}
Expand Down Expand Up @@ -144,6 +146,7 @@ - (void)testLocationSharedTrueFromRemoteParams {
XCTAssertFalse([OneSignalLocation lastLocation]);
// Simulate user granting location services
[OneSignalLocationOverrider grantLocationServices];
[UnitTestCommonMethods runLongBackgroundThreads];
// Last location should exist since we are sharing location
XCTAssertTrue([OneSignalLocation lastLocation]);
}
Expand Down

0 comments on commit 1f5ae96

Please sign in to comment.