Skip to content

Commit 454342e

Browse files
authored
OneSignal Integration (#344)
This PR integrates OneSignal for both Android and iOS. Fixes #331 Note: For iOS, the OneSignal Notification Service Extension is only set up for the bundle ID `com.friend-app-with-wearable.ios12`. This means it won't work with the bundle ID `com.friend-app-with-wearable.ios12.dev` because this bundle ID isn't included in the Development Team. Steps to integrate OneSignal on iOS with xcode 15 or higher: OneSignal/OneSignal-Flutter-SDK#551 (comment) Android | iOS :-------------------------:|:-------------------------: ![Android](https://github.com/BasedHardware/Friend/assets/59914433/7c3a7acf-6f5d-43f0-a9ce-e51f1b3bde64) | ![iOS](https://github.com/BasedHardware/Friend/assets/59914433/6aa20bd5-5cf0-4287-9108-12ad01271be1)
2 parents 0eb6825 + fceb265 commit 454342e

17 files changed

+674
-10
lines changed

apps/AppWithWearable/.env.template

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
ONESIGNAL_APP_ID=
12
SENTRY_DSN_KEY=
23
OPENAI_API_KEY=
34
DEEPGRAM_API_KEY=
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>NSExtension</key>
6+
<dict>
7+
<key>NSExtensionPointIdentifier</key>
8+
<string>com.apple.usernotifications.service</string>
9+
<key>NSExtensionPrincipalClass</key>
10+
<string>$(PRODUCT_MODULE_NAME).NotificationService</string>
11+
</dict>
12+
</dict>
13+
</plist>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import UserNotifications
2+
3+
import OneSignalExtension
4+
5+
class NotificationService: UNNotificationServiceExtension {
6+
7+
var contentHandler: ((UNNotificationContent) -> Void)?
8+
var receivedRequest: UNNotificationRequest!
9+
var bestAttemptContent: UNMutableNotificationContent?
10+
11+
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
12+
self.receivedRequest = request
13+
self.contentHandler = contentHandler
14+
self.bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
15+
16+
if let bestAttemptContent = bestAttemptContent {
17+
/* DEBUGGING: Uncomment the 2 lines below to check this extension is executing
18+
Note, this extension only runs when mutable-content is set
19+
Setting an attachment or action buttons automatically adds this */
20+
// print("Running NotificationServiceExtension")
21+
// bestAttemptContent.body = "[Modified] " + bestAttemptContent.body
22+
23+
OneSignalExtension.didReceiveNotificationExtensionRequest(self.receivedRequest, with: bestAttemptContent, withContentHandler: self.contentHandler)
24+
}
25+
}
26+
27+
override func serviceExtensionTimeWillExpire() {
28+
// Called just before the extension will be terminated by the system.
29+
// Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
30+
if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent {
31+
OneSignalExtension.serviceExtensionTimeWillExpireRequest(self.receivedRequest, with: self.bestAttemptContent)
32+
contentHandler(bestAttemptContent)
33+
}
34+
}
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>com.apple.security.application-groups</key>
6+
<array>
7+
<string>group.com.friend-app-with-wearable.ios12.onesignal</string>
8+
</array>
9+
</dict>
10+
</plist>

apps/AppWithWearable/ios/Runner.xcodeproj/project.pbxproj

+564-10
Large diffs are not rendered by default.

apps/AppWithWearable/ios/Runner/Runner.entitlements

+4
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,9 @@
44
<dict>
55
<key>aps-environment</key>
66
<string>development</string>
7+
<key>com.apple.security.application-groups</key>
8+
<array>
9+
<string>group.com.friend-app-with-wearable.ios12.onesignal</string>
10+
</array>
711
</dict>
812
</plist>

apps/AppWithWearable/ios/Runner/RunnerDebug-dev.entitlements

+4
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,9 @@
44
<dict>
55
<key>aps-environment</key>
66
<string>development</string>
7+
<key>com.apple.security.application-groups</key>
8+
<array>
9+
<string>group.com.friend-app-with-wearable.ios12.onesignal</string>
10+
</array>
711
</dict>
812
</plist>

apps/AppWithWearable/ios/Runner/RunnerDebug-prod.entitlements

+4
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,9 @@
44
<dict>
55
<key>aps-environment</key>
66
<string>development</string>
7+
<key>com.apple.security.application-groups</key>
8+
<array>
9+
<string>group.com.friend-app-with-wearable.ios12.onesignal</string>
10+
</array>
711
</dict>
812
</plist>

apps/AppWithWearable/ios/Runner/RunnerProfile-dev.entitlements

+4
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,9 @@
44
<dict>
55
<key>aps-environment</key>
66
<string>development</string>
7+
<key>com.apple.security.application-groups</key>
8+
<array>
9+
<string>group.com.friend-app-with-wearable.ios12.onesignal</string>
10+
</array>
711
</dict>
812
</plist>

apps/AppWithWearable/ios/Runner/RunnerProfile-prod.entitlements

+4
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,9 @@
44
<dict>
55
<key>aps-environment</key>
66
<string>development</string>
7+
<key>com.apple.security.application-groups</key>
8+
<array>
9+
<string>group.com.friend-app-with-wearable.ios12.onesignal</string>
10+
</array>
711
</dict>
812
</plist>

apps/AppWithWearable/ios/Runner/RunnerRelease-dev.entitlements

+4
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,9 @@
44
<dict>
55
<key>aps-environment</key>
66
<string>development</string>
7+
<key>com.apple.security.application-groups</key>
8+
<array>
9+
<string>group.com.friend-app-with-wearable.ios12.onesignal</string>
10+
</array>
711
</dict>
812
</plist>

apps/AppWithWearable/ios/Runner/RunnerRelease-prod.entitlements

+4
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,9 @@
44
<dict>
55
<key>aps-environment</key>
66
<string>development</string>
7+
<key>com.apple.security.application-groups</key>
8+
<array>
9+
<string>group.com.friend-app-with-wearable.ios12.onesignal</string>
10+
</array>
711
</dict>
812
</plist>

apps/AppWithWearable/lib/env/dev_env.dart

+4
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ final class DevEnv implements EnvFields {
4141
final String? mixpanelProjectToken = _DevEnv.mixpanelProjectToken;
4242

4343
@override
44+
@EnviedField(varName: 'ONESIGNAL_APP_ID', obfuscate: true)
45+
final String? oneSignalAppId = _DevEnv.oneSignalAppId;
46+
47+
@override
4448
@EnviedField(varName: 'API_BASE_URL', obfuscate: true)
4549
final String? apiBaseUrl = _DevEnv.apiBaseUrl;
4650
}

apps/AppWithWearable/lib/env/env.dart

+4
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ abstract class Env {
77
_instance = instance ?? DevEnv();
88
}
99

10+
static String? get oneSignalAppId => _instance.oneSignalAppId;
11+
1012
static String? get sentryDSNKey => _instance.sentryDSNKey;
1113

1214
static String? get openAIAPIKey => _instance.openAIAPIKey;
@@ -27,6 +29,8 @@ abstract class Env {
2729
}
2830

2931
abstract class EnvFields {
32+
String? get oneSignalAppId;
33+
3034
String? get sentryDSNKey;
3135

3236
String? get openAIAPIKey;

apps/AppWithWearable/lib/env/prod_env.dart

+4
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ final class ProdEnv implements EnvFields {
4040
@EnviedField(varName: 'MIXPANEL_PROJECT_TOKEN', obfuscate: true)
4141
final String? mixpanelProjectToken = _ProdEnv.mixpanelProjectToken;
4242

43+
@override
44+
@EnviedField(varName: 'ONESIGNAL_APP_ID', obfuscate: true)
45+
final String? oneSignalAppId = _ProdEnv.oneSignalAppId;
46+
4347
@override
4448
@EnviedField(varName: 'API_BASE_URL', obfuscate: true)
4549
final String? apiBaseUrl = _ProdEnv.apiBaseUrl;

apps/AppWithWearable/lib/main.dart

+10
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import 'package:friend_private/pages/onboarding/welcome/page.dart';
1111
import 'package:friend_private/pages/onboarding/wrapper.dart';
1212
import 'package:friend_private/utils/notifications.dart';
1313
import 'package:instabug_flutter/instabug_flutter.dart';
14+
import 'package:onesignal_flutter/onesignal_flutter.dart';
1415

1516
import 'backend/preferences.dart';
1617
import 'env/env.dart';
@@ -22,6 +23,15 @@ void main() async {
2223
await SharedPreferencesUtil.init();
2324
await MixpanelManager.init();
2425
await ObjectBoxUtil.init();
26+
if (Env.oneSignalAppId != null) {
27+
OneSignal.Debug.setLogLevel(OSLogLevel.verbose);
28+
OneSignal.initialize(Env.oneSignalAppId!);
29+
var permissionGranted = await OneSignal.Notifications.requestPermission(true);
30+
if (permissionGranted) {
31+
OneSignal.login(SharedPreferencesUtil().uid);
32+
}
33+
}
34+
2535
if (Env.instabugApiKey != null) {
2636
runZonedGuarded(
2737
() {

apps/AppWithWearable/pubspec.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ dependencies:
9090
record_darwin: ^1.1.0
9191
flutter_sound: ^9.6.0
9292
audio_session: ^0.1.19
93+
onesignal_flutter: ^5.1.2
9394

9495
dependency_overrides:
9596
http: ^1.2.1

0 commit comments

Comments
 (0)