Repository navigation
fix(ios): run Talsec.start off the platform thread - #239
Open
shoaib-akhtar wants to merge 2 commits into
Open
shoaib-akhtar wants to merge 2 commits into
shoaib-akhtar wants to merge 2 commits into
Conversation
Adds an XCTest target to the example app and a seam (`talsecStarter`) so the plugin's call to Talsec.start can be observed without running TalsecRuntime. The two threading tests fail against the current bridge: start runs inline on the platform thread and blocks handle(_:result:). Refs talsec#231
Talsec.start generates a key over a synchronous keychain/XPC call. Called from the method channel handler it ran on the main thread, which on iOS 26 hung the UI for 30+ s and led to watchdog terminations. Start now runs on a serial background queue and the Flutter result is delivered on the main thread once it returns, so `await Talsec.instance.start(...)` keeps its meaning. Fixes talsec#231
shoaib-akhtar
force-pushed
the
fix/ios-start-off-main-thread
branch
from
October 14, 2026 10:14
493b271 to
bdc502d
Compare
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.
Fixes #231
Problem
SwiftFreeraspPluginhandles thestartmethod call on the platform (main) thread and callsTalsec.start(config:)inline.Talsec.startgenerates a key throughSecKeyGeneratePair→SecItemAdd, which is a synchronous XPC round trip tosecurityd. On iOS 26 that round trip has been measured blocking the main thread for 30+ seconds, which causes app-hang reports andWatchdogTerminationkills on first launch (details in #231). Because the work runs inline, the Dart-sideawait Talsec.instance.start(config)gives no relief.Change
Talsec.startnow runs on a serial background queue (talsec.app/freerasp/start,.userInitiated).resultis delivered on the main thread afterTalsec.startreturns, soawait Talsec.instance.start(...)still means "the SDK has started".blockScreenCapture/isScreenCaptureBlockedalready hop to main.This matches how the React Native bridge already calls
Talsec.start: RN module methods run on a background method queue, so running the SDK start off-main has precedent in production.I went with an explicit queue rather than a channel
taskQueue:(option 1 in the issue) so that onlystartmoves off the main thread and the change can be unit-tested directly.Tests (written first)
The repo had no native iOS tests, so this adds a
RunnerTestsXCTest target to the example app (example/ios) and a small seam (talsecStarter) so tests can observe the call without running TalsecRuntime.The commits are ordered red → green:
test(ios): …: the tests, run against the unchanged bridge:testStartRunsTalsecOffTheMainThread: fails (Optional(true)is not equal toOptional(false))testStartReturnsBeforeTalsecFinishes: fails (.timedOut, becausehandleblocked until start finished)testStartRepliesOnTheMainThreadAfterTalsecStarts: passes (guard)testStartWithInvalidConfigReturnsErrorWithoutStartingTalsec: passes (guard)fix(ios): …: all 4 pass.Run with:
Verified on Xcode 26.1.1, iOS 26.1 simulator, Flutter 3.38.2. As an extra check, I also called the real
TalsecRuntimestart through the patched plugin from a test. It started off-main, replied, and did not crash.Not covered
The issue also shows the same keychain path being reached from inside TalsecRuntime through a
UIScreenKVO/notification callback. That code lives in the closed-source xcframework, so this PR can't change it.