From 8805e6eea07356633b862bc68cb33d39234f438a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikl=C3=B3s=20Fazekas?= Date: Wed, 29 Apr 2026 06:31:48 +0200 Subject: [PATCH 1/2] fix(ios): pass fit in Rive constructor, bump rive-ios to 6.19.1 Passes fit directly in the Rive() constructor instead of setting it after creation. Removes the layoutSubviews workaround since rive-ios 6.19.1 fixes the MTKView drawable timing issue (rive-ios#443). --- ios/new/HybridRiveFileFactory.swift | 5 +++-- ios/new/HybridRiveView.swift | 2 +- ios/new/RiveReactNativeView.swift | 21 ++------------------- 3 files changed, 6 insertions(+), 22 deletions(-) diff --git a/ios/new/HybridRiveFileFactory.swift b/ios/new/HybridRiveFileFactory.swift index f7f2751c..b0a0f486 100644 --- a/ios/new/HybridRiveFileFactory.swift +++ b/ios/new/HybridRiveFileFactory.swift @@ -1,4 +1,4 @@ -@_spi(RiveExperimental) import RiveRuntime +import RiveRuntime import NitroModules final class HybridRiveFileFactory: HybridRiveFileFactorySpec, @unchecked Sendable { @@ -24,8 +24,9 @@ final class HybridRiveFileFactory: HybridRiveFileFactorySpec, @unchecked Sendabl let data = try await HTTPDataLoader.shared.downloadData(from: fileURL) RCTLog("[HybridRiveFileFactory] fromURL: downloaded \(data.count) bytes") let worker = try await HybridRiveFileFactory.sharedWorkerTask.value - RCTLog("[HybridRiveFileFactory] fromURL: got shared worker") + RCTLog("[HybridRiveFileFactory] fromURL: got shared worker, referencedAssets=\(referencedAssets == nil ? "nil" : "\(referencedAssets!.data?.count ?? -1) assets"), keys=\(referencedAssets?.data?.keys.sorted() ?? [])") await ExperimentalAssetLoader.registerAssets(referencedAssets, on: worker) + RCTLog("[HybridRiveFileFactory] fromURL: assets registered, creating file...") let file = try await File(source: .data(data), worker: worker) RCTLog("[HybridRiveFileFactory] fromURL: created file") return HybridRiveFile(file: file, worker: worker) diff --git a/ios/new/HybridRiveView.swift b/ios/new/HybridRiveView.swift index 59064c4b..0e253c1a 100644 --- a/ios/new/HybridRiveView.swift +++ b/ios/new/HybridRiveView.swift @@ -1,4 +1,4 @@ -@_spi(RiveExperimental) import RiveRuntime +import RiveRuntime import Foundation import NitroModules import UIKit diff --git a/ios/new/RiveReactNativeView.swift b/ios/new/RiveReactNativeView.swift index b486c9e3..200e5ab1 100644 --- a/ios/new/RiveReactNativeView.swift +++ b/ios/new/RiveReactNativeView.swift @@ -1,7 +1,6 @@ import RiveRuntime import NitroModules import UIKit -import MetalKit enum ExperimentalBindData { case none @@ -28,23 +27,8 @@ class RiveReactNativeView: UIView { private var isViewReady = false private var configTask: Task? private var isPaused = false - private var pendingFit: RiveRuntime.Fit? - var autoPlay: Bool = true - override func layoutSubviews() { - super.layoutSubviews() - applyPendingFitIfMTKViewReady() - } - - // https://github.com/rive-app/rive-nitro-react-native/pull/231 - private func applyPendingFitIfMTKViewReady() { - guard let fit = pendingFit, let rive = riveInstance, - riveUIView?.subviews.contains(where: { $0 is MTKView }) == true else { return } - rive.fit = fit - pendingFit = nil - } - func awaitViewReady() async -> Bool { if !isViewReady { await withCheckedContinuation { continuation in @@ -101,7 +85,8 @@ class RiveReactNativeView: UIView { file: config.file, artboard: artboard, stateMachine: stateMachine, - dataBind: dataBind + dataBind: dataBind, + fit: config.fit ) guard !Task.isCancelled else { return } @@ -110,8 +95,6 @@ class RiveReactNativeView: UIView { self.riveInstance = rive self.setupRiveUIView(with: rive) - self.pendingFit = config.fit - if config.autoPlay { self.isPaused = false } From 0ef84aa56fcb71116f622e640b770598746c1e83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikl=C3=B3s=20Fazekas?= Date: Wed, 29 Apr 2026 06:32:16 +0200 Subject: [PATCH 2/2] fix(ios): warn on unsupported updateReferencedAssets, add asset types to OOB example Experimental backend logs a warning when updateReferencedAssets is called since the concurrency API cannot update already-bound artboard assets. Add explicit type fields to OutOfBandAssets example to suppress inference warnings. Bundle kanit_regular.ttf font in expo examples via expo-font. --- example/src/exercisers/OutOfBandAssets.tsx | 15 +++------------ expo-example/app.config.js | 6 ++++++ expo55-example/app.config.js | 6 ++++++ ios/new/ExperimentalAssetLoader.swift | 2 +- ios/new/HybridRiveFile.swift | 11 ++--------- ios/new/HybridRiveFileFactory.swift | 3 +-- 6 files changed, 19 insertions(+), 24 deletions(-) diff --git a/example/src/exercisers/OutOfBandAssets.tsx b/example/src/exercisers/OutOfBandAssets.tsx index 050dbf27..0ad9d93d 100644 --- a/example/src/exercisers/OutOfBandAssets.tsx +++ b/example/src/exercisers/OutOfBandAssets.tsx @@ -22,26 +22,17 @@ export default function OutOfBandAssetsExample() { referencedAssets: { 'Inter-594377': { source: require('../../assets/fonts/Inter-594377.ttf'), - // source: { - // fileName: 'Inter-594377.ttf', - // path: 'fonts', // only needed for Android assets - // }, + type: 'font', }, 'referenced-image-2929282': { source: { uri: uri, }, - // source: { - // fileName: 'referenced-image-2929282.png', - // path: 'images', // only needed for Android assets - // }, + type: 'image', }, 'referenced_audio-2929340': { source: require('../../assets/audio/referenced_audio-2929340.wav'), - // source: { - // fileName: 'referenced_audio-2929340.wav', - // path: 'audio', // only needed for Android assets - // }, + type: 'audio', }, }, } diff --git a/expo-example/app.config.js b/expo-example/app.config.js index d4bd7bae..22dff6ff 100644 --- a/expo-example/app.config.js +++ b/expo-example/app.config.js @@ -47,6 +47,12 @@ module.exports = { assets: ['../example/assets/rive/rewards.riv'], }, ], + [ + 'expo-font', + { + fonts: ['./assets/kanit_regular.ttf'], + }, + ], ], experiments: { typedRoutes: true, diff --git a/expo55-example/app.config.js b/expo55-example/app.config.js index 96354988..db9b4701 100644 --- a/expo55-example/app.config.js +++ b/expo55-example/app.config.js @@ -47,6 +47,12 @@ module.exports = { assets: ['../example/assets/rive/rewards.riv'], }, ], + [ + 'expo-font', + { + fonts: ['./assets/kanit_regular.ttf'], + }, + ], ], experiments: { typedRoutes: true, diff --git a/ios/new/ExperimentalAssetLoader.swift b/ios/new/ExperimentalAssetLoader.swift index d19c2eef..78ce7176 100644 --- a/ios/new/ExperimentalAssetLoader.swift +++ b/ios/new/ExperimentalAssetLoader.swift @@ -1,4 +1,4 @@ -@_spi(RiveExperimental) import RiveRuntime +import RiveRuntime import NitroModules enum AssetType { diff --git a/ios/new/HybridRiveFile.swift b/ios/new/HybridRiveFile.swift index b8ee3c69..4477890a 100644 --- a/ios/new/HybridRiveFile.swift +++ b/ios/new/HybridRiveFile.swift @@ -1,4 +1,4 @@ -@_spi(RiveExperimental) import RiveRuntime +import RiveRuntime import NitroModules class HybridRiveFile: HybridRiveFileSpec { @@ -149,14 +149,7 @@ class HybridRiveFile: HybridRiveFileSpec { } func updateReferencedAssets(referencedAssets: ReferencedAssetsType) { - guard let worker = worker else { - RCTLogWarn("HybridRiveFile.updateReferencedAssets: No worker available") - return - } - RCTLogInfo("HybridRiveFile.updateReferencedAssets: Updating \(referencedAssets.data?.count ?? 0) assets (note: existing artboards won't refresh)") - Task { @MainActor in - await ExperimentalAssetLoader.registerAssets(referencedAssets, on: worker) - } + RCTLogWarn("[Rive] updateReferencedAssets is not supported with the experimental backend — already-rendered artboards cannot be updated. Use the legacy backend for runtime asset swapping.") } func getEnums() throws -> Promise<[RiveEnumDefinition]> { diff --git a/ios/new/HybridRiveFileFactory.swift b/ios/new/HybridRiveFileFactory.swift index b0a0f486..4752cc36 100644 --- a/ios/new/HybridRiveFileFactory.swift +++ b/ios/new/HybridRiveFileFactory.swift @@ -24,9 +24,8 @@ final class HybridRiveFileFactory: HybridRiveFileFactorySpec, @unchecked Sendabl let data = try await HTTPDataLoader.shared.downloadData(from: fileURL) RCTLog("[HybridRiveFileFactory] fromURL: downloaded \(data.count) bytes") let worker = try await HybridRiveFileFactory.sharedWorkerTask.value - RCTLog("[HybridRiveFileFactory] fromURL: got shared worker, referencedAssets=\(referencedAssets == nil ? "nil" : "\(referencedAssets!.data?.count ?? -1) assets"), keys=\(referencedAssets?.data?.keys.sorted() ?? [])") + RCTLog("[HybridRiveFileFactory] fromURL: got shared worker") await ExperimentalAssetLoader.registerAssets(referencedAssets, on: worker) - RCTLog("[HybridRiveFileFactory] fromURL: assets registered, creating file...") let file = try await File(source: .data(data), worker: worker) RCTLog("[HybridRiveFileFactory] fromURL: created file") return HybridRiveFile(file: file, worker: worker)