Repository navigation
feat!: harden iOS and Android SDKs for 1.0.0 - #27
Conversation
BREAKING CHANGE: the public API is reduced to the supported entry points. iOS: PoltioOverlayManager, PoltioWebViewController, PoltioPassthroughWindow, the trigger views, PoltioWidgetResponse/PoltioOverlayOptions, CachedWidgetResult, PoltioLogger and AnyCodable are now internal (use the new PoltioSDK.hideTrigger()). Android: PoltioLogger, PoltioWidgetResponse, PoltioOverlayOptions and PoltioWebViewActivity are internal, and PoltioSDK.onWidgetEvent is now a PoltioWidgetEventListener fun interface. The default log level on both platforms is now WARNING. - Android: @JvmStatic/@jvmoverloads across PoltioSDK and PoltioPurchaseItem - Android: handle WebView renderer crashes instead of killing the host app - iOS: WebView navigation policy matching Android (Poltio domains only; external links, target=_blank and deep links go to the system); reload on web content process termination - iOS: privacy manifest declares UserDefaults (CA92.1) and collected data - CI/Makefile: build and test iOS on the simulator so the UIKit layer is compiled and tested; add pod lib lint (podspec moved to repo root) - Untrack committed example/ios build artifacts (~94 MB) - Android: no main-thread disk I/O in configure/track/identify (serial background executor) - iOS logs via os_log; identifiers and params only logged at debug - Send X-Poltio-SDK-Version / X-Poltio-SDK-Platform headers; expose PoltioSDK.version - Document that non-view track() events are not sent to the API - Android sheet applies navigation bar and keyboard insets (edge-to-edge) - Trigger accessibility: button role, labels, close/collapse actions, and screen-reader activation opens the widget directly - Android: seed the current Activity when configure() is called late; persist dismissals against the application context - Small fixes: iOS force unwraps, view request-id race, consumer R8 rule for the JS bridge Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Code Review
This pull request introduces major enhancements to the Poltio Mobile SDK, including robust Java interop support, off-main-thread execution of disk and network operations via a new serial executor, TalkBack accessibility configurations for floating triggers, and WebView stability improvements such as edge-to-edge layouts and renderer crash handling. The code review highlights a security vulnerability where blob: and data: schemes bypass trusted URL checks, a consistency issue in PoltioFloatingBoxTriggerView when handling clicks in accessibility mode, and a bug where user identifiers (PUID) set prior to SDK configuration fail to persist to disk.
…dget directly from box tab, persist early PUID - Only about:blank (besides https Poltio hosts) is trusted on both platforms; data:/blob: documents could otherwise run script with bridge access - Box trigger's accessibility shortcut calls onOpenWidget() directly, like card/pill, instead of performClick() on the expanded container - A PUID set via identify() before configure() is now written to prefs (or cleared) once configure() provides a Context Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request updates the Poltio Mobile SDK to version 1.0.0, introducing improved background thread execution for disk I/O, enhanced Java interop, TalkBack accessibility support for floating triggers, and edge-to-edge layout handling in the WebView activity. Feedback identifies a critical security vulnerability in the trusted URL validation logic where a parser differential between android.net.Uri and Chromium could allow host validation bypass. Additionally, it is recommended to explicitly enable buildConfig in the Gradle build features to prevent compilation failures under newer Android Gradle Plugin versions.
android.net.Uri/Foundation and the WebView engines don't parse authorities identically (e.g. Chromium treats a backslash as '/'), so a host such as evil.com\.poltio.com could pass the .poltio.com suffix check yet load evil.com. Only plain [a-z0-9.-] hostnames are now trusted, on both platforms. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request refactors the Poltio Android SDK to improve Java interoperability, offload disk and network operations to a background serial executor, and enhance the WebView activity with edge-to-edge layout, robust URL validation, and renderer crash handling. It also introduces accessibility support for floating triggers. The review feedback highlights a potential race condition with concurrent requests, recommends unwrapping wrapped contexts to properly resolve activities, suggests using the application context to prevent memory leaks, and points out a missing import for the Build class.
…gure() Also check trigger dismissals against the application context, matching how they are recorded. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces significant updates to the Poltio Mobile SDK, focusing on Java interop, background thread safety, accessibility, and security. Key changes include preloading identifiers on a background thread, adding JvmStatic and JvmOverloads annotations, introducing TalkBack support for floating triggers, and hardening the WebView with trusted URL validation and crash handling. Feedback on these changes highlights two main areas for improvement: using locale-invariant case conversion (Locale.ROOT) when validating trusted widget URLs to prevent locale-specific bugs, and preserving existing left, top, and right padding values when setting the bottom padding on the sheet view.
Also pin the trusted-URL check's locale invariance with a tr-TR test. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces significant updates to the Poltio Mobile SDK, focusing on Java interoperability, background thread offloading for state persistence, edge-to-edge layout support, and accessibility improvements for floating triggers. Key changes include refactoring the Android SDK to use a serial background executor, adding ProGuard rules, implementing robust WebView crash handling, and introducing domain validation for trusted widget URLs. Feedback on these changes highlights a potential issue with weak reference checks when seeding the current activity, a security vulnerability from allowing unencrypted HTTP schemes in trusted URLs, and a missing callback notification to the host app when the WebView renderer process crashes.
- Widget WebView trust check accepts https only (both platforms), so a cleartext page can't be modified in transit to reach the JS bridge - seedCurrentActivity replaces a weakly-held Activity that is already finishing/destroyed but not yet garbage-collected Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SVG trigger icons render in a small WebView, and WebView consumes every touch in onTouchEvent even with isClickable = false. On the collapsed pill the icon covers most of the tap target, so the pill could not be tapped or expanded. The icon now uses PoltioNonInteractiveWebView, which never handles touches (the Android analogue of iOS's isUserInteractionEnabled = false), and is hidden from TalkBack since the trigger already carries the label. Also warn in `make run-example-android` when the running emulator is headless (-no-window), since the app then launches with no visible window. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Final pre-1.0 pass over both native SDKs. It locks the public API to what we intend to support, fixes host-app crash and privacy risks, and makes CI actually compile the iOS UI layer.
majorrelease)PoltioSDK,PoltioLogLevelandPoltioPurchaseItem.PoltioOverlayManager,PoltioWebViewController,PoltioPassthroughWindow, the trigger views,PoltioWidgetResponse/PoltioOverlayOptions,CachedWidgetResult,PoltioLoggerandAnyCodableare now internal.AnyCodablewas renamed toPoltioAnyCodableso it can't clash with the popular AnyCodable package. The newPoltioSDK.hideTrigger()replacesPoltioOverlayManager.shared.hideTrigger(). The instance-levelcacheTTL/cacheLimit/clearCache()are internal; use the static ones.PoltioLogger,PoltioWidgetResponse,PoltioOverlayOptionsandPoltioWebViewActivityare internal.PoltioSDK.onWidgetEventis now aPoltioWidgetEventListenerfun interface instead of a Kotlin function type:PoltioSDK.onWidgetEvent = PoltioWidgetEventListener { event, data -> }.warningon both platforms (wasinfo).Changes
@JvmStaticon everyPoltioSDKmember, and@JvmOverloadsonconfigure/track/recordPurchase/PoltioPurchaseItem. A Java test (PoltioSDKJavaInteropTest) compiles against the API the way a Java host would.onRenderProcessGonenow closes the sheet instead of letting Android kill the host process.*.poltio.comloads in the sheet. External links,target="_blank"/window.open,tel:/mailto:and deep links go to the system. The sheet reloads if the web content process is terminated. Both platforms share a testedisTrustedWidgetURLcheck.CA92.1) and the collected data types (Device ID, User ID, Purchase History, Product Interaction), all with tracking = false. Documented indocs/IOS.md. Please sanity-check the linked/purpose choices against our privacy policy.make test-iosnow runs on an iOS Simulator. Previously,swift teston macOS compiled out the whole UIKit layer: 58 tests instead of 46 run now, 62 with the new ones.make build-iosalso builds for the simulator SDK.make test-ios-macoskeeps the quick host-only run.lint-podCI job (pod lib lint). The podspec moved to the repo root so local lint can resolve paths; the publish workflow and bump script are updated.example/ios/.build+.swiftpmfiles. They're already gitignored. History is not rewritten.configure/track/identify/recordPurchasedo no disk I/O on the caller's thread. Work runs on a serial background executor, so view events keep their call order.os_log(subsystemcom.poltio.sdk) instead ofprint. PUID,sdk_idand event params are only logged atdebug.X-Poltio-SDK-VersionandX-Poltio-SDK-Platform, andPoltioSDK.versionis public. Android takes the version from the published Maven version; iOS readsPoltioSDKInfo.version, whichmake versionnow bumps.track()docs: non-view events are documented as local-only. The iOS example's "TrackConversion" button now callsrecordPurchase.configure()is called late with anActivity, that Activity is used for triggers right away. Dismissals are persisted against the application context.Small fixes: iOS force unwraps in
recordPurchaseremoved; view request-ID race fixed on both platforms; consumer R8 rule keeps@JavascriptInterfacemethods.Not in this PR
UIApplication.shared.windows/keyWindowfallbacks.Release notes
make version VERSION=x.y.zbefore merging. SPM consumers build from the tagged source, soPoltioSDKInfo.versionmust already be correct at tag time. It's set to1.0.0here.Testing
make test-ios: 62/62 on an iOS Simulatormake test-ios-macos: passesmake test-android: 81/81 (debug + release)make lint-ios,make lint-android,make lint-pod,make lint-actions: all cleanmake build-ios,make build-android,make build-example-ios,make build-example-android: all succeed🤖 Generated with Claude Code