diff --git a/ios/OneSignalNotificationServiceExtension/Info.plist b/ios/OneSignalNotificationServiceExtension/Info.plist
new file mode 100644
index 0000000..57421eb
--- /dev/null
+++ b/ios/OneSignalNotificationServiceExtension/Info.plist
@@ -0,0 +1,13 @@
+
+
+
+
+ NSExtension
+
+ NSExtensionPointIdentifier
+ com.apple.usernotifications.service
+ NSExtensionPrincipalClass
+ $(PRODUCT_MODULE_NAME).NotificationService
+
+
+
diff --git a/ios/OneSignalNotificationServiceExtension/NotificationService.swift b/ios/OneSignalNotificationServiceExtension/NotificationService.swift
new file mode 100644
index 0000000..ab391a3
--- /dev/null
+++ b/ios/OneSignalNotificationServiceExtension/NotificationService.swift
@@ -0,0 +1,32 @@
+import UserNotifications
+import OneSignalExtension
+
+class NotificationService: UNNotificationServiceExtension {
+ var contentHandler: ((UNNotificationContent) -> Void)?
+ var receivedRequest: UNNotificationRequest!
+ var bestAttemptContent: UNMutableNotificationContent?
+
+ // Note this extension only runs when `mutable_content` is set
+ // Setting an attachment or action buttons automatically sets the property to true
+ override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
+ self.receivedRequest = request
+ self.contentHandler = contentHandler
+ self.bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
+
+ if let bestAttemptContent = bestAttemptContent {
+ // DEBUGGING: Uncomment the 2 lines below to check this extension is executing
+// print("Running NotificationServiceExtension")
+// bestAttemptContent.body = "[Modified] " + bestAttemptContent.body
+
+ OneSignalExtension.didReceiveNotificationExtensionRequest(self.receivedRequest, with: bestAttemptContent, withContentHandler: self.contentHandler)
+ }
+ }
+
+ override func serviceExtensionTimeWillExpire() {
+ // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
+ if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent {
+ OneSignalExtension.serviceExtensionTimeWillExpireRequest(self.receivedRequest, with: self.bestAttemptContent)
+ contentHandler(bestAttemptContent)
+ }
+ }
+}
diff --git a/ios/OneSignalNotificationServiceExtension/OneSignalNotificationServiceExtension.entitlements b/ios/OneSignalNotificationServiceExtension/OneSignalNotificationServiceExtension.entitlements
new file mode 100644
index 0000000..675953d
--- /dev/null
+++ b/ios/OneSignalNotificationServiceExtension/OneSignalNotificationServiceExtension.entitlements
@@ -0,0 +1,12 @@
+
+
+
+
+ aps-environment
+ development
+ com.apple.security.application-groups
+
+ group.com.dbiz.partner.onesignal
+
+
+
diff --git a/ios/Podfile b/ios/Podfile
index 620e46e..ead9595 100644
--- a/ios/Podfile
+++ b/ios/Podfile
@@ -1,5 +1,5 @@
# Uncomment this line to define a global platform for your project
-# platform :ios, '13.0'
+platform :ios, '13.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
@@ -36,8 +36,19 @@ target 'Runner' do
end
end
+# OneSignal Notification Service Extension (OUTSIDE Runner target)
+target 'OneSignalNotificationServiceExtension' do
+ use_frameworks!
+ pod 'OneSignalXCFramework', '>= 5.0.0', '< 6.0'
+end
+
post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
+
+ # Ensure consistent deployment target
+ target.build_configurations.each do |config|
+ config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '13.0'
+ end
end
-end
+end
\ No newline at end of file
diff --git a/ios/Podfile.lock b/ios/Podfile.lock
index d465686..fdfbbf4 100644
--- a/ios/Podfile.lock
+++ b/ios/Podfile.lock
@@ -94,6 +94,55 @@ PODS:
- nanopb/encode (= 2.30910.0)
- nanopb/decode (2.30910.0)
- nanopb/encode (2.30910.0)
+ - onesignal_flutter (5.3.4):
+ - Flutter
+ - OneSignalXCFramework (= 5.2.14)
+ - OneSignalXCFramework (5.2.14):
+ - OneSignalXCFramework/OneSignalComplete (= 5.2.14)
+ - OneSignalXCFramework/OneSignal (5.2.14):
+ - OneSignalXCFramework/OneSignalCore
+ - OneSignalXCFramework/OneSignalExtension
+ - OneSignalXCFramework/OneSignalLiveActivities
+ - OneSignalXCFramework/OneSignalNotifications
+ - OneSignalXCFramework/OneSignalOSCore
+ - OneSignalXCFramework/OneSignalOutcomes
+ - OneSignalXCFramework/OneSignalUser
+ - OneSignalXCFramework/OneSignalComplete (5.2.14):
+ - OneSignalXCFramework/OneSignal
+ - OneSignalXCFramework/OneSignalInAppMessages
+ - OneSignalXCFramework/OneSignalLocation
+ - OneSignalXCFramework/OneSignalCore (5.2.14)
+ - OneSignalXCFramework/OneSignalExtension (5.2.14):
+ - OneSignalXCFramework/OneSignalCore
+ - OneSignalXCFramework/OneSignalOutcomes
+ - OneSignalXCFramework/OneSignalInAppMessages (5.2.14):
+ - OneSignalXCFramework/OneSignalCore
+ - OneSignalXCFramework/OneSignalNotifications
+ - OneSignalXCFramework/OneSignalOSCore
+ - OneSignalXCFramework/OneSignalOutcomes
+ - OneSignalXCFramework/OneSignalUser
+ - OneSignalXCFramework/OneSignalLiveActivities (5.2.14):
+ - OneSignalXCFramework/OneSignalCore
+ - OneSignalXCFramework/OneSignalOSCore
+ - OneSignalXCFramework/OneSignalUser
+ - OneSignalXCFramework/OneSignalLocation (5.2.14):
+ - OneSignalXCFramework/OneSignalCore
+ - OneSignalXCFramework/OneSignalNotifications
+ - OneSignalXCFramework/OneSignalOSCore
+ - OneSignalXCFramework/OneSignalUser
+ - OneSignalXCFramework/OneSignalNotifications (5.2.14):
+ - OneSignalXCFramework/OneSignalCore
+ - OneSignalXCFramework/OneSignalExtension
+ - OneSignalXCFramework/OneSignalOutcomes
+ - OneSignalXCFramework/OneSignalOSCore (5.2.14):
+ - OneSignalXCFramework/OneSignalCore
+ - OneSignalXCFramework/OneSignalOutcomes (5.2.14):
+ - OneSignalXCFramework/OneSignalCore
+ - OneSignalXCFramework/OneSignalUser (5.2.14):
+ - OneSignalXCFramework/OneSignalCore
+ - OneSignalXCFramework/OneSignalNotifications
+ - OneSignalXCFramework/OneSignalOSCore
+ - OneSignalXCFramework/OneSignalOutcomes
- open_file_ios (0.0.1):
- Flutter
- path_provider_foundation (0.0.1):
@@ -123,6 +172,8 @@ DEPENDENCIES:
- image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`)
- integration_test (from `.symlinks/plugins/integration_test/ios`)
- mobile_scanner (from `.symlinks/plugins/mobile_scanner/ios`)
+ - onesignal_flutter (from `.symlinks/plugins/onesignal_flutter/ios`)
+ - OneSignalXCFramework (< 6.0, >= 5.0.0)
- open_file_ios (from `.symlinks/plugins/open_file_ios/ios`)
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
- share_plus (from `.symlinks/plugins/share_plus/ios`)
@@ -145,6 +196,7 @@ SPEC REPOS:
- MLKitCommon
- MLKitVision
- nanopb
+ - OneSignalXCFramework
- PromisesObjC
- SDWebImage
- SwiftyGif
@@ -164,6 +216,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/integration_test/ios"
mobile_scanner:
:path: ".symlinks/plugins/mobile_scanner/ios"
+ onesignal_flutter:
+ :path: ".symlinks/plugins/onesignal_flutter/ios"
open_file_ios:
:path: ".symlinks/plugins/open_file_ios/ios"
path_provider_foundation:
@@ -198,6 +252,8 @@ SPEC CHECKSUMS:
MLKitVision: e858c5f125ecc288e4a31127928301eaba9ae0c1
mobile_scanner: 96e91f2e1fb396bb7df8da40429ba8dfad664740
nanopb: 438bc412db1928dac798aa6fd75726007be04262
+ onesignal_flutter: f69ff09eeaf41cea4b7a841de5a61e79e7fd9a5a
+ OneSignalXCFramework: 7112f3e89563e41ebc23fe807788f11985ac541c
open_file_ios: 461db5853723763573e140de3193656f91990d9e
path_provider_foundation: 0b743cbb62d8e47eab856f09262bb8c1ddcfe6ba
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
@@ -208,6 +264,6 @@ SPEC CHECKSUMS:
SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4
url_launcher_ios: bb13df5870e8c4234ca12609d04010a21be43dfa
-PODFILE CHECKSUM: 3c63482e143d1b91d2d2560aee9fb04ecc74ac7e
+PODFILE CHECKSUM: 41022e80ca79dfdcc337fcf6a6cca3b7d3cb6958
COCOAPODS: 1.16.2
diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj
index 50c9196..9d171f5 100644
--- a/ios/Runner.xcodeproj/project.pbxproj
+++ b/ios/Runner.xcodeproj/project.pbxproj
@@ -10,12 +10,14 @@
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
+ 48D410762ED7067500A8B931 /* OneSignalNotificationServiceExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 48D4106F2ED7067500A8B931 /* OneSignalNotificationServiceExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
58215889146B2DBBD9C81410 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2545A56CA7C5FCC88F0D6DF7 /* Pods_Runner.framework */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
AB1F84BC849C548E4DA2D9A4 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 23D173C6FEE4F53025C06238 /* Pods_RunnerTests.framework */; };
+ E88379F7C7DF9A2FA2741EC2 /* Pods_OneSignalNotificationServiceExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FC689749C1B738DA836BE8F2 /* Pods_OneSignalNotificationServiceExtension.framework */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -26,9 +28,27 @@
remoteGlobalIDString = 97C146ED1CF9000F007C117D;
remoteInfo = Runner;
};
+ 48D410742ED7067500A8B931 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 97C146E61CF9000F007C117D /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 48D4106E2ED7067500A8B931;
+ remoteInfo = OneSignalNotificationServiceExtension;
+ };
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
+ 48D4107C2ED7067500A8B931 /* Embed Foundation Extensions */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "";
+ dstSubfolderSpec = 13;
+ files = (
+ 48D410762ED7067500A8B931 /* OneSignalNotificationServiceExtension.appex in Embed Foundation Extensions */,
+ );
+ name = "Embed Foundation Extensions";
+ runOnlyForDeploymentPostprocessing = 0;
+ };
9705A1C41CF9048500538489 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
@@ -43,6 +63,7 @@
/* Begin PBXFileReference section */
01651DC8E3A322D39483596C /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; };
+ 055EB8AF0F56FE3029E6507E /* Pods-OneSignalNotificationServiceExtension.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OneSignalNotificationServiceExtension.release.xcconfig"; path = "Target Support Files/Pods-OneSignalNotificationServiceExtension/Pods-OneSignalNotificationServiceExtension.release.xcconfig"; sourceTree = ""; };
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; };
18121E1016DEC4038E74F1F0 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; };
@@ -51,6 +72,10 @@
331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; };
331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; };
+ 4720F73E5117230A69E1B4A0 /* Pods-OneSignalNotificationServiceExtension.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OneSignalNotificationServiceExtension.profile.xcconfig"; path = "Target Support Files/Pods-OneSignalNotificationServiceExtension/Pods-OneSignalNotificationServiceExtension.profile.xcconfig"; sourceTree = ""; };
+ 48D4106A2ED7062D00A8B931 /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = ""; };
+ 48D4106F2ED7067500A8B931 /* OneSignalNotificationServiceExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = OneSignalNotificationServiceExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
+ 5B101E50F7EDE4E6F1714DD8 /* Pods-OneSignalNotificationServiceExtension.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OneSignalNotificationServiceExtension.debug.xcconfig"; path = "Target Support Files/Pods-OneSignalNotificationServiceExtension/Pods-OneSignalNotificationServiceExtension.debug.xcconfig"; sourceTree = ""; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; };
@@ -65,9 +90,43 @@
A2165E7BD4BCB2253391F0B0 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; };
B234409A1C87269651420659 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; };
C436CF2D08FCD6AFF7811DE0 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; };
+ FC689749C1B738DA836BE8F2 /* Pods_OneSignalNotificationServiceExtension.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_OneSignalNotificationServiceExtension.framework; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
+/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */
+ 48D410772ED7067500A8B931 /* Exceptions for "OneSignalNotificationServiceExtension" folder in "OneSignalNotificationServiceExtension" target */ = {
+ isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
+ membershipExceptions = (
+ Info.plist,
+ );
+ target = 48D4106E2ED7067500A8B931 /* OneSignalNotificationServiceExtension */;
+ };
+/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */
+
+/* Begin PBXFileSystemSynchronizedRootGroup section */
+ 48D410702ED7067500A8B931 /* OneSignalNotificationServiceExtension */ = {
+ isa = PBXFileSystemSynchronizedRootGroup;
+ exceptions = (
+ 48D410772ED7067500A8B931 /* Exceptions for "OneSignalNotificationServiceExtension" folder in "OneSignalNotificationServiceExtension" target */,
+ );
+ explicitFileTypes = {
+ };
+ explicitFolders = (
+ );
+ path = OneSignalNotificationServiceExtension;
+ sourceTree = "";
+ };
+/* End PBXFileSystemSynchronizedRootGroup section */
+
/* Begin PBXFrameworksBuildPhase section */
+ 48D4106C2ED7067500A8B931 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ E88379F7C7DF9A2FA2741EC2 /* Pods_OneSignalNotificationServiceExtension.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
61A54C58DE898B1B550583E8 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@@ -111,6 +170,7 @@
children = (
9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */,
+ 48D410702ED7067500A8B931 /* OneSignalNotificationServiceExtension */,
97C146EF1CF9000F007C117D /* Products */,
331C8082294A63A400263BE5 /* RunnerTests */,
D39C332D04678D8C49EEA401 /* Pods */,
@@ -123,6 +183,7 @@
children = (
97C146EE1CF9000F007C117D /* Runner.app */,
331C8081294A63A400263BE5 /* RunnerTests.xctest */,
+ 48D4106F2ED7067500A8B931 /* OneSignalNotificationServiceExtension.appex */,
);
name = Products;
sourceTree = "";
@@ -130,6 +191,7 @@
97C146F01CF9000F007C117D /* Runner */ = {
isa = PBXGroup;
children = (
+ 48D4106A2ED7062D00A8B931 /* Runner.entitlements */,
97C146FA1CF9000F007C117D /* Main.storyboard */,
97C146FD1CF9000F007C117D /* Assets.xcassets */,
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
@@ -151,6 +213,9 @@
C436CF2D08FCD6AFF7811DE0 /* Pods-RunnerTests.debug.xcconfig */,
01651DC8E3A322D39483596C /* Pods-RunnerTests.release.xcconfig */,
18121E1016DEC4038E74F1F0 /* Pods-RunnerTests.profile.xcconfig */,
+ 5B101E50F7EDE4E6F1714DD8 /* Pods-OneSignalNotificationServiceExtension.debug.xcconfig */,
+ 055EB8AF0F56FE3029E6507E /* Pods-OneSignalNotificationServiceExtension.release.xcconfig */,
+ 4720F73E5117230A69E1B4A0 /* Pods-OneSignalNotificationServiceExtension.profile.xcconfig */,
);
path = Pods;
sourceTree = "";
@@ -160,6 +225,7 @@
children = (
2545A56CA7C5FCC88F0D6DF7 /* Pods_Runner.framework */,
23D173C6FEE4F53025C06238 /* Pods_RunnerTests.framework */,
+ FC689749C1B738DA836BE8F2 /* Pods_OneSignalNotificationServiceExtension.framework */,
);
name = Frameworks;
sourceTree = "";
@@ -186,11 +252,33 @@
productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
+ 48D4106E2ED7067500A8B931 /* OneSignalNotificationServiceExtension */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 48D410782ED7067500A8B931 /* Build configuration list for PBXNativeTarget "OneSignalNotificationServiceExtension" */;
+ buildPhases = (
+ D2C3589E1C02A832F759D563 /* [CP] Check Pods Manifest.lock */,
+ 48D4106B2ED7067500A8B931 /* Sources */,
+ 48D4106C2ED7067500A8B931 /* Frameworks */,
+ 48D4106D2ED7067500A8B931 /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ fileSystemSynchronizedGroups = (
+ 48D410702ED7067500A8B931 /* OneSignalNotificationServiceExtension */,
+ );
+ name = OneSignalNotificationServiceExtension;
+ productName = OneSignalNotificationServiceExtension;
+ productReference = 48D4106F2ED7067500A8B931 /* OneSignalNotificationServiceExtension.appex */;
+ productType = "com.apple.product-type.app-extension";
+ };
97C146ED1CF9000F007C117D /* Runner */ = {
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
6FF008E9F6081D18F1331B43 /* [CP] Check Pods Manifest.lock */,
+ 48D4107C2ED7067500A8B931 /* Embed Foundation Extensions */,
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
@@ -203,6 +291,7 @@
buildRules = (
);
dependencies = (
+ 48D410752ED7067500A8B931 /* PBXTargetDependency */,
);
name = Runner;
productName = Runner;
@@ -216,6 +305,7 @@
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = YES;
+ LastSwiftUpdateCheck = 1640;
LastUpgradeCheck = 1510;
ORGANIZATIONNAME = "";
TargetAttributes = {
@@ -223,6 +313,9 @@
CreatedOnToolsVersion = 14.0;
TestTargetID = 97C146ED1CF9000F007C117D;
};
+ 48D4106E2ED7067500A8B931 = {
+ CreatedOnToolsVersion = 16.4;
+ };
97C146ED1CF9000F007C117D = {
CreatedOnToolsVersion = 7.3.1;
LastSwiftMigration = 1100;
@@ -244,6 +337,7 @@
targets = (
97C146ED1CF9000F007C117D /* Runner */,
331C8080294A63A400263BE5 /* RunnerTests */,
+ 48D4106E2ED7067500A8B931 /* OneSignalNotificationServiceExtension */,
);
};
/* End PBXProject section */
@@ -256,6 +350,13 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ 48D4106D2ED7067500A8B931 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
97C146EC1CF9000F007C117D /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
@@ -379,6 +480,28 @@
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
};
+ D2C3589E1C02A832F759D563 /* [CP] Check Pods Manifest.lock */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ );
+ inputPaths = (
+ "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+ "${PODS_ROOT}/Manifest.lock",
+ );
+ name = "[CP] Check Pods Manifest.lock";
+ outputFileListPaths = (
+ );
+ outputPaths = (
+ "$(DERIVED_FILE_DIR)/Pods-OneSignalNotificationServiceExtension-checkManifestLockResult.txt",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
+ showEnvVarsInLog = 0;
+ };
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
@@ -390,6 +513,13 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ 48D4106B2ED7067500A8B931 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
97C146EA1CF9000F007C117D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@@ -407,6 +537,11 @@
target = 97C146ED1CF9000F007C117D /* Runner */;
targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */;
};
+ 48D410752ED7067500A8B931 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 48D4106E2ED7067500A8B931 /* OneSignalNotificationServiceExtension */;
+ targetProxy = 48D410742ED7067500A8B931 /* PBXContainerItemProxy */;
+ };
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
@@ -487,6 +622,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
+ CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 9R5X2DM2C8;
ENABLE_BITCODE = NO;
@@ -554,6 +690,123 @@
};
name = Profile;
};
+ 48D410792ED7067500A8B931 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 5B101E50F7EDE4E6F1714DD8 /* Pods-OneSignalNotificationServiceExtension.debug.xcconfig */;
+ buildSettings = {
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CODE_SIGN_ENTITLEMENTS = OneSignalNotificationServiceExtension/OneSignalNotificationServiceExtension.entitlements;
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ DEVELOPMENT_TEAM = 9R5X2DM2C8;
+ ENABLE_USER_SCRIPT_SANDBOXING = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu17;
+ GENERATE_INFOPLIST_FILE = YES;
+ INFOPLIST_FILE = OneSignalNotificationServiceExtension/Info.plist;
+ INFOPLIST_KEY_CFBundleDisplayName = OneSignalNotificationServiceExtension;
+ INFOPLIST_KEY_NSHumanReadableCopyright = "";
+ IPHONEOS_DEPLOYMENT_TARGET = 13;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ "@executable_path/../../Frameworks",
+ );
+ LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
+ MARKETING_VERSION = 1.0;
+ MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
+ MTL_FAST_MATH = YES;
+ PRODUCT_BUNDLE_IDENTIFIER = com.dbiz.partner.OneSignalNotificationServiceExtension;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SKIP_INSTALL = YES;
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ 48D4107A2ED7067500A8B931 /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 055EB8AF0F56FE3029E6507E /* Pods-OneSignalNotificationServiceExtension.release.xcconfig */;
+ buildSettings = {
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CODE_SIGN_ENTITLEMENTS = OneSignalNotificationServiceExtension/OneSignalNotificationServiceExtension.entitlements;
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ DEVELOPMENT_TEAM = 9R5X2DM2C8;
+ ENABLE_USER_SCRIPT_SANDBOXING = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu17;
+ GENERATE_INFOPLIST_FILE = YES;
+ INFOPLIST_FILE = OneSignalNotificationServiceExtension/Info.plist;
+ INFOPLIST_KEY_CFBundleDisplayName = OneSignalNotificationServiceExtension;
+ INFOPLIST_KEY_NSHumanReadableCopyright = "";
+ IPHONEOS_DEPLOYMENT_TARGET = 13;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ "@executable_path/../../Frameworks",
+ );
+ LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
+ MARKETING_VERSION = 1.0;
+ MTL_FAST_MATH = YES;
+ PRODUCT_BUNDLE_IDENTIFIER = com.dbiz.partner.OneSignalNotificationServiceExtension;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SKIP_INSTALL = YES;
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Release;
+ };
+ 48D4107B2ED7067500A8B931 /* Profile */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 4720F73E5117230A69E1B4A0 /* Pods-OneSignalNotificationServiceExtension.profile.xcconfig */;
+ buildSettings = {
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CODE_SIGN_ENTITLEMENTS = OneSignalNotificationServiceExtension/OneSignalNotificationServiceExtension.entitlements;
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ DEVELOPMENT_TEAM = 9R5X2DM2C8;
+ ENABLE_USER_SCRIPT_SANDBOXING = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu17;
+ GENERATE_INFOPLIST_FILE = YES;
+ INFOPLIST_FILE = OneSignalNotificationServiceExtension/Info.plist;
+ INFOPLIST_KEY_CFBundleDisplayName = OneSignalNotificationServiceExtension;
+ INFOPLIST_KEY_NSHumanReadableCopyright = "";
+ IPHONEOS_DEPLOYMENT_TARGET = 13;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ "@executable_path/../../Frameworks",
+ );
+ LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
+ MARKETING_VERSION = 1.0;
+ MTL_FAST_MATH = YES;
+ PRODUCT_BUNDLE_IDENTIFIER = com.dbiz.partner.OneSignalNotificationServiceExtension;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SKIP_INSTALL = YES;
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Profile;
+ };
97C147031CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
@@ -671,6 +924,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
+ CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 9R5X2DM2C8;
ENABLE_BITCODE = NO;
@@ -695,6 +949,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
+ CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 9R5X2DM2C8;
ENABLE_BITCODE = NO;
@@ -725,6 +980,16 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
+ 48D410782ED7067500A8B931 /* Build configuration list for PBXNativeTarget "OneSignalNotificationServiceExtension" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 48D410792ED7067500A8B931 /* Debug */,
+ 48D4107A2ED7067500A8B931 /* Release */,
+ 48D4107B2ED7067500A8B931 /* Profile */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist
index 20bc755..8d8cb20 100644
--- a/ios/Runner/Info.plist
+++ b/ios/Runner/Info.plist
@@ -2,6 +2,8 @@
+ CADisableMinimumFrameDurationOnPhone
+
CFBundleDevelopmentRegion
$(DEVELOPMENT_LANGUAGE)
CFBundleDisplayName
@@ -22,18 +24,26 @@
????
CFBundleVersion
$(FLUTTER_BUILD_NUMBER)
+ ITSAppUsesNonExemptEncryption
+
LSRequiresIPhoneOS
+ NSCameraUsageDescription
+ Ứng dụng cần quyền truy cập camera để quét mã QR và chụp ảnh giấy tờ xác thực (CCCD/CMND, chứng chỉ hành nghề)
+ NSMicrophoneUsageDescription
+ Ứng dụng cần quyền truy cập microphone để ghi âm video nếu cần
+ NSPhotoLibraryUsageDescription
+ Ứng dụng cần quyền truy cập thư viện ảnh để chọn ảnh giấy tờ xác thực và mã QR từ thiết bị của bạn
+ UIApplicationSupportsIndirectInputEvents
+
+ UIBackgroundModes
+
+ remote-notification
+
UILaunchStoryboardName
LaunchScreen
UIMainStoryboardFile
Main
- NSCameraUsageDescription
- Ứng dụng cần quyền truy cập camera để quét mã QR và chụp ảnh giấy tờ xác thực (CCCD/CMND, chứng chỉ hành nghề)
- NSPhotoLibraryUsageDescription
- Ứng dụng cần quyền truy cập thư viện ảnh để chọn ảnh giấy tờ xác thực và mã QR từ thiết bị của bạn
- NSMicrophoneUsageDescription
- Ứng dụng cần quyền truy cập microphone để ghi âm video nếu cần
UISupportedInterfaceOrientations
UIInterfaceOrientationPortrait
@@ -47,11 +57,5 @@
UIInterfaceOrientationLandscapeLeft
UIInterfaceOrientationLandscapeRight
- CADisableMinimumFrameDurationOnPhone
-
- UIApplicationSupportsIndirectInputEvents
-
- ITSAppUsesNonExemptEncryption
-
diff --git a/ios/Runner/Runner.entitlements b/ios/Runner/Runner.entitlements
new file mode 100644
index 0000000..675953d
--- /dev/null
+++ b/ios/Runner/Runner.entitlements
@@ -0,0 +1,12 @@
+
+
+
+
+ aps-environment
+ development
+ com.apple.security.application-groups
+
+ group.com.dbiz.partner.onesignal
+
+
+
diff --git a/lib/core/network/api_interceptor.dart b/lib/core/network/api_interceptor.dart
index d3f7a9d..57388ec 100644
--- a/lib/core/network/api_interceptor.dart
+++ b/lib/core/network/api_interceptor.dart
@@ -569,7 +569,7 @@ Future authInterceptor(Ref ref, Dio dio) async {
@riverpod
LoggingInterceptor loggingInterceptor(Ref ref) {
// Only enable logging in debug mode
- const bool isDebug = true; // TODO: Replace with kDebugMode from Flutter
+ const bool isDebug = false; // TODO: Replace with kDebugMode from Flutter
return LoggingInterceptor(
enableRequestLogging: false,
diff --git a/lib/core/router/app_router.dart b/lib/core/router/app_router.dart
index f6f8d2c..ccfd821 100644
--- a/lib/core/router/app_router.dart
+++ b/lib/core/router/app_router.dart
@@ -65,14 +65,21 @@ final routerProvider = Provider((ref) {
redirect: (context, state) {
final isLoading = authState.isLoading;
final isLoggedIn = authState.value != null;
- final isOnSplashPage = state.matchedLocation == RouteNames.splash;
- final isOnLoginPage = state.matchedLocation == RouteNames.login;
- final isOnForgotPasswordPage =
- state.matchedLocation == RouteNames.forgotPassword;
- final isOnRegisterPage = state.matchedLocation == RouteNames.register;
- final isOnBusinessUnitPage =
- state.matchedLocation == RouteNames.businessUnitSelection;
- final isOnOtpPage = state.matchedLocation == RouteNames.otpVerification;
+ final currentPath = state.matchedLocation;
+ final targetPath = state.uri.toString();
+
+ // Log redirect attempts for debugging
+ print('🔄 Router redirect check:');
+ print(' Current: $currentPath');
+ print(' Target: $targetPath');
+ print(' isLoading: $isLoading, isLoggedIn: $isLoggedIn');
+
+ final isOnSplashPage = currentPath == RouteNames.splash;
+ final isOnLoginPage = currentPath == RouteNames.login;
+ final isOnForgotPasswordPage = currentPath == RouteNames.forgotPassword;
+ final isOnRegisterPage = currentPath == RouteNames.register;
+ final isOnBusinessUnitPage = currentPath == RouteNames.businessUnitSelection;
+ final isOnOtpPage = currentPath == RouteNames.otpVerification;
final isOnAuthPage =
isOnLoginPage ||
isOnForgotPasswordPage ||
@@ -82,25 +89,35 @@ final routerProvider = Provider((ref) {
// While loading auth state, show splash screen
if (isLoading) {
- return RouteNames.splash;
+ if (!isOnSplashPage) {
+ print(' ➡️ Redirecting to splash (loading)');
+ return RouteNames.splash;
+ }
+ print(' ✓ Already on splash (loading)');
+ return null;
}
// After loading, redirect from splash to appropriate page
- if (isOnSplashPage && !isLoading) {
- return isLoggedIn ? RouteNames.home : RouteNames.login;
+ if (isOnSplashPage) {
+ final destination = isLoggedIn ? RouteNames.home : RouteNames.login;
+ print(' ➡️ Redirecting from splash to $destination');
+ return destination;
}
// If not logged in and not on auth/splash pages, redirect to login
- if (!isLoggedIn && !isOnAuthPage && !isOnSplashPage) {
+ if (!isLoggedIn && !isOnAuthPage) {
+ print(' ➡️ Redirecting to login (not authenticated)');
return RouteNames.login;
}
// If logged in and on login page, redirect to home
if (isLoggedIn && isOnLoginPage) {
+ print(' ➡️ Redirecting to home (already logged in)');
return RouteNames.home;
}
// No redirect needed
+ print(' ✓ No redirect needed');
return null;
},
@@ -549,7 +566,7 @@ final routerProvider = Provider((ref) {
),
// Debug logging (disable in production)
- debugLogDiagnostics: true,
+ debugLogDiagnostics: false, // Using custom logs instead
);
});
diff --git a/lib/features/auth/presentation/providers/auth_provider.dart b/lib/features/auth/presentation/providers/auth_provider.dart
index 5598cb4..33066a3 100644
--- a/lib/features/auth/presentation/providers/auth_provider.dart
+++ b/lib/features/auth/presentation/providers/auth_provider.dart
@@ -88,10 +88,8 @@ class Auth extends _$Auth {
@override
Future build() async {
// Simple initialization - just check if user is logged in
- // Don't call getSession() here to avoid ref disposal issues
+ // Do this ONCE on app startup and don't rebuild
try {
- final secureStorage = ref.read(secureStorageProvider);
-
// Check if "Remember Me" was enabled
final rememberMe = await _localDataSource.getRememberMe();
@@ -101,6 +99,7 @@ class Auth extends _$Auth {
}
// Check if we have a stored session
+ final secureStorage = ref.read(secureStorageProvider);
final sid = await secureStorage.read(key: 'frappe_sid');
final userId = await secureStorage.read(key: 'frappe_user_id');
final fullName = await secureStorage.read(key: 'frappe_full_name');
diff --git a/lib/main.dart b/lib/main.dart
index 617f4cc..8cacf52 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -4,6 +4,7 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:onesignal_flutter/onesignal_flutter.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:worker/app.dart';
@@ -29,6 +30,10 @@ void main() async {
// Initialize app with error handling
await _initializeApp();
+
+ // Enable verbose logging for debugging (remove in production)
+
+
}
/// Initialize all app dependencies with comprehensive error handling
@@ -40,6 +45,55 @@ Future _initializeApp() async {
// Initialize core dependencies in parallel for faster startup
await Future.wait([_initializeHive(), _initializeSharedPreferences()]);
+ // Initialize OneSignal with verbose logging for debugging
+ OneSignal.Debug.setLogLevel(OSLogLevel.verbose);
+
+ // Initialize with your OneSignal App ID
+ OneSignal.initialize("778ca22d-c719-4ec8-86cb-a6b911166066");
+
+ debugPrint('🔔 OneSignal initialized');
+
+ // Add observer BEFORE requesting permission to catch the subscription event
+ OneSignal.User.pushSubscription.addObserver((state) {
+ debugPrint('🔔 Push subscription state changed:');
+ debugPrint(' Previous - optedIn: ${state.previous.optedIn}, id: ${state.previous.id}');
+ debugPrint(' Current - optedIn: ${state.current.optedIn}, id: ${state.current.id}');
+ debugPrint(' Subscription ID: ${state.current.id}');
+ debugPrint(' Push Token: ${state.current.token}');
+
+ // Save subscription info when available
+ if (state.current.id != null) {
+ debugPrint('🔔 ✅ Device successfully subscribed!');
+ }
+ });
+
+ // Add notification permission observer
+ OneSignal.Notifications.addPermissionObserver((isGranted) {
+ debugPrint('🔔 Notification permission changed: $isGranted');
+ });
+
+ // Request permission - TRUE to show the native permission prompt
+ final accepted = await OneSignal.Notifications.requestPermission(true);
+ debugPrint('🔔 Permission request result: $accepted');
+
+ // Give OneSignal SDK time to complete initialization and server registration
+ // This is necessary because the subscription happens asynchronously
+ await Future.delayed(const Duration(seconds: 2));
+
+ // Check current subscription status after initialization completes
+ final optedIn = OneSignal.User.pushSubscription.optedIn;
+ final id = OneSignal.User.pushSubscription.id;
+ final token = OneSignal.User.pushSubscription.token;
+
+ debugPrint('🔔 Current subscription status (after delay):');
+ debugPrint(' Opted In: $optedIn');
+ debugPrint(' Subscription ID: $id');
+ debugPrint(' Push Token: $token');
+
+ if (id == null) {
+ debugPrint('🔔 ⚠️ Subscription ID is still null - check device connectivity and OneSignal app ID');
+ }
+
// Run the app with Riverpod ProviderScope
runApp(const ProviderScope(child: WorkerApp()));
} catch (error, stackTrace) {
diff --git a/pubspec.lock b/pubspec.lock
index 8205081..70718df 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -964,6 +964,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.0"
+ onesignal_flutter:
+ dependency: "direct main"
+ description:
+ name: onesignal_flutter
+ sha256: b5bb43bf496ddb5e3975ba54c6477cc2d1fcd18fb3698f195d2e0bfd376ddafd
+ url: "https://pub.dev"
+ source: hosted
+ version: "5.3.4"
open_file:
dependency: "direct main"
description:
diff --git a/pubspec.yaml b/pubspec.yaml
index 414a7cc..0c51038 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix.
-version: 1.0.1+15
+version: 1.0.1+16
environment:
sdk: ^3.10.0
@@ -78,6 +78,7 @@ dependencies:
shared_preferences: ^2.2.3
flutter_secure_storage: ^9.2.4
+ onesignal_flutter: ^5.3.4
# Navigation
go_router: ^14.6.2