Skip to content

Commit 8fddfc5

Browse files
committed
Update new example app
1 parent 373f0be commit 8fddfc5

33 files changed

Lines changed: 2809 additions & 791 deletions
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
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>CFBundleDevelopmentRegion</key>
6+
<string>en</string>
7+
<key>CFBundleDisplayName</key>
8+
<string>OneSignalNotificationServiceExtension</string>
9+
<key>CFBundleExecutable</key>
10+
<string>$(EXECUTABLE_NAME)</string>
11+
<key>CFBundleIdentifier</key>
12+
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
13+
<key>CFBundleInfoDictionaryVersion</key>
14+
<string>6.0</string>
15+
<key>CFBundleName</key>
16+
<string>$(PRODUCT_NAME)</string>
17+
<key>CFBundlePackageType</key>
18+
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
19+
<key>CFBundleShortVersionString</key>
20+
<string>$(MARKETING_VERSION)</string>
21+
<key>CFBundleVersion</key>
22+
<string>$(CURRENT_PROJECT_VERSION)</string>
23+
<key>NSExtension</key>
24+
<dict>
25+
<key>NSExtensionPointIdentifier</key>
26+
<string>com.apple.usernotifications.service</string>
27+
<key>NSExtensionPrincipalClass</key>
28+
<string>$(PRODUCT_MODULE_NAME).NotificationService</string>
29+
</dict>
30+
</dict>
31+
</plist>
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import UserNotifications
2+
import OneSignalExtension
3+
4+
class NotificationService: UNNotificationServiceExtension {
5+
6+
var contentHandler: ((UNNotificationContent) -> Void)?
7+
var receivedRequest: UNNotificationRequest?
8+
var bestAttemptContent: UNMutableNotificationContent?
9+
10+
override func didReceive(
11+
_ request: UNNotificationRequest,
12+
withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void
13+
) {
14+
self.receivedRequest = request
15+
self.contentHandler = contentHandler
16+
self.bestAttemptContent = request.content.mutableCopy() as? UNMutableNotificationContent
17+
18+
if let bestAttemptContent = bestAttemptContent {
19+
OneSignalExtension.didReceiveNotificationExtensionRequest(
20+
request,
21+
with: bestAttemptContent,
22+
withContentHandler: contentHandler
23+
)
24+
}
25+
}
26+
27+
override func serviceExtensionTimeWillExpire() {
28+
if let contentHandler = contentHandler,
29+
let bestAttemptContent = bestAttemptContent {
30+
OneSignalExtension.serviceExtensionTimeWillExpireRequest(
31+
receivedRequest!,
32+
with: bestAttemptContent
33+
)
34+
contentHandler(bestAttemptContent)
35+
}
36+
}
37+
}
Lines changed: 10 additions & 0 deletions
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.onesignal.example.onesignal</string>
8+
</array>
9+
</dict>
10+
</plist>

iOS_SDK/OneSignalSwiftUIExample/OneSignalSwiftUIExample.entitlements

Lines changed: 4 additions & 0 deletions
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.onesignal.example.onesignal</string>
10+
</array>
711
</dict>
812
</plist>

iOS_SDK/OneSignalSwiftUIExample/OneSignalSwiftUIExample.xcodeproj/project.pbxproj

Lines changed: 246 additions & 4 deletions
Large diffs are not rendered by default.

iOS_SDK/OneSignalSwiftUIExample/OneSignalSwiftUIExample/App/OneSignalSwiftUIExampleApp.swift

Lines changed: 96 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import OneSignalFramework
3232
struct OneSignalSwiftUIExampleApp: App {
3333
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
3434
@StateObject private var viewModel = OneSignalViewModel()
35-
35+
3636
var body: some Scene {
3737
WindowGroup {
3838
ContentView()
@@ -44,92 +44,157 @@ struct OneSignalSwiftUIExampleApp: App {
4444
// MARK: - App Delegate
4545

4646
class AppDelegate: NSObject, UIApplicationDelegate {
47-
47+
48+
// Keys for caching SDK state in UserDefaults
49+
private let cachedIAMPausedKey = "CachedInAppMessagesPaused"
50+
private let cachedLocationSharedKey = "CachedLocationShared"
51+
private let cachedConsentRequiredKey = "CachedConsentRequired"
52+
private let cachedPrivacyConsentKey = "CachedPrivacyConsent"
53+
4854
func application(
4955
_ application: UIApplication,
5056
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
5157
) -> Bool {
58+
// Set consent required before init (must be set before initWithContext)
59+
let consentRequired = UserDefaults.standard.bool(forKey: cachedConsentRequiredKey)
60+
let privacyConsent = UserDefaults.standard.bool(forKey: cachedPrivacyConsentKey)
61+
OneSignal.setConsentRequired(consentRequired)
62+
OneSignal.setConsentGiven(privacyConsent)
63+
5264
// Initialize OneSignal
5365
OneSignalService.shared.initialize(launchOptions: launchOptions)
54-
66+
67+
// Restore cached SDK states before UI loads
68+
restoreCachedStates()
69+
5570
// Set up notification lifecycle listeners
5671
setupNotificationListeners()
57-
72+
5873
// Set up in-app message listeners
5974
setupInAppMessageListeners()
60-
75+
76+
// Set up SDK log listener for LogView
77+
setupLogListener()
78+
79+
// Initialize tooltip service (fetches on background thread, non-blocking)
80+
TooltipService.shared.initialize()
81+
6182
return true
6283
}
63-
84+
85+
private func setupLogListener() {
86+
OneSignal.Debug.setLogLevel(.LL_VERBOSE)
87+
OneSignal.Debug.addLogListener(SDKLogListener.shared)
88+
}
89+
90+
private func restoreCachedStates() {
91+
// Restore IAM paused status
92+
let iamPaused = UserDefaults.standard.bool(forKey: cachedIAMPausedKey)
93+
OneSignal.InAppMessages.paused = iamPaused
94+
95+
// Restore location shared status
96+
let locationShared = UserDefaults.standard.bool(forKey: cachedLocationSharedKey)
97+
OneSignal.Location.isShared = locationShared
98+
}
99+
64100
private func setupNotificationListeners() {
65101
// Foreground notification display
66102
OneSignal.Notifications.addForegroundLifecycleListener(NotificationLifecycleHandler.shared)
67-
103+
68104
// Notification click handling
69105
OneSignal.Notifications.addClickListener(NotificationClickHandler.shared)
70106
}
71-
107+
72108
private func setupInAppMessageListeners() {
73109
// In-app message lifecycle
74110
OneSignal.InAppMessages.addLifecycleListener(InAppMessageLifecycleHandler.shared)
75-
111+
76112
// In-app message click handling
77113
OneSignal.InAppMessages.addClickListener(InAppMessageClickHandler.shared)
78-
79-
// Start with IAM paused
80-
OneSignal.InAppMessages.paused = true
81114
}
82115
}
83116

84117
// MARK: - Notification Handlers
85118

86119
class NotificationLifecycleHandler: NSObject, OSNotificationLifecycleListener {
87120
static let shared = NotificationLifecycleHandler()
88-
121+
89122
func onWillDisplay(event: OSNotificationWillDisplayEvent) {
90-
print("[OneSignal] Notification will display: \(event.notification.title ?? "No title")")
91-
// Optionally modify display behavior
92-
// event.preventDefault() // Prevent automatic display
93-
// event.notification.display() // Manually display later
123+
Task { @MainActor in
124+
LogManager.shared.i("Notification", "Will display: \(event.notification.title ?? "No title")")
125+
}
94126
}
95127
}
96128

97129
class NotificationClickHandler: NSObject, OSNotificationClickListener {
98130
static let shared = NotificationClickHandler()
99-
131+
100132
func onClick(event: OSNotificationClickEvent) {
101-
print("[OneSignal] Notification clicked: \(event.notification.title ?? "No title")")
102-
// Handle notification click - navigate to specific screen, etc.
133+
Task { @MainActor in
134+
LogManager.shared.i("Notification", "Clicked: \(event.notification.title ?? "No title")")
135+
}
103136
}
104137
}
105138

106139
// MARK: - In-App Message Handlers
107140

108141
class InAppMessageLifecycleHandler: NSObject, OSInAppMessageLifecycleListener {
109142
static let shared = InAppMessageLifecycleHandler()
110-
143+
111144
func onWillDisplay(event: OSInAppMessageWillDisplayEvent) {
112-
print("[OneSignal] IAM will display: \(event.message.messageId)")
145+
Task { @MainActor in
146+
LogManager.shared.i("IAM", "Will display: \(event.message.messageId)")
147+
}
113148
}
114-
149+
115150
func onDidDisplay(event: OSInAppMessageDidDisplayEvent) {
116-
print("[OneSignal] IAM did display: \(event.message.messageId)")
151+
Task { @MainActor in
152+
LogManager.shared.i("IAM", "Did display: \(event.message.messageId)")
153+
}
117154
}
118-
155+
119156
func onWillDismiss(event: OSInAppMessageWillDismissEvent) {
120-
print("[OneSignal] IAM will dismiss: \(event.message.messageId)")
157+
Task { @MainActor in
158+
LogManager.shared.i("IAM", "Will dismiss: \(event.message.messageId)")
159+
}
121160
}
122-
161+
123162
func onDidDismiss(event: OSInAppMessageDidDismissEvent) {
124-
print("[OneSignal] IAM did dismiss: \(event.message.messageId)")
163+
Task { @MainActor in
164+
LogManager.shared.i("IAM", "Did dismiss: \(event.message.messageId)")
165+
}
125166
}
126167
}
127168

128169
class InAppMessageClickHandler: NSObject, OSInAppMessageClickListener {
129170
static let shared = InAppMessageClickHandler()
130-
171+
131172
func onClick(event: OSInAppMessageClickEvent) {
132-
print("[OneSignal] IAM clicked: \(event.result.actionId ?? "No action ID")")
133-
// Handle IAM click - navigate, track event, etc.
173+
Task { @MainActor in
174+
LogManager.shared.i("IAM", "Clicked: \(event.result.actionId ?? "No action ID")")
175+
}
176+
}
177+
}
178+
179+
// MARK: - SDK Log Listener
180+
181+
class SDKLogListener: NSObject, OSLogListener {
182+
static let shared = SDKLogListener()
183+
184+
func onLogEvent(_ event: OneSignalLogEvent) {
185+
let level: LogLevel
186+
switch event.level {
187+
case .LL_FATAL, .LL_ERROR:
188+
level = .error
189+
case .LL_WARN:
190+
level = .warning
191+
case .LL_INFO:
192+
level = .info
193+
default:
194+
level = .debug
195+
}
196+
Task { @MainActor in
197+
LogManager.shared.log("SDK", event.entry, level: level)
198+
}
134199
}
135200
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"images" : [
3+
{
4+
"filename" : "onesignal_rectangle.png",
5+
"idiom" : "universal",
6+
"scale" : "1x"
7+
},
8+
{
9+
"idiom" : "universal",
10+
"scale" : "2x"
11+
},
12+
{
13+
"idiom" : "universal",
14+
"scale" : "3x"
15+
}
16+
],
17+
"info" : {
18+
"author" : "xcode",
19+
"version" : 1
20+
},
21+
"properties" : {
22+
"template-rendering-intent" : "template"
23+
}
24+
}
18.2 KB
Loading

0 commit comments

Comments
 (0)