[iOS] Script init caches the wrong view model when dataBind is applied after state-machine creation
I maintainer di solito rispondono entro 1 giorno
Valutazione
- Difficoltà
- 2/5
- Tempo stimato
- 1-3 ore
- Idoneità per principianti
- 63/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Attiva
- Stack tecnologico
- react-native, swift, typescript
Direzione di ricerca
Leggi ios/new/RiveReactNativeView.swift, concentrandoti sulla creazione della macchina a stati e sulla risoluzione di dataBind. Confronta l’ordine attuale con la sonda Swift autonoma fornita e il diff proposto, quindi esegui la riproduzione iOS con RiveRuntime 6.28.0. Il lavoro è completato quando, durante la creazione della macchina a stati, viene usata l’istanza host associata esplicitamente, così che la sonda riporti isReady: 1 e observedSeed: 42; Android e il backend legacy non rientrano nella validazione riportata.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Description
On the iOS new runtime, supplying an explicit view-model instance through <RiveView dataBind={instance}> can leave a Luau script reading and writing the authored default instance instead of the host instance.
The script caches context:viewModel() in init. The React Native wrapper creates the state machine before passing the explicit instance into Rive(...dataBind: .instance(...)). The script appears to initialize against the default instance during state-machine creation and retain that reference after the host model is bound.
This has a functional consequence beyond the deprecated-API warnings tracked in #403: host initialization values are invisible to the script, and script-written readiness/results never reach the host's instance. In a small probe, the host seeds seed = 42, the script sets isReady = 1 in init, and each advance copies its cached model's seed into observedSeed.
| Value read from the host instance after 2 seconds | Current order | Bind at state-machine creation | Expected |
|---|---|---|---|
| seed | 42 | 42 | 42 |
| isReady | 0 | 1 | 1 |
| observedSeed | 0 | 42 | 42 |
The current-order rectangle renders red (script sees seed 0), while the early-binding rectangle renders green (script sees seed 42). There is no crash or script exception.
Minimal reproduction and source file
Complete standalone reproduction
The gist includes:
- A 17,434-byte signed
.rivfixture, base64-encoded because gists do not accept binary files, with a decode command and SHA-256 checksum. No CLI login is required to run the supplied file. - Complete
scene.rml,probe.luau, andrive.yamlsource: one artboard, one state machine, one script, three numbers; no application assets. - A runnable
main.swift+run-ios.pyprobe that tests both initialization orders side by side using RiveRuntime 6.28.0. It prints results and asserts both outcomes. - Actual
results.json, a minimal React NativeApp.tsxadapter, andproposed-fix.diff.
Verified native repro steps
- Clone/download the gist and decode
binding-init-repro.riv.b64using the command in its README. - Download the official RiveRuntime 6.28.0 XCFramework.
- With an Apple Silicon iOS simulator booted, run
python3 run-ios.py /path/to/RiveRuntime.xcframework. - Observe
lateBinding: {seed: 42, isReady: 0, observedSeed: 0}andbindingAtCreation: {seed: 42, isReady: 1, observedSeed: 42}.
Both cases create independent artboards and host model instances from the same file. Both seed the model before state-machine creation and use the same deprecated Rive(...dataBind: .instance(model)) initializer afterward. The only difference is supplying binding: model to createStateMachine.
React Native usage
The App.tsx adapter uses useViewModelInstance(riveFile, { async: true, viewModelName: 'ProbeModel', onInit }), seeds seed = 42 in onInit, and mounts RiveView only after the instance exists:
<RiveView
file={riveFile}
artboardName="Binding Probe"
stateMachineName="Main"
dataBind={instance}
autoPlay
fit={Fit.Layout}
style={{ width: 160, height: 160 }}
/>
Use a native development build, add riv to Metro's assetExts, and leave the default iOS new backend enabled. The gist has the complete component and setup notes.
Likely cause / small workaround
The relevant current code is in ios/new/RiveReactNativeView.swift at v0.5.4. It calls createStateMachine(config.stateMachineName) before resolving dataBind and constructing Rive.
Moving state-machine creation after binding resolution and using the explicit-instance overload fixes the isolated probe:
let stateMachine: StateMachine
if case .instance(let vmi) = dataBind {
stateMachine = try await artboard.createStateMachine(
config.stateMachineName, binding: vmi
)
} else {
stateMachine = try await artboard.createStateMachine(config.stateMachineName)
}
The Rive iOS 6.28.0 release guidance also supplies the model at state-machine creation. The attached diff is a narrow workaround for initial explicit-instance binding, not a complete migration or a claim to fix later instance replacement. The broader auto/by-name/rebinding migration can stay under #403.
Environment / validation scope
- Original affected application:
@rive-app/react-native0.5.3, React Native 0.86.0, Expo SDK 57,react-native-nitro-modules0.36.5. - Runtime: iOS new backend, RiveRuntime 6.28.0.
- Standalone Swift repro actually executed on iPhone 17 Pro simulator, iOS 26.5; recorded results are in the gist.
- Latest 0.5.4 source inspected: the relevant initialization order is unchanged and its
runtimeVersions.iosis also 6.28.0. I have not separately run a complete 0.5.4 React Native app. - The generic
App.tsxadapter type-checks against 0.5.3; the executed isolated test is the Swift probe, which follows the wrapper's native initialization sequence. - Android and the legacy iOS backend: not tested for this issue.
- Previous working version: not established.
- Fixture authored with Rive CLI 1.3.0, signed and watermarked. It executes in both native cases, so this is not an unsigned-script rejection.
I searched existing issues and found #403 related, but did not find a report for this specific cached-script-model behavior. Happy to consolidate this reproduction into #403 if that is preferable.
- Lingua principale
- TypeScript
- Stelle
- 154
- Fork
- 16
- Merge medio
- 2g 23h
- PR unite (30g)
- 18
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Nessun modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di rive-app/rive-nitro-react-native
-
useRiveList: removeListeners() on a disposed list property segfaults on unmount in release buildsForse già presa @mfazekas l’ha presa 2 giorni fa. Aperta
Difficoltà 2/5 Meno di un'ora Idoneità per principianti 85/100
rive-app/rive-nitro-react-native#407 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 48/100
rive-app/rive-nitro-react-native#413 ·
I maintainer di solito rispondono entro 1 giorno
-
enhancement iOS
Difficoltà 4/5 3-5 giorni Idoneità per principianti 68/100
rive-app/rive-nitro-react-native#403 ·
I maintainer di solito rispondono entro 1 giorno
-
[Android] RiveFonts: loadFont({name}) fails for script fonts on OEM fonts.xml; systemFallback() is not script-aware (tofu for Thai/Hebrew/Arabic/CJK)Forse già presa @mfazekas l’ha presa 6 giorni fa. Aperta
Difficoltà 3/5 1-2 giorni Idoneità per principianti 65/100
rive-app/rive-nitro-react-native#369 · 3 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 35/100
rive-app/rive-nitro-react-native#58 · 7 commenti ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di rive-app/rive-nitro-react-native
Issue simili
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 85/100
lukilabs/beautiful-mermaid#160 ·
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 66/100
rescript-lang/rescript-lang.org#1420 ·
I maintainer di solito rispondono entro 2 giorni
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
chthollyphile/folia-major#520 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
databuddy-analytics/Databuddy#1106 ·
I maintainer di solito rispondono entro 1 giorno