Skip to content

Commit 4970aa5

Browse files
feat: [SDK-4775] add location opt-out support (#184)
Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent a622e1d commit 4970aa5

35 files changed

Lines changed: 1060 additions & 92 deletions

OneSignalSDK.DotNet.Android/AndroidLocationManager.cs

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,67 @@
1-
using OneSignalSDK.DotNet.Core;
1+
using System.Runtime.CompilerServices;
2+
using OneSignalSDK.DotNet.Core;
23
using OneSignalSDK.DotNet.Core.Location;
34
using OneSignalNative = Com.OneSignal.Android.OneSignal;
45

56
namespace OneSignalSDK.DotNet.Android;
67

78
public class AndroidLocationManager : ILocationManager
89
{
10+
private const string LocationModuleNotAvailable =
11+
"OneSignal.Location call failed. The location module may not be included in this build.";
12+
913
public bool IsShared
1014
{
11-
get => OneSignalNative.Location.Shared;
12-
set => OneSignalNative.Location.Shared = value;
15+
get
16+
{
17+
try
18+
{
19+
return GetShared();
20+
}
21+
catch (Exception exception)
22+
{
23+
LogLocationModuleNotAvailable(exception);
24+
return false;
25+
}
26+
}
27+
set
28+
{
29+
try
30+
{
31+
SetShared(value);
32+
}
33+
catch (Exception exception)
34+
{
35+
LogLocationModuleNotAvailable(exception);
36+
}
37+
}
1338
}
1439

1540
public void RequestPermission()
41+
{
42+
try
43+
{
44+
RequestNativePermission();
45+
}
46+
catch (Exception exception)
47+
{
48+
LogLocationModuleNotAvailable(exception);
49+
}
50+
}
51+
52+
private static void LogLocationModuleNotAvailable(Exception exception)
53+
{
54+
global::Android.Util.Log.Error("OneSignal", $"{LocationModuleNotAvailable} {exception}");
55+
}
56+
57+
[MethodImpl(MethodImplOptions.NoInlining)]
58+
private static bool GetShared() => OneSignalNative.Location.Shared;
59+
60+
[MethodImpl(MethodImplOptions.NoInlining)]
61+
private static void SetShared(bool shared) => OneSignalNative.Location.Shared = shared;
62+
63+
[MethodImpl(MethodImplOptions.NoInlining)]
64+
private static void RequestNativePermission()
1665
{
1766
var consumer = new AndroidBoolConsumer();
1867
OneSignalNative.Location.RequestPermission(Com.OneSignal.Android.Continue.With(consumer));

OneSignalSDK.DotNet.Android/OneSignalSDK.DotNet.Android.csproj

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,10 @@
4444
<ProjectReference Include="..\OneSignalSDK.DotNet.Android.InAppMessages.Binding\OneSignalSDK.DotNet.Android.InAppMessages.Binding.csproj">
4545
<ReferenceSourceTarget>ProjectReference</ReferenceSourceTarget>
4646
</ProjectReference>
47-
<ProjectReference Include="..\OneSignalSDK.DotNet.Android.Location.Binding\OneSignalSDK.DotNet.Android.Location.Binding.csproj">
47+
<ProjectReference
48+
Include="..\OneSignalSDK.DotNet.Android.Location.Binding\OneSignalSDK.DotNet.Android.Location.Binding.csproj"
49+
Condition="'$(OneSignalDisableLocation)' != 'true'"
50+
>
4851
<ReferenceSourceTarget>ProjectReference</ReferenceSourceTarget>
4952
</ProjectReference>
5053
<ProjectReference Include="..\OneSignalSDK.DotNet.Android.Notifications.Binding\OneSignalSDK.DotNet.Android.Notifications.Binding.csproj">

OneSignalSDK.DotNet.iOS.Binding/OneSignalSDK.DotNet.iOS.Binding.csproj

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,10 @@
8585
<ForceLoad>True</ForceLoad>
8686
<Frameworks>OneSignalCore OneSignalNotifications OneSignalOSCore</Frameworks>
8787
</NativeReference>
88-
<NativeReference Include="OneSignalLocation.xcframework">
88+
<NativeReference
89+
Include="OneSignalLocation.xcframework"
90+
Condition="'$(OneSignalDisableLocation)' != 'true'"
91+
>
8992
<Kind>Framework</Kind>
9093
<SmartLink>False</SmartLink>
9194
<ForceLoad>True</ForceLoad>

OneSignalSDK.DotNet.iOS.Binding/OneSignalSDK.dotnet.targets

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,10 @@
4343
<ForceLoad>True</ForceLoad>
4444
<Frameworks>OneSignalCore OneSignalNotifications OneSignalOSCore</Frameworks>
4545
</NativeReference>
46-
<NativeReference Include="$(MSBuildThisFileDirectory)../../res/ios/OneSignalLocation.xcframework">
46+
<NativeReference
47+
Include="$(MSBuildThisFileDirectory)../../res/ios/OneSignalLocation.xcframework"
48+
Condition="'$(OneSignalDisableLocation)' != 'true'"
49+
>
4750
<Kind>Framework</Kind>
4851
<SmartLink>False</SmartLink>
4952
<ForceLoad>True</ForceLoad>
Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,65 @@
1-
using OneSignalSDK.DotNet.Core;
1+
using System.Runtime.CompilerServices;
2+
using OneSignalSDK.DotNet.Core;
23
using OneSignalSDK.DotNet.Core.Location;
34
using OneSignalNative = Com.OneSignal.iOS.OneSignal;
45

56
namespace OneSignalSDK.DotNet.iOS;
67

78
public class iOSLocationManager : ILocationManager
89
{
10+
private const string LocationModuleNotAvailable =
11+
"OneSignal.Location call failed. The location module may not be included in this build.";
12+
913
public bool IsShared
1014
{
11-
get => OneSignalNative.Location.IsShared;
12-
set => OneSignalNative.Location.SetShared(value);
15+
get
16+
{
17+
try
18+
{
19+
return GetShared();
20+
}
21+
catch (Exception exception)
22+
{
23+
LogLocationModuleNotAvailable(exception);
24+
return false;
25+
}
26+
}
27+
set
28+
{
29+
try
30+
{
31+
SetShared(value);
32+
}
33+
catch (Exception exception)
34+
{
35+
LogLocationModuleNotAvailable(exception);
36+
}
37+
}
1338
}
1439

1540
public void RequestPermission()
1641
{
17-
OneSignalNative.Location.RequestPermission();
42+
try
43+
{
44+
RequestNativePermission();
45+
}
46+
catch (Exception exception)
47+
{
48+
LogLocationModuleNotAvailable(exception);
49+
}
50+
}
51+
52+
private static void LogLocationModuleNotAvailable(Exception exception)
53+
{
54+
Console.Error.WriteLine($"{LocationModuleNotAvailable} {exception}");
1855
}
56+
57+
[MethodImpl(MethodImplOptions.NoInlining)]
58+
private static bool GetShared() => OneSignalNative.Location.IsShared;
59+
60+
[MethodImpl(MethodImplOptions.NoInlining)]
61+
private static void SetShared(bool shared) => OneSignalNative.Location.SetShared(shared);
62+
63+
[MethodImpl(MethodImplOptions.NoInlining)]
64+
private static void RequestNativePermission() => OneSignalNative.Location.RequestPermission();
1965
}

OneSignalSDK.DotNet.nuspec

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,5 +99,8 @@
9999
<!-- This is a .target files that gets used by project that consumes the NuGet package.
100100
This copies out the OneSignal.xcframework from the resources folder and adds a NativeReference to it in the app project. -->
101101
<file src="OneSignalSDK.DotNet.iOS.Binding\OneSignalSDK.DotNet.targets" target="build\net10.0-ios12.2\" />
102+
103+
<!-- Removes optional Android location assets when OneSignalDisableLocation=true. -->
104+
<file src="OneSignalSDK.DotNet\OneSignalSDK.DotNet.Android.targets" target="build\net10.0-android21.0\OneSignalSDK.DotNet.targets" />
102105
</files>
103106
</package>
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
2+
<Target
3+
Name="OneSignalRemoveAndroidLocationAssets"
4+
AfterTargets="ResolvePackageAssets"
5+
BeforeTargets="ResolveReferences;_ResolveLibraryProjectImports"
6+
Condition="'$(OneSignalDisableLocation)' == 'true'"
7+
>
8+
<ItemGroup>
9+
<Reference
10+
Remove="@(Reference)"
11+
Condition="'%(Reference.Filename)' == 'OneSignalSDK.DotNet.Android.Location.Binding'"
12+
/>
13+
<ReferencePath
14+
Remove="@(ReferencePath)"
15+
Condition="'%(ReferencePath.Filename)' == 'OneSignalSDK.DotNet.Android.Location.Binding'"
16+
/>
17+
<ReferenceCopyLocalPaths
18+
Remove="@(ReferenceCopyLocalPaths)"
19+
Condition="'%(ReferenceCopyLocalPaths.Filename)' == 'OneSignalSDK.DotNet.Android.Location.Binding'"
20+
/>
21+
<AndroidLibrary
22+
Remove="@(AndroidLibrary)"
23+
Condition="'%(AndroidLibrary.Filename)%(AndroidLibrary.Extension)' == 'location-release.aar'"
24+
/>
25+
<AndroidAarLibrary
26+
Remove="@(AndroidAarLibrary)"
27+
Condition="'%(AndroidAarLibrary.Filename)%(AndroidAarLibrary.Extension)' == 'location-release.aar'"
28+
/>
29+
</ItemGroup>
30+
</Target>
31+
</Project>

README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,29 @@ Xamarin projects: See the [Setup Documentation](https://documentation.onesignal.
3535

3636
See OneSignal's [.NET SDK API](https://documentation.onesignal.com/docs/net-client-sdk) page for a list of all available methods.
3737

38+
#### Disable Location Module
39+
40+
By default, `OneSignalSDK.DotNet` includes OneSignal's native location module so `OneSignal.Location` works without extra setup. If your app does not use location features, you can exclude the native location module from iOS and Android builds with an MSBuild property in your app project:
41+
42+
```xml
43+
<PropertyGroup>
44+
<OneSignalDisableLocation>true</OneSignalDisableLocation>
45+
</PropertyGroup>
46+
```
47+
48+
When disabled, `OneSignal.Location.RequestPermission()` and `OneSignal.Location.IsShared = value` no-op on native builds without the location module, and `OneSignal.Location.IsShared` returns `false`.
49+
50+
For regular development, make sure the property is set for the app build that consumes the SDK. If you are building from source with project references or scripts, pass the property to the `dotnet build` command so it applies to the referenced SDK projects too:
51+
52+
```sh
53+
dotnet build -f net10.0-ios -p:OneSignalDisableLocation=true
54+
dotnet build -f net10.0-android -p:OneSignalDisableLocation=true
55+
```
56+
57+
In CI, include the `OneSignalDisableLocation` value in build cache keys, or clean build outputs when toggling it. This avoids restoring stale iOS app bundles, Android intermediates, or `bin`/`obj` outputs that were produced with the location module enabled.
58+
59+
This is an MSBuild-only setting; Gradle properties are not supported for disabling the .NET SDK location module.
60+
3861
#### Change Log
3962

4063
See this repository's [release tags](https://github.com/OneSignal/OneSignal-DotNet-SDK/releases) for a complete change log of every released version.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ONESIGNAL_APP_ID=your-onesignal-app-id

examples/demo-no-location/App.xaml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<Application
3+
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
4+
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
5+
x:Class="OneSignalDemoNoLocation.App"
6+
>
7+
<Application.Resources>
8+
<ResourceDictionary>
9+
<ResourceDictionary.MergedDictionaries>
10+
<ResourceDictionary Source="Resources/Styles/Colors.xaml" />
11+
<ResourceDictionary Source="Resources/Styles/Styles.xaml" />
12+
</ResourceDictionary.MergedDictionaries>
13+
</ResourceDictionary>
14+
</Application.Resources>
15+
</Application>

0 commit comments

Comments
 (0)