Skip to content

AB#280444 - Add GamifyWidget SDK module - #140

Merged
dmytro-b-optimove merged 11 commits into
masterfrom
feature/280444-gamify-widget-ios
May 19, 2026
Merged

AB#280444 - Add GamifyWidget SDK module#140
dmytro-b-optimove merged 11 commits into
masterfrom
feature/280444-gamify-widget-ios

Conversation

@dmytro-b-optimove

@dmytro-b-optimove dmytro-b-optimove commented Apr 13, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds GamifyWidgetSDK — public entry point with initialize(widgetUrl:) and open(from:userId:token:) that presents a modal sheet
  • Adds GamifyWidgetViewController — internal UIKit view controller hosting a WKWebView with JS bridge (READY → INIT → CLOSE handshake), loading spinner, and error state
  • Adds GamifyWidgetSDKTests — unit tests for URL initialisation

iOS equivalent of Android SDK PR #91 (AB#280444). No changes to Package.swift — new files sit inside the existing OptimoveSDK target source path.

JS Bridge

Widget fires READY via window.webkit.messageHandlers.receiveMessage.postMessage({type: "READY", ...}) → native responds with INIT (userId/token) via window.postMessage. Widget calls window.webkit.messageHandlers.closeWidget.postMessage(...) to close. Handler names match the canonical bridge contract in opti-ls/packages/widget-fe/src/lib/bridge/bridge.ts. Token is redacted in logs.

Test plan

  • cmd+U on OptimoveSDK scheme — GamifyWidgetSDKTests pass
  • cmd+B on iOS scheme — clean build, no errors or warnings
  • Run QA app, navigate to Gamify Widget, fill tenant + userId, tap Open Widget — sheet opens and close button dismisses

@dmytro-b-optimove
dmytro-b-optimove marked this pull request as draft April 13, 2026 23:41
@dmytro-b-optimove
dmytro-b-optimove marked this pull request as ready for review April 27, 2026 11:28
@dmytro-b-optimove
dmytro-b-optimove force-pushed the feature/280444-gamify-widget-ios branch from 0ac9128 to fa68645 Compare April 27, 2026 11:57
SofiaVainstein
SofiaVainstein previously approved these changes Apr 30, 2026
Comment thread OptimoveSDK/Sources/Classes/GamifyWidget/GamifyWidgetViewController.swift Outdated
Comment thread OptimoveSDK/Sources/Classes/GamifyWidget/GamifyWidgetViewController.swift Outdated
Comment thread OptimoveSDK/Sources/Classes/GamifyWidget/GamifyWidgetSDK.swift Outdated
Comment thread OptimoveSDK/Sources/Classes/GamifyWidget/GamifyWidgetSDK.swift
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Comment thread OptimoveSDK/Sources/Classes/GamifyWidget/GamifyWidgetSDK.swift
Match the ensureMain + assertOnMainThread pattern from InAppPresenter.swift
so public entry points dispatch to main themselves instead of relying on a
debug-only assert that strips in release builds.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new “Gamify Widget” feature area to the OptimoveSDK, providing a public SDK entry point to configure a widget URL and present a modal sheet hosting a WKWebView with a simple JS bridge handshake.

Changes:

  • Introduces GamifyWidgetSDK as the public API for configuring and opening the widget.
  • Adds GamifyWidgetViewController to host the WKWebView, show loading/error UI, and handle READY/INIT/CLOSE messages.
  • Adds GamifyWidgetSDKTests covering URL initialization behavior (including a background-thread call case).

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.

File Description
OptimoveSDK/Sources/Classes/GamifyWidget/GamifyWidgetSDK.swift Public entry point to initialize widget URL and present the widget as a modal sheet.
OptimoveSDK/Sources/Classes/GamifyWidget/GamifyWidgetViewController.swift Internal UIKit controller with WKWebView + JS bridge, loading spinner, and error state.
OptimoveSDK/Tests/Sources/GamifyWidget/GamifyWidgetSDKTests.swift Unit tests validating widget URL initialization behavior.
Comments suppressed due to low confidence (1)

OptimoveSDK/Tests/Sources/GamifyWidget/GamifyWidgetSDKTests.swift:21

  • Same issue as above: this test asserts immediately after calling initialize, but initialize may be async if invoked off the main thread. Make the test deterministic by running the call on the main thread or waiting until the main-queue work has executed.
    func testInitializeOverwritesPreviousUrl() {
        GamifyWidgetSDK.initialize(widgetUrl: "https://first.example.com")
        GamifyWidgetSDK.initialize(widgetUrl: "https://second.example.com")
        XCTAssertEqual(GamifyWidgetSDK.widgetUrl, "https://second.example.com")
    }

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread OptimoveSDK/Sources/Classes/GamifyWidget/GamifyWidgetSDK.swift
Comment thread OptimoveSDK/Tests/Sources/GamifyWidget/GamifyWidgetSDKTests.swift Outdated
dmytro-b-optimove and others added 3 commits May 18, 2026 15:34
…w error label

Match the existing presenter pattern from InAppPresenter/OverlayMessagingPresenter:
- GamifyWidgetSDK.open pre-flight guards empty/invalid widgetUrl with Logger.error + return
- Remove the error label from GamifyWidgetViewController; nav failures silently dismiss

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Wrap GamifyWidgetSDK.initialize(widgetUrl:) calls in runOnMainSync helper
so the write completes before assertions, removing the false-negative risk
under off-main test execution.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@dmytro-b-optimove
dmytro-b-optimove merged commit 1b15554 into master May 19, 2026
8 of 11 checks passed
dmytro-b-optimove added a commit to optimove-tech/Optimove-SDK-React-Native that referenced this pull request Jun 2, 2026
iOS 6.7.0 is the first release to bundle GamifyWidgetSDK (merged in
optimove-tech/Optimove-SDK-iOS#140, released 2026-06-01). The Swift bridge
already targets the released API (initialize(widgetUrl:) + open(from:userId:token:)),
so this only bumps the dependency pins: OptimoveCore/OptimoveSDK ~> 6.7.0 in
the podspec, OptimoveNotificationServiceExtension ~> 6.7.0 in the example
Podfile, and the regenerated Podfile.lock.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants