OneSignal iOS SDK

repository·main·Indexed 19 days ago

https://github.com/onesignal/onesignal-ios-sdk

A plugin for integrating native iOS applications with OneSignal's mobile engagement services, including push notifications, in-app messages, email, and SMS. The SDK supports user management, push subscriptions, custom events, location sharing, and Live Activities (iOS 16.1+). It can be installed via CocoaPods, Carthage, or Swift Package Manager.

Tokens
13.4K
Snippets
36
Records
51
Agent score
68%

What's inside onesignal-ios-sdk

  1. Overview of OneSignal SDK capabilities in the Demo App

    main

    The SwiftUI demo app provides a visual interface to test the following OneSignal SDK features:

    • App / Consent: Displaying App ID and toggling consent_required and privacy_consent.
    • User Management: Logging in/out with an external user ID.
    • Push Subscription: Managing push subscription IDs, opt-in toggles, and permission prompts.
    • Push Notifications: Sending simple, image, sound, or custom notifications via the OneSignal REST API.
    • In-App Messaging (IAM): Pausing/resuming IAM display and triggering dashboard messages.
    • User Data: Adding/removing Aliases, Emails, SMS, and Tags.
    • Outcomes: Sending normal, unique, or value-based outcomes.
    • Triggers: Managing single/multiple triggers or clearing all.
    • Custom Events: Tracking events with optional JSON properties.
    • Location: Toggling location sharing and requesting permissions.
    • Live Activities (iOS 16.1+): Starting, updating, and ending activities using OneSignal.LiveActivities or the REST API.
  2. How state management works in the OneSignal Demo

    main

    The demo app uses a centralized state management pattern to bridge the OneSignal SDK with a SwiftUI interface:

    • OneSignalViewModel: The central ObservableObject that holds @Published properties for reactive UI updates (e.g., pushSubscriptionId, tags, consent, isLoading). It uses observers like OSPushSubscriptionObserver and OSUserStateObserver to keep state in sync.
    • OneSignalService: A singleton that acts as the single entry point for all SDK calls. It handles the logic of writing to both the SDK and a local PreferencesService (UserDefaults) to ensure settings like consentRequired or isLocationShared persist across app restarts.
    • PreferencesService: A UserDefaults-backed cache used to store user preferences that the SDK might not persist automatically, ensuring a consistent state on cold launches.
    • NotificationSender: A specialized service that wraps the /notifications REST endpoint and includes retry logic with exponential backoff to handle transient race conditions between subscription creation and notification delivery.
  3. Important limitations and usage constraints

    main

    When working with the OneSignal iOS SDK, keep the following constraints in mind:

    • Initialization Order: Any calls to the OneSignal.User namespace (e.g., OneSignal.User.addTag("tag", "2")) must be invoked after the SDK has been initialized.
    • App IDs: Changing app IDs is not supported.
    • User State Refresh: The user state is only refreshed from the OneSignal server when:
      • A new session starts (cold start or the app has been in the background for over 30 seconds).
      • The user is logged in. This behavior is intentional design.
  4. Understand the User-Centered Subscription Model

    main

    In OneSignal SDK v5.0.0+, the model has shifted from a 'player' model to a 'user' model.

    • Push Subscription: A user owns the current device's push subscription.
    • Email/SMS Subscriptions: A single user can now own zero or more email subscriptions and zero or more SMS subscriptions.

    Important Note on Login: If a new user logs in via the login method, the previous user will no longer own the current device's push subscription.

  5. Manage Live Activities with OneSignal

    main

    Live Activities allow you to provide real-time updates to users via the lock screen and Dynamic Island. Using the OneSignal SDK, you can associate a custom activityId with a Live Activity's temporary push token on OneSignal's servers. This allows you to update one or multiple Live Activities simultaneously using the OneSignal REST API via that activityId.

    // Enter a Live Activity
    OneSignal.LiveActivities.enter("ACTIVITY_ID", withToken: "TOKEN") { result in
        print("enter success with result: \(result ?? [:])")
    } withFailure: { error in
        print("enter error: \(String(describing: error))")
    }
  6. Implement Dialogs and Tooltips

    main

    The demo demonstrates two patterns for overlays:

    Tooltips

    Tooltips are managed by the ViewModel. The ViewModel holds @Published var activeTooltip: TooltipData?. The view layer binds this to a .osCenteredDialog modifier. Sections trigger them using viewModel.showTooltip(for:).

    Action Dialogs

    For specific user actions (e.g., adding or removing items), use local @State booleans within the section view to control visibility. Attach the .osCenteredDialog(isPresented: $isPresented) { DialogView(...) } modifier to the section.

    Implementation Note: The .osCenteredDialog is built on top of .fullScreenCover with a ClearBackgroundView to ensure the dialog presents at the window level and is not clipped by parent ScrollView containers.

  7. Understand device-scoped users and identification

    main

    A device-scoped user is an anonymous user with no aliases. Upon app installation, the OneSignal SDK is initialized with this user type. This user can only be retrieved via the current device or the OneSignal dashboard.

    To upgrade a device-scoped user to an identified user, call OneSignal.login("USER_EXTERNAL_ID") using a specific external user ID.

    // Upgrade to an identified user
    OneSignal.login("USER_EXTERNAL_ID")
  8. Manage user-scoped data via the User namespace

    main

    In OneSignal SDK v5.0.0+, user-scoped functionality is accessed through the OneSignal.User namespace. This namespace allows you to manage identity, contact information, and metadata for the current user.

    Key Capabilities:

    • Identity: Get or set onesignalId, externalId, and language.
    • Contact Methods: Add or remove email and sms subscriptions.
    • Aliases: Manage user aliases using addAlias, addAliases, removeAlias, or removeAliases.
    • Tags: Manage key-value pairs for targeting and personalization using addTag, addTags, removeTag, removeTags, or getTags to retrieve local tags.
    // Swift Examples
    OneSignal.User.setLanguage("en")
    OneSignal.User.addEmail("customer@company.com")
    OneSignal.User.addTag(key: "KEY", value: "VALUE")
    let id = OneSignal.User.externalId
  9. Setup the OneSignal iOS Sample App

    main

    The OneSignal iOS sample app is designed to build against the local SDK source tree directly. It uses XcodeGen to manage the project structure.

    Prerequisites

    • Install XcodeGen via Homebrew:
      brew install xcodegen

    Project Generation

    To generate the App.xcodeproj from the project.yml configuration, run the following from the examples/demo/ directory:

    cd examples/demo
    xcodegen generate

    Running the App

    1. Open the workspace: open iOS_SDK/OneSignalSDK.xcworkspace
    2. Select the App scheme.
    3. Build and run (⌘R) on a simulator or device.

    Note: The app and its extensions (OneSignalNotificationServiceExtension and OneSignalWidget) build from local SDK source, so any changes made to the SDK code will be reflected immediately in the app.

    brew install xcodegen
    cd examples/demo
    xcodegen generate
  10. Implement a Toast Notification System

    main

    The demo uses a ToastPresenter to manage transient UI messages.

    1. Setup: Create a @MainActor ObservableObject named ToastPresenter with a @Published var message: String? property and a show(_:) method.
    2. Injection: Inject the presenter into the view hierarchy using .environmentObject(toastPresenter) at the app root.
    3. Triggering: Section views access the presenter via @EnvironmentObject var toast: ToastPresenter and call toast.show("message").
    4. Display: Attach a .toast(message: $toast.message) modifier to the main view host to render the message.

    Behavior: The show(_:) method should cancel any existing dismissal tasks, set the new message, and start a new Task that sleeps for ToastPresenter.toastDurationMs (defaulting to 3_000 ms) before clearing the message.

    // In App.swift
    @StateObject var toastPresenter = ToastPresenter()
    
    ContentView()
        .environmentObject(toastPresenter)
        .toast(message: $toastPresenter.message)
  11. Enable location sharing in OneSignal iOS SDK v5.1.0+

    main

    Starting with version v5.1.0, location sharing is disabled by default. To enable location-scoped functionality and geotagging, you must explicitly set isShared to true via the OneSignal.Location namespace. You can also manually prompt the user for location permissions using requestPermission().

    // Swift
    OneSignal.Location.isShared = true
    OneSignal.Location.requestPermission()
    // Objective-C
    [OneSignal.Location setShared:YES];
    [OneSignal.Location requestPermission];