Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ enum AssetType {
}

@MainActor
final class ExperimentalAssetLoader {
final class AssetLoader {

static func registerAssets(
_ referencedAssets: ReferencedAssetsType?,
Expand Down Expand Up @@ -161,25 +161,21 @@ final class ExperimentalAssetLoader {
type: AssetType,
worker: Worker
) async throws {
RCTLogInfo("ExperimentalAssetLoader: Registering \(type) asset '\(name)' (\(data.count) bytes)")
switch type {
case .image:
worker.removeGlobalImageAsset(name: name)
let image = try await worker.decodeImage(from: data)
worker.addGlobalImageAsset(image, name: name)
RCTLogInfo("ExperimentalAssetLoader: Image '\(name)' registered successfully")

case .font:
worker.removeGlobalFontAsset(name)
let font = try await worker.decodeFont(from: data)
worker.addGlobalFontAsset(font, name: name)
RCTLogInfo("ExperimentalAssetLoader: Font '\(name)' registered successfully")

case .audio:
worker.removeGlobalAudioAsset(name: name)
let audio = try await worker.decodeAudio(from: data)
worker.addGlobalAudioAsset(audio, name: name)
RCTLogInfo("ExperimentalAssetLoader: Audio '\(name)' registered successfully")
}
}
}
15 changes: 4 additions & 11 deletions ios/new/HybridRiveFileFactory.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,10 @@ final class HybridRiveFileFactory: HybridRiveFileFactorySpec, @unchecked Sendabl
guard let fileURL = URL(string: url) else {
throw RuntimeError.error(withMessage: "Invalid URL: \(url)")
}
RCTLog("[HybridRiveFileFactory] fromURL: downloading \(url)")
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")
await ExperimentalAssetLoader.registerAssets(referencedAssets, on: worker)
await AssetLoader.registerAssets(referencedAssets, on: worker)
let file = try await File(source: .data(data), worker: worker)
RCTLog("[HybridRiveFileFactory] fromURL: created file")
return HybridRiveFile(file: file, worker: worker)
}
}
Expand All @@ -44,7 +40,7 @@ final class HybridRiveFileFactory: HybridRiveFileFactorySpec, @unchecked Sendabl
}
let data = try FileDataLoader().loadData(from: url)
let worker = try await HybridRiveFileFactory.sharedWorkerTask.value
await ExperimentalAssetLoader.registerAssets(referencedAssets, on: worker)
await AssetLoader.registerAssets(referencedAssets, on: worker)
let file = try await File(source: .data(data), worker: worker)
return HybridRiveFile(file: file, worker: worker)
}
Expand All @@ -58,7 +54,7 @@ final class HybridRiveFileFactory: HybridRiveFileFactorySpec, @unchecked Sendabl
throw RuntimeError.error(withMessage: "Could not find Rive file: \(resource).riv")
}
let worker = try await HybridRiveFileFactory.sharedWorkerTask.value
await ExperimentalAssetLoader.registerAssets(referencedAssets, on: worker)
await AssetLoader.registerAssets(referencedAssets, on: worker)
let file = try await File(source: .local(resource, nil), worker: worker)
return HybridRiveFile(file: file, worker: worker)
}
Expand All @@ -68,13 +64,10 @@ final class HybridRiveFileFactory: HybridRiveFileFactorySpec, @unchecked Sendabl
throws -> Promise<(any HybridRiveFileSpec)>
{
let data = bytes.toData(copyIfNeeded: true)
RCTLog("[HybridRiveFileFactory] fromBytes: got \(data.count) bytes")
return Promise.async {
let worker = try await HybridRiveFileFactory.sharedWorkerTask.value
RCTLog("[HybridRiveFileFactory] fromBytes: got shared worker")
await ExperimentalAssetLoader.registerAssets(referencedAssets, on: worker)
await AssetLoader.registerAssets(referencedAssets, on: worker)
let file = try await File(source: .data(data), worker: worker)
RCTLog("[HybridRiveFileFactory] fromBytes: created file")
return HybridRiveFile(file: file, worker: worker)
}
}
Expand Down
14 changes: 7 additions & 7 deletions ios/new/HybridRiveView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ typealias HybridDataBindMode = Variant__any_HybridViewModelInstanceSpec__DataBin

extension Optional
where Wrapped == HybridDataBindMode {
func toExperimentalBindData() throws -> ExperimentalBindData {
func toBindData() throws -> BindData {
guard let value = self else {
return .auto
}
Expand Down Expand Up @@ -195,13 +195,13 @@ class HybridRiveView: HybridRiveViewSpec {
return
}

let config = ExperimentalViewConfiguration(
let config = ViewConfiguration(
artboardName: artboardName,
stateMachineName: stateMachineName,
autoPlay: autoPlay ?? DefaultConfiguration.autoPlay,
file: riveFile,
fit: toExperimentalFit(fit, alignment: alignment, layoutScaleFactor: layoutScaleFactor),
bindData: try dataBind.toExperimentalBindData()
fit: toRiveFit(fit, alignment: alignment, layoutScaleFactor: layoutScaleFactor),
bindData: try dataBind.toBindData()
)

try MainActor.assumeIsolated {
Expand All @@ -222,12 +222,12 @@ class HybridRiveView: HybridRiveViewSpec {
private var initialUpdate = true

// MARK: Helpers
private func toExperimentalFit(
private func toRiveFit(
_ fit: Fit?,
alignment: Alignment?,
layoutScaleFactor: Double?
) -> RiveRuntime.Fit {
let expAlignment = toExperimentalAlignment(alignment) ?? .center
let expAlignment = toRiveAlignment(alignment) ?? .center

switch fit ?? .contain {
case .fill: return .fill(alignment: expAlignment)
Expand All @@ -245,7 +245,7 @@ class HybridRiveView: HybridRiveViewSpec {
}
}

private func toExperimentalAlignment(_ alignment: Alignment?) -> RiveRuntime.Alignment? {
private func toRiveAlignment(_ alignment: Alignment?) -> RiveRuntime.Alignment? {
guard let alignment = alignment else { return nil }

switch alignment {
Expand Down
4 changes: 1 addition & 3 deletions ios/new/HybridViewModelImageProperty.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,14 @@ class HybridViewModelImageProperty: HybridViewModelImagePropertySpec {
do {
let experimentalImage = try await worker.decodeImage(from: hybridImage.rawData)
instance.setValue(of: prop, to: experimentalImage)
RCTLogInfo("HybridViewModelImageProperty: Set image on path '\(prop.path)'")
} catch {
RCTLogError("HybridViewModelImageProperty: Failed to decode/set image: \(error)")
}
}
}

func addListener(onChanged: @escaping () -> Void) throws -> () -> Void {
// TODO: Experimental API image property listener - API changed, needs update
// The triggerStream method may have been removed or renamed
// TODO: image property listener not yet available in concurrency API
return {}
}

Expand Down
4 changes: 2 additions & 2 deletions ios/new/HybridViewModelListProperty.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ class HybridViewModelListProperty: HybridViewModelListPropertySpec {
private let worker: Worker
private var listenerTasks: [UUID: Task<Void, Never>] = [:]

// Note: Experimental API doesn't validate property paths - non-existent properties
// return garbage values instead of throwing. This is a known limitation.
// Note: the concurrency API doesn't validate property paths non-existent
// properties return garbage values instead of throwing.
init(instance: ViewModelInstance, path: String, worker: Worker) {
self.vmiInstance = instance
self.prop = ListProperty(path: path)
Expand Down
15 changes: 4 additions & 11 deletions ios/new/RiveReactNativeView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,20 @@
import NitroModules
import UIKit

enum ExperimentalBindData {
enum BindData {
case none
case auto
case instance(ViewModelInstance)
case byName(String)
}

struct ExperimentalViewConfiguration {
struct ViewConfiguration {
let artboardName: String?
let stateMachineName: String?
let autoPlay: Bool
let file: File
let fit: RiveRuntime.Fit
let bindData: ExperimentalBindData
let bindData: BindData
}

@MainActor
Expand All @@ -38,9 +38,8 @@
return true
}

func configure(_ config: ExperimentalViewConfiguration, dataBindingChanged: Bool = false, reload: Bool = false, initialUpdate: Bool = false) {
func configure(_ config: ViewConfiguration, dataBindingChanged: Bool = false, reload: Bool = false, initialUpdate: Bool = false) {
dispatchPrecondition(condition: .onQueue(.main))
RCTLog("[RiveReactNativeView] configure called - reload: \(reload), dataBindingChanged: \(dataBindingChanged), initialUpdate: \(initialUpdate)")

if reload {
cleanup()
Expand All @@ -51,10 +50,7 @@
configTask = Task { [weak self] in
guard let self else { return }
do {
RCTLog("[RiveReactNativeView] Creating artboard: \(config.artboardName ?? "default")")
let artboard = try await config.file.createArtboard(config.artboardName)

RCTLog("[RiveReactNativeView] Creating state machine: \(config.stateMachineName ?? "default")")
let stateMachine = try await artboard.createStateMachine(config.stateMachineName)

let dataBind: RiveRuntime.DataBind
Expand All @@ -65,7 +61,7 @@
// Probe for a default ViewModel first. If the artboard has none,
// the SDK would fire an error event — skip auto-binding silently instead.
do {
let _ = try await config.file.getDefaultViewModelInfo(for: artboard)

Check warning on line 64 in ios/new/RiveReactNativeView.swift

View workflow job for this annotation

GitHub Actions / lint-swift

Prefer `_ = foo()` over `let _ = foo()` when discarding a result from a function (redundant_discardable_let)
dataBind = .auto
} catch {
dataBind = .none
Expand All @@ -80,7 +76,6 @@

guard !Task.isCancelled else { return }

RCTLog("[RiveReactNativeView] Creating Rive instance...")
let rive = try await RiveRuntime.Rive(
file: config.file,
artboard: artboard,
Expand All @@ -91,7 +86,6 @@

guard !Task.isCancelled else { return }

RCTLog("[RiveReactNativeView] Rive instance created successfully")
self.riveInstance = rive
self.setupRiveUIView(with: rive)

Expand All @@ -106,7 +100,6 @@
}
self.viewReadyContinuations.removeAll()
}
RCTLog("[RiveReactNativeView] Configuration complete!")
} catch {
RCTLogError("[RiveReactNativeView] Failed to configure: \(error)")
}
Expand Down
Loading