Back to Blog Home
← all posts

🤘 Rock on with Rive in NativeScript

August 14, 2023 — by Technical Steering Committee (TSC)

Rive allows you to "build interactive animations that run anywhere". They are indeed blazing fast, tiny size and "made for runtime". Read more to understand what Rive aims to solve and have fun exploring the incredible creations from the exciting Rive community.

Let's explore bringing to life several animations from Rive creators such as Bobbeh, @HelloJcToon, @PedroAlpera, including inspirations from @gordonphayes and more...

Get ready to Rive!

Let's install and setup our iOS and Android apps to Rive things up a bit.

npm install @nativescript/rive

We can now setup our app configurations to use it.

Configure iOS

For iOS, configure your nativescript.config.ts to use the Swift Package:

ios: {
    SPMPackages: [
        {
            name: 'RiveRuntime',
            libs: ['RiveRuntime'],
            repositoryURL: 'https://github.com/rive-app/rive-ios.git',
            version: '5.0.0',
        },
    ],
},

Swift Package version note

If you encounter a build error related to a specified version as follows:

xcodebuild: error: Could not resolve package dependencies:
  Dependencies could not be resolved because no versions of 'rive-ios' match the requirement 5.1.12..<6.0.0 and root depends on 'rive-ios' 5.1.12..<6.0.0.

You can use the base major version, 5.0.0, instead of the precise version. It will still resolve the latest in the major version series.

Configure Android

For Android, add this provider to your AndroidManifest.xml inside the application tag:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="__PACKAGE__"
    xmlns:tools="http://schemas.android.com/tools"> <!-- You may need to add this xmlns:tools attr/value -->
    ...

    <application
        android:name="com.tns.NativeScriptApplication"
        ...>

        <!-- Add this for Rive -->
        <provider
                android:name="androidx.startup.InitializationProvider"
                android:authorities="${applicationId}.androidx-startup"
                android:exported="false"
                tools:node="merge">
            <meta-data android:name="app.rive.runtime.kotlin.RiveInitializer"
                        android:value="androidx.startup" />
        </provider>

Prepare RiveView for use

When using flavors, you can register the element for usage in your markup:

import { RiveView } from '@nativescript/rive'

// Angular
import { registerElement } from '@nativescript/angular'
registerElement('RiveView', () => RiveView)

// Solid
import { registerElement } from 'dominative';
registerElement('riveView', RiveView);

// Svelte
import { registerNativeViewElement } from 'svelte-native/dom'
registerNativeViewElement('riveView', () => RiveView);

// React
import { registerElement } from 'react-nativescript';
registerElement('riveView', () => RiveView);

// Vue
import Vue from 'nativescript-vue'
Vue.registerElement('RiveView', () => RiveView)

Use RiveView anywhere.

<RiveView />

Use .riv files

You can use .riv files in the following ways:

  1. (Most often used) -- Locally in your src/assets often referred as ~/assets/file.riv
  2. Remotely via urls like https://cdn.rive.app/animations/vehicles.riv
  3. App_Resources via res://file.riv

You can find rich examples throughout the Rive Community.

You can create your own .riv files using the rich Rive Editor.

RiveView API

You can trigger inputs via state machines and configure artboards through view bindings.

<RiveView 
  src="~/assets/file.riv" 
  artboard="artboard-name" 
  stateMachine="state-machine-name" 
  input="input-name" 
  inputValue="input-value-as-boolean-or-number" 
  autoPlay="true" 
  onStateChanged="state event handler"
/>

You can also trigger inputs programmatically through the RiveView instance.

riveView.triggerInputValue('CHAT', true);

Enjoy rocking with Rive!

Whether you are applying micro animations throughout your app or even contemplating building an entire interactive UI, Rive offers some really cool stuff to get into.

Learn more with the Rive Learning Guide.

Troubleshooting and Solutions

When configuring your Android app for Rive you may run into the following issues. Here's some solutions.

Potential Error 1

Execution failed for task ':app:checkDebugDuplicateClasses'.
Duplicate class kotlin.collections.jdk8.CollectionsJDK8Kt found in modules jetified-kotlin-stdlib-1.8.21 (org.jetbrains.kotlin:kotlin-stdlib:1.8.21) and jetified-kotlin-stdlib-jdk8-1.6.21 (org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.21)
Duplicate class kotlin.internal.jdk7.JDK7PlatformImplementations found in modules jetified-kotlin-stdlib-1.8.21 (org.jetbrains.kotlin:kotlin-stdlib:1.8.21) and jetified-kotlin-stdlib-jdk7-1.6.21 (org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.6.21)

Solution

Add the following dependency constraints to the top of your app.gradle above the android section:

dependencies {
    constraints {
        implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.21" 
        implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.21"
    }
}

Potential Error 2

Execution failed for task ':app:mergeDebugNativeLibs'.
2 files found with path 'lib/arm64-v8a/libc++_shared.so' from inputs:
 - /Users/you/.gradle/caches/transforms-3/fed290951dd20dba6bd42d7106bb3f26/transformed/jetified-rive-android-8.1.3/jni/arm64-v8a/libc++_shared.so

Solution

Add this section to app.gradle android section:

android {
  …
  packagingOptions {
      pickFirst "lib/x86/libc++_shared.so"
      pickFirst "lib/x86_64/libc++_shared.so"
      pickFirst "lib/armeabi-v7a/libc++_shared.so"
      pickFirst "lib/arm64-v8a/libc++_shared.so"
  }
  …
}

Potential Error 3

This version (1.2.0-alpha05) of the Compose Compiler requires Kotlin version 1.6.10 but you appear to be using Kotlin version 1.7.10 which is not known to be compatible.  Please fix your configuration (or `suppressKotlinVersionCompatibilityCheck` but don't say I didn't warn you!).

Solution

Add a before-plugins.gradle file next to your app.gradle containing the following:

ext {
    gradlePluginVersion = "7.3.1"
    kotlinVersion = "1.6.10"
}