Conversation
95816cf to
4fe9e12
Compare
8485f9f to
9b4acd8
Compare
There was a problem hiding this comment.
Remaining comments which cannot be posted as a review comment to avoid GitHub Rate Limit
ktlint
🚫 [ktlint] standard:multiline-if-else reported by reviewdog 🐶
Missing { ... }
🚫 [ktlint] standard:chain-method-continuation reported by reviewdog 🐶
Expected newline before '.'
🚫 [ktlint] standard:chain-method-continuation reported by reviewdog 🐶
Expected newline before '.'
🚫 [ktlint] standard:try-catch-finally-spacing reported by reviewdog 🐶
Expected a newline after '{'
🚫 [ktlint] standard:statement-wrapping reported by reviewdog 🐶
Missing newline after '{'
🚫 [ktlint] standard:statement-wrapping reported by reviewdog 🐶
Missing newline before '}'
🚫 [ktlint] standard:try-catch-finally-spacing reported by reviewdog 🐶
Expected a newline before '}'
🚫 [ktlint] standard:try-catch-finally-spacing reported by reviewdog 🐶
Expected a newline after '{'
🚫 [ktlint] standard:statement-wrapping reported by reviewdog 🐶
Missing newline after '{'
🚫 [ktlint] standard:statement-wrapping reported by reviewdog 🐶
Missing newline before '}'
🚫 [ktlint] standard:try-catch-finally-spacing reported by reviewdog 🐶
Expected a newline before '}'
🚫 [ktlint] standard:no-unused-imports reported by reviewdog 🐶
Unused import
🚫 [ktlint] standard:string-template reported by reviewdog 🐶
Redundant curly braces
🚫 [ktlint] standard:if-else-wrapping reported by reviewdog 🐶
Expected a newline
🚫 [ktlint] standard:multiline-if-else reported by reviewdog 🐶
Missing { ... }
🚫 [ktlint] standard:if-else-wrapping reported by reviewdog 🐶
Expected a newline
🚫 [ktlint] standard:multiline-if-else reported by reviewdog 🐶
Missing { ... }
🚫 [ktlint] standard:chain-method-continuation reported by reviewdog 🐶
Expected newline before '.'
🚫 [ktlint] standard:argument-list-wrapping reported by reviewdog 🐶
Argument should be on a separate line (unless all arguments can fit a single line)
🚫 [ktlint] standard:argument-list-wrapping reported by reviewdog 🐶
Argument should be on a separate line (unless all arguments can fit a single line)
🚫 [ktlint] standard:string-template reported by reviewdog 🐶
Redundant curly braces
🚫 [ktlint] standard:max-line-length reported by reviewdog 🐶
Exceeded max line length (140)
🚫 [ktlint] standard:string-template reported by reviewdog 🐶
Redundant curly braces
🚫 [ktlint] standard:argument-list-wrapping reported by reviewdog 🐶
Missing newline before ")"
🚫 [ktlint] standard:statement-wrapping reported by reviewdog 🐶
Missing newline after '{'
🚫 [ktlint] standard:statement-wrapping reported by reviewdog 🐶
Missing newline after ';'
🚫 [ktlint] standard:statement-wrapping reported by reviewdog 🐶
Missing newline before '}'
🚫 [ktlint] standard:statement-wrapping reported by reviewdog 🐶
Missing newline after '{'
🚫 [ktlint] standard:statement-wrapping reported by reviewdog 🐶
Missing newline after ';'
🚫 [ktlint] standard:statement-wrapping reported by reviewdog 🐶
Missing newline before '}'
🚫 [ktlint] standard:if-else-wrapping reported by reviewdog 🐶
A single line if-statement should be kept simple. The 'THEN' may not be wrapped in a block.
🚫 [ktlint] standard:statement-wrapping reported by reviewdog 🐶
Missing newline after '{'
🚫 [ktlint] standard:string-template reported by reviewdog 🐶
Redundant curly braces
🚫 [ktlint] standard:statement-wrapping reported by reviewdog 🐶
Missing newline after ';'
🚫 [ktlint] standard:statement-wrapping reported by reviewdog 🐶
Missing newline before '}'
🚫 [ktlint] standard:chain-method-continuation reported by reviewdog 🐶
Expected newline before '.'
🚫 [ktlint] standard:chain-method-continuation reported by reviewdog 🐶
Expected newline before '.'
🚫 [ktlint] standard:argument-list-wrapping reported by reviewdog 🐶
Argument should be on a separate line (unless all arguments can fit a single line)
🚫 [ktlint] standard:argument-list-wrapping reported by reviewdog 🐶
Argument should be on a separate line (unless all arguments can fit a single line)
🚫 [ktlint] standard:max-line-length reported by reviewdog 🐶
Exceeded max line length (140)
🚫 [ktlint] standard:argument-list-wrapping reported by reviewdog 🐶
Missing newline before ")"
🚫 [ktlint] standard:function-naming reported by reviewdog 🐶
Function name should start with a lowercase letter (except factory methods) and use camel case
🚫 [ktlint] standard:chain-method-continuation reported by reviewdog 🐶
Expected newline before '.'
🚫 [ktlint] standard:argument-list-wrapping reported by reviewdog 🐶
Argument should be on a separate line (unless all arguments can fit a single line)
🚫 [ktlint] standard:argument-list-wrapping reported by reviewdog 🐶
Argument should be on a separate line (unless all arguments can fit a single line)
🚫 [ktlint] standard:max-line-length reported by reviewdog 🐶
Exceeded max line length (140)
🚫 [ktlint] standard:argument-list-wrapping reported by reviewdog 🐶
Missing newline before ")"
dd06b3a to
a5855c9
Compare
There was a problem hiding this comment.
Remaining comments which cannot be posted as a review comment to avoid GitHub Rate Limit
ktlint
🚫 [ktlint] standard:if-else-wrapping reported by reviewdog 🐶
A single line if-statement should be kept simple. The 'THEN' may not be wrapped in a block.
🚫 [ktlint] standard:statement-wrapping reported by reviewdog 🐶
Missing newline after '{'
🚫 [ktlint] standard:string-template reported by reviewdog 🐶
Redundant curly braces
🚫 [ktlint] standard:statement-wrapping reported by reviewdog 🐶
Missing newline after ';'
🚫 [ktlint] standard:statement-wrapping reported by reviewdog 🐶
Missing newline before '}'
🚫 [ktlint] standard:chain-method-continuation reported by reviewdog 🐶
Expected newline before '.'
🚫 [ktlint] standard:chain-method-continuation reported by reviewdog 🐶
Expected newline before '.'
🚫 [ktlint] standard:argument-list-wrapping reported by reviewdog 🐶
Argument should be on a separate line (unless all arguments can fit a single line)
🚫 [ktlint] standard:argument-list-wrapping reported by reviewdog 🐶
Argument should be on a separate line (unless all arguments can fit a single line)
🚫 [ktlint] standard:max-line-length reported by reviewdog 🐶
Exceeded max line length (140)
🚫 [ktlint] standard:argument-list-wrapping reported by reviewdog 🐶
Missing newline before ")"
🚫 [ktlint] standard:function-naming reported by reviewdog 🐶
Function name should start with a lowercase letter (except factory methods) and use camel case
🚫 [ktlint] standard:chain-method-continuation reported by reviewdog 🐶
Expected newline before '.'
🚫 [ktlint] standard:argument-list-wrapping reported by reviewdog 🐶
Argument should be on a separate line (unless all arguments can fit a single line)
🚫 [ktlint] standard:argument-list-wrapping reported by reviewdog 🐶
Argument should be on a separate line (unless all arguments can fit a single line)
🚫 [ktlint] standard:max-line-length reported by reviewdog 🐶
Exceeded max line length (140)
🚫 [ktlint] standard:argument-list-wrapping reported by reviewdog 🐶
Missing newline before ")"
8134a07 to
ec12673
Compare
91e2fb6 to
cfb2ff6
Compare
cfb2ff6 to
44681b5
Compare
44681b5 to
91c487b
Compare
Add new experimental iOS backend (ios/new/) with synchronous API, move legacy backend files to ios/legacy/, add getEnums() support, retry listener streams on missingData, and restore TestComponentOverlay. Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering)
Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering)
getEnums() in legacy now throws directing users to the experimental backend instead of creating throwaway Worker+File instances. Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering)
…essing Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering)
… binding Each Worker has its own C++ command server with its own m_artboards handle map. Creating separate Workers per file meant artboard handles from one file were invalid on another file's server. Using a shared singleton Worker fixes cross-file artboard property set. Also wires fit/alignment through experimental Fit enum and improves asset type detection with audio/font magic bytes. Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>
Passing fit to the Rive() constructor breaks layout mode because the MTKView drawable isn't ready yet. Set rive.fit after setupRiveUIView() instead.
Port Flutter data binding tests for VM access, enums, creation variants, list properties, artboard and image properties. Includes new .riv test assets and react-native-harness upgrade to alpha.25.
…ceByIndex Prevents fatal crash when passing negative numbers to Swift APIs expecting unsigned integers.
CocoaPods doesn't embed SPM-resolved dynamic frameworks automatically. Patches the embed script to include RiveRuntime when USE_RIVE_SPM=1.
Move 19 backend-specific files to src/legacy/java/, add Gradle sourceSets switching via USE_RIVE_NEW_API property, prepare empty experimental dirs.
Uses the new handle-based Rive Android SDK (app.rive.*) with CommandQueue, path-based ViewModelInstance property access, and Kotlin Flows for reactivity. Throws UnsupportedOperationException for SMI inputs, text runs, and events. Also fixes Gradle property resolution to use rootProject.findProperty.
Custom TextureView renderer with Choreographer render loop, CommandQueue polling infrastructure, ViewModel resolution and property validation, and example Compose test activities for manual testing.
- Always use SPM for RiveRuntime (remove CocoaPods fallback) - Add RiveSPMEmbedFix module to auto-embed RiveRuntime.framework - Pin SPM to exactVersion instead of upToNextMajorVersion - Replace USE_RIVE_SPM with USE_RIVE_EXPERIMENTAL_RUNTIME to select legacy vs experimental backend independently of SPM Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ener All backends now emit the current value as the first listener emission, so hooks no longer need a synchronous property.value read on mount. - useRiveProperty: always starts undefined; value arrives via the listener's first callback (not a sync read). Setter updater fn now uses tracked React state instead of property.value. - iOS legacy: Number/String/Boolean/Enum addListener now emits the current value synchronously on subscribe, matching the stream-based behaviour of the experimental backend (valueStream) and Android (Flow with drop=0). No native changes needed elsewhere. - Tests: mock addListener emits current value on subscribe; updated test description to reflect the new async-first semantics. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…erimental iOS test issues - Rename USE_RIVE_EXPERIMENTAL_RUNTIME to USE_RIVE_NEW_API (matches Android) - Remove USE_RIVE_SPM and all SPM embedding hacks from podspec/Podfile - Use standard CocoaPods dependency for RiveRuntime - Emit initial value in experimental addListener (number/string/bool/enum/color) - Guard tests that crash on experimental iOS (list ops, autoPlay, artboard/image loading) - Handle createInstanceByName throwing on experimental backend
f1b851e to
aa2fdf0
Compare
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…leFactory ArrayBufferHolder is a C++ type; the Swift protocol uses ArrayBuffer. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Deprecate the sync properties in favour of non-blocking async methods: - `viewModelCount` → `getViewModelCountAsync()` - `artboardCount` → `getArtboardCountAsync()` - `artboardNames` → `getArtboardNamesAsync()` Implemented across all four backends (iOS new/legacy, Android experimental/legacy) and regenerated nitrogen bindings. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add getValueAsync(), getLengthAsync(), and getInstanceAtAsync() to all ViewModel property types (Number, String, Boolean, Color, Enum, List) across all four backends (iOS new/legacy, Android experimental/legacy). Sync versions are kept but deprecated in favour of the new async methods. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…s, extract shared async helpers - Add missing `import com.margelo.nitro.core.Promise` to all 6 experimental Android ViewModel property files (Boolean, Color, Enum, List, Number, String) - Extract private async helpers in iOS new Color and List to eliminate non-trivial code duplication between deprecated sync and async methods Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The Android Kotlin Style Guide (android: true) is not used by rive-android itself and introduces rules like chain-method-continuation that don't apply well to React Native bridge/Nitro bindings code. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Auto-fixed code style violations via ktlint --format - Disabled if-else-wrapping and condition-wrapping rules in .editorconfig (non-bug style opinions inconsistent with project's permissive approach) - Added scripts/lint-fix-kotlin.sh and yarn lint:fix:kotlin for auto-fixing Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ading
Adds an optional `type` field ('image' | 'font' | 'audio') to
ResolvedReferencedAsset so callers can declare asset types explicitly,
avoiding the deprecated extension/magic-byte inference fallback.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…pe field Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…nctions Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace the old string-based `AssetType(fromExplicit:)` initializer and call site with the new `AssetType(from: RiveAssetType)` initializer that takes the typed enum directly from the nitrogen-generated `asset.type` property. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…pe enum Replace string-based explicit type comparison with a proper enum `when` expression now that nitrogen generates `asset.type` as `RiveAssetType?` instead of `String?`. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ame, set() method - Add `validate?: boolean` (default true) to `viewModelByNameAsync` on all 4 backends; experimental backends skip the getViewModelNames() round-trip when false, legacy backends ignore it (native call already returns nil/null for unknown names) - Rename `createInstanceAsync()` → `createBlankInstanceAsync()` across spec and all 4 backends to make the semantics (blank/empty instance) explicit - Add `set(value)` fire-and-forget method to all 5 property types (Number, String, Boolean, Color, Enum) as the recommended write path; fully deprecate `value` getter and setter - Deprecate `viewModelCount`, `viewModelByIndex`, `viewModelByName` in favour of `getViewModelNamesAsync()` + `viewModelByNameAsync()`; remove removed `getViewModelCountAsync` / `viewModelByIndexAsync` variants - Regenerate nitrogen/ outputs and apply ktlint auto-format Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Nitrogen generates `func set(value: T)` with an external `value:` label,
but our implementations had `func set(_ value: T)` with no external label.
Fixes Swift build error: "instance method 'set' has different argument labels
from those required by protocol 'Hybrid*PropertySpec_protocol' ('set(value:)')".
Also updates the deprecated `value` setter delegate to `try? set(value: newValue)`.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds an explicit test for the contract that `useRiveNumber` delivers its initial value purely from the first listener emission on subscribe — no prop change is required. Uses a tight 1 s timeout to make it fail fast if the hook ever accidentally regresses to relying on a prop update cycle. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Mirror of the existing Data Binding exerciser but with WithViewModelSetup replaced to use `defaultArtboardViewModelAsync()` and `createDefaultInstanceAsync()` instead of the deprecated sync counterparts. Useful for verifying the async path produces identical visual results. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Previously both the sync and async variants ignored `index` and always called createDefaultInstance(). Fix implements createInstanceByIndexImpl which calls getInstanceNames(of:) on the File and picks the name at the requested position, then creates via .name(name, from:). Also adds a post_install Podfile hook that strips the RiveRuntime.Swift submodule from RiveRuntime's modulemaps. Without it the project cannot be built with Xcode 26 / Swift 6.2 because Clang sees conflicting definitions of swift::Optional / swift::String between the pre-built RiveRuntime XCFramework (Swift 6.1 ABI) and the freshly-compiled NitroModules (Swift 6.2 ABI). Closes issue 1 (iOS) from .local/docs/issues.md. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…Android Remove the async variant — callers should use createInstanceByNameAsync instead. The deprecated sync createInstanceByIndex now correctly uses getViewModelInstanceNames + index lookup on Android (was returning default instance). Tests updated to use the sync API.
Were hardcoded to 0. Now use file.getProperties(of:) and file.getInstanceNames(of:) respectively. Tests strengthened to assert > 0 instead of >= 0.
Was accepting both replaced and original values. Now strictly asserts the replacement took effect. Passes on iOS; Android experimental SDK lacks the native bridge method (known limitation).
viewModelImpl was passing the property path as instanceName, which is misleading. The SDK doesn't expose the actual instance name, so leave it as "" (consistent with Android and Issue 11 limitation).
Summary
blockingAsynchelper to bridge async rive-ios API to sync interfacePromise.async {}wrappers (underlying SDK is already sync)useViewModelInstance,useRiveProperty) — no moreuseState+useEffectfor async loadingvaluegetter/setter instead ofgetValue()/setValue()Usage
Without the flags, the legacy backends are used.
TODO
RiveFileAssetsubclasses. Currently inferred from file extensions and magic bytes, but fails for assets with no extension (e.g.referenced_audio-2929340). Fix: add optionaltypein field toResolvedReferencedAsset. This fix is in RN.updateReferencedAssetsdoesn't work in experimental backend. Legacy cachesRiveFileAssetobjects and mutates them in-place (imageAsset.renderImage()). Experimental only hasworker.addGlobalImageAsset()consumed at file load time. ViewModel image properties (imgProp.set()) work fine via data binding — only affects OOB file-level assets.rive::CommandQueue::processMessages()crashes withEXC_BAD_ACCESS. The CADisplayLink fires after the Worker/ViewModelInstance are deallocated. Upstream: rive-ios#418, CDN variant: rive-ios#410valueStreamthrowsmissingDataon empty string — Setting a nested ViewModel string property to""kills the listener permanently. We work around this by restarting the stream on error. Upstream: rive-ios#416play()/pause()/reset()are no-ops — They setisPausedbut nothing reads it. No explicit play/pause, in experimental RiveView.