Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 13 additions & 9 deletions examples/demo/App.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@
E194A3F19072CB17A8F1A12E /* SmsSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SmsSection.swift; sourceTree = "<group>"; };
ECAC7EF0B67920F9FEC4F129 /* TagsSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TagsSection.swift; sourceTree = "<group>"; };
F46DFACB9F304B9374F3C570 /* ToastView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToastView.swift; sourceTree = "<group>"; };
"TEMP_ABAB8D6F-E57E-4D74-98B6-E29157EB8D71" /* Build.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Build.xcconfig; sourceTree = "<group>"; };
"TEMP_DEC528CA-1E47-4B0F-AAAF-071417BC60C5" /* Build.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Build.xcconfig; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -582,10 +582,10 @@
path = Support;
sourceTree = "<group>";
};
"TEMP_50803CDB-250B-41C8-93E2-9DF8EB2C4802" /* demo */ = {
"TEMP_17E43425-D1F7-4A88-B0A0-C0368CB0E171" /* demo */ = {
isa = PBXGroup;
children = (
"TEMP_ABAB8D6F-E57E-4D74-98B6-E29157EB8D71" /* Build.xcconfig */,
"TEMP_DEC528CA-1E47-4B0F-AAAF-071417BC60C5" /* Build.xcconfig */,
);
path = demo;
sourceTree = "<group>";
Expand Down Expand Up @@ -956,7 +956,7 @@
/* Begin XCBuildConfiguration section */
0D2EF3911CA89837C30DB0D1 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = "TEMP_ABAB8D6F-E57E-4D74-98B6-E29157EB8D71" /* Build.xcconfig */;
baseConfigurationReference = "TEMP_DEC528CA-1E47-4B0F-AAAF-071417BC60C5" /* Build.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground;
Expand All @@ -974,7 +974,7 @@
};
4A0C935808978B5A7673E412 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = "TEMP_ABAB8D6F-E57E-4D74-98B6-E29157EB8D71" /* Build.xcconfig */;
baseConfigurationReference = "TEMP_DEC528CA-1E47-4B0F-AAAF-071417BC60C5" /* Build.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = App.entitlements;
Expand Down Expand Up @@ -1029,6 +1029,7 @@
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DERIVE_MACCATALYST_PRODUCT_BUNDLE_IDENTIFIER = YES;
DEVELOPMENT_TEAM = "";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
Expand All @@ -1047,6 +1048,7 @@
MTL_FAST_MATH = YES;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;
SUPPORTS_MACCATALYST = YES;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_VERSION = 5.9;
Expand All @@ -1055,7 +1057,7 @@
};
D0E56A85F1C385808720F94B /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = "TEMP_ABAB8D6F-E57E-4D74-98B6-E29157EB8D71" /* Build.xcconfig */;
baseConfigurationReference = "TEMP_DEC528CA-1E47-4B0F-AAAF-071417BC60C5" /* Build.xcconfig */;
buildSettings = {
CODE_SIGN_ENTITLEMENTS = OneSignalNotificationServiceExtension/OneSignalNotificationServiceExtension.entitlements;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
Expand All @@ -1077,7 +1079,7 @@
};
EB1CC3A930E09FEBECF9195D /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = "TEMP_ABAB8D6F-E57E-4D74-98B6-E29157EB8D71" /* Build.xcconfig */;
baseConfigurationReference = "TEMP_DEC528CA-1E47-4B0F-AAAF-071417BC60C5" /* Build.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = App.entitlements;
Expand All @@ -1101,7 +1103,7 @@
};
F305A3E63851EE49DA2D190E /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = "TEMP_ABAB8D6F-E57E-4D74-98B6-E29157EB8D71" /* Build.xcconfig */;
baseConfigurationReference = "TEMP_DEC528CA-1E47-4B0F-AAAF-071417BC60C5" /* Build.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground;
Expand All @@ -1124,7 +1126,7 @@
};
F5FD25168D9B32A08A468069 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = "TEMP_ABAB8D6F-E57E-4D74-98B6-E29157EB8D71" /* Build.xcconfig */;
baseConfigurationReference = "TEMP_DEC528CA-1E47-4B0F-AAAF-071417BC60C5" /* Build.xcconfig */;
buildSettings = {
CODE_SIGN_ENTITLEMENTS = OneSignalNotificationServiceExtension/OneSignalNotificationServiceExtension.entitlements;
DEVELOPMENT_TEAM = 99SW8E36CT;
Expand Down Expand Up @@ -1176,6 +1178,7 @@
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = dwarf;
DERIVE_MACCATALYST_PRODUCT_BUNDLE_IDENTIFIER = YES;
DEVELOPMENT_TEAM = "";
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
Expand All @@ -1201,6 +1204,7 @@
ONLY_ACTIVE_ARCH = YES;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;
SUPPORTS_MACCATALYST = YES;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.9;
Expand Down
3 changes: 2 additions & 1 deletion examples/demo/App/App.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@

import SwiftUI
import OneSignalFramework
import OneSignalLiveActivities

@main
struct App: SwiftUI.App {
Expand Down Expand Up @@ -62,9 +61,11 @@ class AppDelegate: NSObject, UIApplicationDelegate {
setupInAppMessageListeners()

// Set up Live Activities (iOS 16.1+)
#if !targetEnvironment(macCatalyst)
if #available(iOS 16.1, *) {
LiveActivityController.setup()
}
#endif

return true
}
Expand Down
2 changes: 2 additions & 0 deletions examples/demo/App/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
<string>This app uses your location to personalize notifications and content.</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>This app uses your location to personalize notifications and content even when the app is in the background.</string>
<key>OneSignal_app_groups_key</key>
Comment thread
onesignal-deploy marked this conversation as resolved.
<string>group.com.onesignal.example.onesignal</string>
<key>NSSupportsLiveActivities</key>
<true/>
<key>NSSupportsLiveActivitiesFrequentUpdates</key>
Expand Down
4 changes: 4 additions & 0 deletions examples/demo/App/Services/LiveActivityController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@

import Foundation
import OneSignalFramework
#if targetEnvironment(macCatalyst)
// Live Activities are unavailable on Mac Catalyst.
#else
import OneSignalLiveActivities

/// Order tracking phases used by the Live Activity demo
Expand Down Expand Up @@ -151,3 +154,4 @@ enum LiveActivityController {
}
}
}
#endif
2 changes: 2 additions & 0 deletions examples/demo/App/ViewModels/OneSignalViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,7 @@ final class OneSignalViewModel: ObservableObject {

// MARK: - Live Activities

#if !targetEnvironment(macCatalyst)
func startLiveActivity(activityId: String, orderNumber: String, status: LiveActivityStatus) {
let trimmedId = activityId.trimmingCharacters(in: .whitespacesAndNewlines)
guard !trimmedId.isEmpty else { return }
Expand Down Expand Up @@ -423,6 +424,7 @@ final class OneSignalViewModel: ObservableObject {
)
}
}
#endif

// MARK: - Tooltips

Expand Down
1 change: 1 addition & 0 deletions examples/demo/App/Views/Components/ToggleRow.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ struct ToggleRow: View {
Toggle("", isOn: isOn)
.labelsHidden()
.tint(OS.Color.primary)
.background(OS.Color.grey500.opacity(0.35), in: Capsule())
.disabled(isDisabled)
.accessibilityIdentifier(accessibilityID)
}
Expand Down
2 changes: 2 additions & 0 deletions examples/demo/App/Views/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ struct ContentView: View {
TriggersSection()
CustomEventsSection()
LocationSection()
#if !targetEnvironment(macCatalyst)
LiveActivitySection()
#endif
ActionButton(
"NEXT SCREEN",
accessibilityID: "next_screen_button"
Expand Down
4 changes: 4 additions & 0 deletions examples/demo/App/Views/Sections/LiveActivitySection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@

import SwiftUI

#if targetEnvironment(macCatalyst)
// Live Activities are unavailable on Mac Catalyst.
#else
/// Live Activities (iOS 16.1+) section with activity ID + order # inputs and status cycler.
/// Mirrors the Capacitor demo's LiveActivitySection.
struct LiveActivitySection: View {
Expand Down Expand Up @@ -142,3 +145,4 @@ struct LiveActivitySection: View {
}
}
}
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>OneSignal_app_groups_key</key>
<string>group.com.onesignal.example.onesignal</string>
<key>NSExtension</key>
<dict>
<key>NSExtensionPointIdentifier</key>
Expand Down
4 changes: 4 additions & 0 deletions examples/demo/OneSignalWidget/OneSignalWidgetBundle.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,12 @@ import SwiftUI
@main
struct OneSignalWidgetBundle: WidgetBundle {
var body: some Widget {
#if targetEnvironment(macCatalyst)
OneSignalWidgetPlaceholder()
#else
if #available(iOS 16.2, *) {
OneSignalWidgetLiveActivity()
}
#endif
}
}
42 changes: 41 additions & 1 deletion examples/demo/OneSignalWidget/OneSignalWidgetLiveActivity.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,48 @@
* THE SOFTWARE.
*/

import ActivityKit
import WidgetKit
import SwiftUI

#if targetEnvironment(macCatalyst)
private struct CatalystPlaceholderEntry: TimelineEntry {
let date: Date
}

private struct CatalystPlaceholderProvider: TimelineProvider {
func placeholder(in context: Context) -> CatalystPlaceholderEntry {
CatalystPlaceholderEntry(date: Date())
}

func getSnapshot(
in context: Context,
completion: @escaping (CatalystPlaceholderEntry) -> Void
) {
completion(CatalystPlaceholderEntry(date: Date()))
}

func getTimeline(
in context: Context,
completion: @escaping (Timeline<CatalystPlaceholderEntry>) -> Void
) {
completion(Timeline(entries: [CatalystPlaceholderEntry(date: Date())], policy: .never))
}
}

struct OneSignalWidgetPlaceholder: Widget {
var body: some WidgetConfiguration {
StaticConfiguration(
kind: "com.onesignal.example.catalyst-placeholder",
provider: CatalystPlaceholderProvider()
) { _ in
Text("OneSignal")
}
.configurationDisplayName("OneSignal")
.description("Live Activities are unavailable on Mac Catalyst.")
}
}
#else
import ActivityKit
import OneSignalLiveActivities

/// Live Activity widget that renders the order tracking flow used by the demo.
Expand Down Expand Up @@ -173,3 +212,4 @@ struct DeliveryProgressBar: View {
.frame(height: 6)
}
}
#endif
2 changes: 1 addition & 1 deletion examples/demo/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ xcodegen generate # rewrites App.xcodeproj

### 3. Capabilities & App Group

The shipped `App.entitlements` and `OneSignalNotificationServiceExtension/OneSignalNotificationServiceExtension.entitlements` use `group.com.onesignal.example.onesignal`. If you need a different group (for example to install on a real device under your own team), change the value in both files to the same string. The other capabilities (Push Notifications, Remote notifications background mode, `NSSupportsLiveActivities`) are already declared in the entitlements / `App/Info.plist`.
The shipped `App.entitlements` and `OneSignalNotificationServiceExtension/OneSignalNotificationServiceExtension.entitlements` use `group.com.onesignal.example.onesignal`. Both targets also set `OneSignal_app_groups_key` to this value because Catalyst derives a `maccatalyst.*` bundle identifier that would otherwise produce a different default group name. If you need a different group (for example to install on a real device under your own team), change the value in both entitlements and both Info.plists to the same string. The other capabilities (Push Notifications, Remote notifications background mode, `NSSupportsLiveActivities`) are already declared in the entitlements / `App/Info.plist`.

### 4. Configure your OneSignal credentials

Expand Down
2 changes: 2 additions & 0 deletions examples/demo/project.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ settings:
CODE_SIGN_STYLE: Automatic
DEVELOPMENT_TEAM: ""
GENERATE_INFOPLIST_FILE: NO
SUPPORTS_MACCATALYST: YES
DERIVE_MACCATALYST_PRODUCT_BUNDLE_IDENTIFIER: YES
Comment thread
onesignal-deploy marked this conversation as resolved.
projectReferences:
OneSignalSDK:
path: ../../iOS_SDK/OneSignalSDK/OneSignal.xcodeproj
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import OneSignalCore
///
/// Stored in the App Group container, so it's shared across any targets (main app, NSE, etc.)
/// configured with the same App Group entitlement. Opaque identifiers only: no PII or credentials.
/// Accessors are no-ops on Mac Catalyst, where iOS data protection and prewarming do not apply.
@objc(OSResilientStorage)
public final class OSResilientStorage: NSObject {

Expand All @@ -50,6 +51,14 @@ public final class OSResilientStorage: NSObject {

// MARK: - Internal

private static var isSupported: Bool {
#if targetEnvironment(macCatalyst)
return false
#else
return true
#endif
}

private static let fileName = "onesignal_identity.json"

/// Serial queue used to serialize all file reads/writes.
Expand All @@ -59,15 +68,15 @@ public final class OSResilientStorage: NSObject {
/// the NSE can read the same file. Falls back to the app's private
/// Application Support directory when no App Group is entitled.
private static func fileURL() -> URL? {
let fm = FileManager.default
let fileManager = FileManager.default

let groupName = OneSignalUserDefaults.appGroupName()
if let container = fm.containerURL(forSecurityApplicationGroupIdentifier: groupName) {
if let container = fileManager.containerURL(forSecurityApplicationGroupIdentifier: groupName) {
return container.appendingPathComponent(fileName)
}

do {
let support = try fm.url(
let support = try fileManager.url(
for: .applicationSupportDirectory,
in: .userDomainMask,
appropriateFor: nil,
Expand Down Expand Up @@ -121,6 +130,7 @@ public final class OSResilientStorage: NSObject {

/// Returns the full current contents of the cache. Empty dict if absent.
@objc public static func snapshot() -> [String: String] {
guard isSupported else { return [:] }
return queue.sync { loadUnsafe() }
}

Expand All @@ -133,6 +143,7 @@ public final class OSResilientStorage: NSObject {

/// Atomically updates a single value. Passing nil or an empty string removes the key.
@objc public static func setString(_ value: String?, forKey key: String) {
guard isSupported else { return }
queue.async {
var current = loadUnsafe()
if let value = value, !value.isEmpty {
Expand All @@ -147,7 +158,7 @@ public final class OSResilientStorage: NSObject {
/// Atomically updates multiple values, preserving keys not in `values`.
/// An empty-string value removes the corresponding key.
@objc public static func setStrings(_ values: [String: String]) {
guard !values.isEmpty else { return }
guard isSupported, !values.isEmpty else { return }
queue.async {
var current = loadUnsafe()
for (key, value) in values {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,29 @@ public class OSStubLiveActivities: NSObject, OSLiveActivities {
}

public static func enter(_ activityId: String, withToken: String) {
OneSignalLog.onesignalLog(.LL_ERROR, message: "OneSignalLiveActivities not found. In order to use OneSignal's LiveActivities features the OneSignalLiveActivities module must be added.")
logUnavailable()
}

public static func enter(_ activityId: String, withToken: String, withSuccess: OSResultSuccessBlock?, withFailure: OSFailureBlock?) {
OneSignalLog.onesignalLog(.LL_ERROR, message: "OneSignalLiveActivities not found. In order to use OneSignal's LiveActivities features the OneSignalLiveActivities module must be added.")
logUnavailable()
}

public static func exit(_ activityId: String) {
OneSignalLog.onesignalLog(.LL_ERROR, message: "OneSignalLiveActivities not found. In order to use OneSignal's LiveActivities features the OneSignalLiveActivities module must be added.")
logUnavailable()
}

public static func exit(_ activityId: String, withSuccess: OSResultSuccessBlock?, withFailure: OSFailureBlock?) {
OneSignalLog.onesignalLog(.LL_ERROR, message: "OneSignalLiveActivities not found. In order to use OneSignal's LiveActivities features the OneSignalLiveActivities module must be added.")
logUnavailable()
}

public static func trackClickAndReturnOriginal(_ url: URL) -> URL? {
OneSignalLog.onesignalLog(.LL_ERROR, message: "OneSignalLiveActivities not found. In order to use OneSignal's LiveActivities features the OneSignalLiveActivities module must be added.")
logUnavailable()
return url
}

private static func logUnavailable() {
let message = "OneSignalLiveActivities not found. In order to use OneSignal's " +
"LiveActivities features the OneSignalLiveActivities module must be added."
OneSignalLog.onesignalLog(.LL_ERROR, message: message)
}
}
Loading
Loading