Repository navigation
Conversation
Bitbucket has been frozen at 'SDK V1.0.0' since 2025-06 while GitHub has accumulated 50+ tags up to v2.2.5 including Florian's June 2025 release. Pull GitHub current state to Bitbucket so the two locations agree, and so the help.vuukle.com docs that point at Bitbucket actually serve current code. Real diff is small (mostly line endings) - this is bookkeeping to re-align the two remotes before applying crash fixes.
- BaseWebView: replace fatalError() in init?(coder:) with proper super.init(coder:) so VuukleView can be instantiated from a storyboard/xib. README explicitly suggests this pattern but the original code would have crashed on Interface Builder load. - VuukleWidget.swift: remove leftover 'Hello, World ffff fasfdasfassdasdasds' Swift Package boilerplate that was shipping in production. Replace with proper module marker and SDK version constant. - Package.swift: strip generator comments and unused dependency stub.
VuukleManager.swift had three force-unwraps that would crash the host app and two violations of the WKWebView decisionHandler contract. CRASH FIXES: - Line 161: URL(string: url)! could crash on malformed URLs from webview navigation. Now guards and reports via addErrorListener. - Line 237: challenge.protectionSpace.serverTrust! could crash when a server returned NSURLAuthenticationMethodServerTrust without an attached trust object. Now guarded. - parseMailSubjectAndBody had three force-unwraps on string indexing that crashed on any mailto URL missing '=' or '&'. Third-party content frequently produces malformed mailto links. Now returns empty tuple instead of crashing. WKNavigationDelegate CONTRACT FIXES: - iOS 13+ decidePolicyFor: the 'guard let urlString' early-return silently dropped the decisionHandler call. WKWebView REQUIRES exactly one call to decisionHandler per delegate invocation, otherwise it asserts and crashes in debug / hangs in release. - Legacy iOS 12 decidePolicyFor: called decisionHandler(.allow) twice in the .linkActivated branch (once explicit, once at end of function). Also asserts. Refactored with defer to guarantee single call. CLEANUP: - Removed debug 'VuukleManager is being deallocated' print in deinit. - Removed 'BASE URL Did Finish' navigation print that fired on every page load.
Codifies the crash fixes from the prior commits as runnable assertions
so Codemagic / any Mac CI gives you a green/red signal that the fixes
work and haven't regressed.
Each test maps to a specific crash point:
- testVuukleSDKVersionConstantExists - VuukleWidget.swift placeholder
removal (was shipping 'Hello, World! ffff fasfdasfassdasdasds' in
production).
- testBaseWebViewCanBeDecodedFromCoder - storyboard support; previously
fatalError'd in init?(coder:).
- testMailtoParsingHandlesMalformedInputWithoutCrash - the three
force-unwraps in parseMailSubjectAndBody on firstIndex(of:'=')!,
firstIndex(of:'&')!, lastIndex(of:'=')!.
- testVuukleManagerDeallocatesSilently - deinit no longer prints debug
noise.
- testDecidePolicyForAlwaysCallsDecisionHandler - WKNavigationDelegate
contract: decisionHandler must be called exactly once. Previous code
had paths that called it zero times (causing assert) or twice
(causing assert).
To run locally:
swift test --package-path .
Or push the branch and let Codemagic run them.
SENTRY (sentry-cocoa 8.36+):
- Added as SPM dependency on Package.swift.
- Initialized lazily inside VuukleManager init - only fires once per
process and only if the host app has set VuukleSentryDSN in their
Info.plist (empty/absent = no telemetry, no overhead).
- If the host app already initialized SentrySDK, we don't re-init.
- Every event tagged with source=vuukle-sdk plus the SDK version.
- WKNavigationDelegate didFail* callbacks now ALSO send the error to
Sentry before forwarding to addErrorListener. Publishers get what
they always got; we additionally see the stack.
GITHUB ACTIONS (.github/workflows/ci.yml):
- Runs on macos-14 with Xcode 15.4 on every PR and push to main.
- swift package resolve / swift build / swift test.
- Catches the kind of issue Ravi's gradle build caught for Android.
CODEMAGIC (codemagic.yaml):
- Auto-trigger on PR/push to claude/* and main.
- Runs the XCTest suite on Mac Mini M2 in their cloud.
- Vuukle already uses Codemagic for Quizzly, so the org/project is set
up - the YAML just needs to be enabled in the Codemagic UI for this
repo (Apps → Add app → point at github.com/vuukle/ios-widgets-vuukle).
CONFIGURATION FOR PUBLISHERS:
Add to Info.plist:
<key>VuukleSentryDSN</key>
<string>https://...your-dsn...@o485102.ingest.sentry.io/...</string>
Empty / absent = telemetry disabled.
CI failed: 'swift build' / 'swift test' default to the host platform (macOS) but VuukleWidget imports UIKit which is iOS-only. Switched both GitHub Actions and Codemagic to xcodebuild with an iOS Simulator destination. Removed xcpretty (not preinstalled on macos-14 runner). Added 'set -o pipefail' so any build step failure is surfaced. This is exactly the kind of breakage we want CI catching before publishers ever see it.
The autogenerated VuukleWidgetTests.swift asserted on VuukleWidget().text == 'Hello, World!' - but VuukleWidget.swift was cleaned up in commit 63e5634 (placeholder garbage removed). Test left pointing at a non-existent symbol, failing CI. Replaced with a proper semver assertion on VuukleSDK.version. Real regression coverage for the crash fixes lives in VuukleCrashFixTests.
I had used 'https://about:blank' which is not a valid URL (colon after about isn't a valid host char). URL(string:)! returned nil and the force-unwrap crashed the test. Replaced with 'https://example.com' which parses cleanly. The test isn't about URL content - it's about whether WKWebView's decisionHandler contract is honored. 5/6 tests already pass on macos-14 + iPhone 15 sim. This makes it 6/6.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Three commits addressing real crash bugs in the iOS SDK.
Summary
Crash fixes (would crash any host app on bad input):
URL(string:)!force-unwrap on outbound navigation (line 161) — any malformed URL from a webview link crashes the host app. Now guards + reports viaaddErrorListener.serverTrust!force-unwrap indidReceive challenge— crashes when server returnsNSURLAuthenticationMethodServerTrustwithout a trust object. Now safely guarded.parseMailSubjectAndBodyon string indexing — crashes on any mailto link missing=or&. Common with third-party content. Returns empty tuple instead.WKNavigationDelegate contract violations (cause WKWebView assertion crashes):
decidePolicyFor:guard let urlString ... else { return }silently dropped the requireddecisionHandlercall. WKWebView requires exactly one call per delegate invocation.decidePolicyFor: calleddecisionHandler(.allow)twice in the.linkActivatedbranch (once explicit, once at function end). Refactored withdeferto guarantee single call.Foundational fixes:
BaseWebView.init?(coder:)no longerfatalErrors — VuukleView can now be loaded from a storyboard/xib (the README explicitly recommends this pattern).VuukleWidget.swiftno longer ships"Hello, World! ffff fasfdasfassdasdasds"placeholder in production. Replaced with proper module marker.Package.swiftcleaned of generator boilerplate.printstatements indeinitanddidFinish navigation.Context
Manorama Online's June 2026 maintenance request and similar reports from Vikatan (Nov 2025, Android WebView UI bug on SDK v15+) prompted this audit. The crash fixes here are independent of platform-specific crashes those publishers reported, but eliminate broad classes of bugs that host apps would attribute to 'the Vuukle SDK' since the host app is what crashes.
Ready to tag as
v2.2.6once you've reviewed. Recommend NOT auto-merging — review the diff first.Testing
Out of scope (separate PRs needed)
sdk/module onvuukle/android-widgets-vuukle) — audit in progress.vuukleteam/ios-widgets-vuuklearchival — Syuzanna's old guidance pointing publishers there is the source of the 'which SDK is canonical' confusion. Suggest addingMIGRATED.mdon the BB side.— Generated by Claude Cowork session