Skip to content

fix: iOS production builds fail to load bundled .riv assets#12

Merged
mfazekas merged 2 commits intomainfrom
refactor/data-binding-example
Nov 3, 2025
Merged

fix: iOS production builds fail to load bundled .riv assets#12
mfazekas merged 2 commits intomainfrom
refactor/data-binding-example

Conversation

@mfazekas
Copy link
Copy Markdown
Collaborator

@mfazekas mfazekas commented Oct 31, 2025

Problem

iOS production builds fail to load bundled .riv assets with error:

RiveFileFactory.fromResource(...): Could not find Rive file: rewards_source.riv
image

Root Cause

On iOS, resolveAssetSource() returns file:// URLs for bundled assets:

file:///Users/.../RiveExample.app/assets/assets/rive/rewards_source.riv

The previous implementation:

  • Extracted the filename using regex: rewards_source
  • Tried to load via fromResource("rewards_source")
  • This worked in debug builds where assets url-s to the bundler
  • Failed in production builds where assets are packaged as files

Why it failed in production:
In production, assets exist as physical files in the app bundle deeper, not as named resources accessible via Bundle.main.path(forResource:).

Solution

Load bundled assets directly from their file:// URLs instead of trying to extract and load as bundle resources. To support this fix, added fromFileURL() method to RiveFileFactory:

@mfazekas mfazekas force-pushed the refactor/data-binding-example branch from 2ecd9e7 to c35dbd7 Compare October 31, 2025 15:03
@mfazekas mfazekas changed the title feat: add fromFileURL API for cross-platform file:// URL support fix: iOS production builds fail to load bundled .riv assets Oct 31, 2025
@mfazekas mfazekas force-pushed the refactor/data-binding-example branch from c35dbd7 to 80ef83d Compare October 31, 2025 15:09
Fixes production build issue where iOS bundled assets fail to load.

**Problem:**
On iOS, `resolveAssetSource()` returns file:// URLs for bundled
assets: `file:///path/to/app/assets/rive/rewards_source.riv`

The previous implementation tried to extract the filename and load
it as a bundle resource, which only worked in debug builds. In
production, assets are packaged as actual files in the app bundle,
not as named resources accessible via `Bundle.main.path(forResource:)`.

**Previous approach (broken in production):**
```typescript
// Extract "rewards_source" from file URL
const match = assetURI.match(/file:\/\/(.*\/)+(.*)\.riv/);
return RiveFileFactory.fromResource(match[2], loadCdn);
// ❌ Failed: "Could not find Rive file: rewards_source.riv"
```

**New approach (works in debug and production):**
```typescript
// Load directly from file:// URL
return RiveFileFactory.fromFileURL(assetURI, loadCdn);
// ✅ Reads file directly from disk
```

**Implementation:**
- Added `fromFileURL` to `RiveFile.nitro.ts` spec
- Implemented `fromFileURL` in iOS (`HybridRiveFileFactory.swift`)
  - Validates file:// URL scheme
  - Loads data directly from file path using `Data(contentsOf:)`
  - Runs on background thread
- Implemented `fromFileURL` in Android (`HybridRiveFileFactory.kt`)
  - Matches iOS validation behavior
  - Converts URI to path using `java.net.URI`
  - Loads on `Dispatchers.IO` background thread
- Updated `fromSource()` to use `fromFileURL()` for file:// URLs
- Regenerated Nitrogen boilerplate

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@mfazekas mfazekas force-pushed the refactor/data-binding-example branch from 80ef83d to 246eaed Compare October 31, 2025 15:16
@mfazekas mfazekas marked this pull request as ready for review October 31, 2025 15:18
@mfazekas mfazekas requested a review from HayesGordon October 31, 2025 15:19
HayesGordon
HayesGordon previously approved these changes Nov 3, 2025
Copy link
Copy Markdown
Contributor

@HayesGordon HayesGordon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! Thanks for this.

Likely something we can/should revisit for the old runtime as well?

Co-authored-by: Gordon <pggordonhayes@gmail.com>
@mfazekas
Copy link
Copy Markdown
Collaborator Author

mfazekas commented Nov 3, 2025

Looks great! Thanks for this.

Likely something we can/should revisit for the old runtime as well?

We don't have this issue in old runtime, but we don't support require there - which we should

@mfazekas mfazekas merged commit 09e0fae into main Nov 3, 2025
5 checks passed
mfazekas added a commit that referenced this pull request Nov 17, 2025
* fix: iOS production asset loading

Fixes production build issue where iOS bundled assets fail to load.

**Problem:**
On iOS, `resolveAssetSource()` returns file:// URLs for bundled
assets: `file:///path/to/app/assets/rive/rewards_source.riv`

The previous implementation tried to extract the filename and load
it as a bundle resource, which only worked in debug builds. In
production, assets are packaged as actual files in the app bundle,
not as named resources accessible via `Bundle.main.path(forResource:)`.

**Previous approach (broken in production):**
```typescript
// Extract "rewards_source" from file URL
const match = assetURI.match(/file:\/\/(.*\/)+(.*)\.riv/);
return RiveFileFactory.fromResource(match[2], loadCdn);
// ❌ Failed: "Could not find Rive file: rewards_source.riv"
```

**New approach (works in debug and production):**
```typescript
// Load directly from file:// URL
return RiveFileFactory.fromFileURL(assetURI, loadCdn);
// ✅ Reads file directly from disk
```

**Implementation:**
- Added `fromFileURL` to `RiveFile.nitro.ts` spec
- Implemented `fromFileURL` in iOS (`HybridRiveFileFactory.swift`)
  - Validates file:// URL scheme
  - Loads data directly from file path using `Data(contentsOf:)`
  - Runs on background thread
- Implemented `fromFileURL` in Android (`HybridRiveFileFactory.kt`)
  - Matches iOS validation behavior
  - Converts URI to path using `java.net.URI`
  - Loads on `Dispatchers.IO` background thread
- Updated `fromSource()` to use `fromFileURL()` for file:// URLs
- Regenerated Nitrogen boilerplate

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Update src/core/RiveFile.ts

Co-authored-by: Gordon <pggordonhayes@gmail.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Gordon <pggordonhayes@gmail.com>
@HayesGordon HayesGordon deleted the refactor/data-binding-example branch December 9, 2025 16:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants