diff --git a/.github/workflows/Package.swift.template b/.github/workflows/Package.swift.template
index 623c0d5..fe50445 100644
--- a/.github/workflows/Package.swift.template
+++ b/.github/workflows/Package.swift.template
@@ -3,7 +3,7 @@ import PackageDescription
let package = Package(
name: "RiveRuntime",
- platforms: [.iOS("14.0"), .macOS("13.1")],
+ platforms: [.iOS("14.0"), .visionOS("1.0"), .tvOS("16.0"), .macOS("13.1")],
products: [
.library(
name: "RiveRuntime",
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index bf45e7b..802a873 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -88,6 +88,9 @@ jobs:
- name: Select Xcode 15.4
run: sudo xcodes select 15.4
+
+ - name: Install all Xcode platforms
+ run: xcodebuild -downloadAllPlatforms
- name: Build everything (using the cache, we should make an archive of course)
run: ./scripts/build.sh all
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 15aa4c5..8a352fe 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -40,9 +40,23 @@ jobs:
- name: Select Xcode 15.4
run: sudo xcodes select 15.4
- - name: Build everything (using the cache, we should make an archive of course)
+ - name: Build for iOS Simulator (using the cache, we should make an archive of course)
run: |
./scripts/build.sh ios_sim release
- - name: Testing iOS app
- run: ./scripts/test.sh
+ - name: Test iOS runtime
+ run: ./scripts/test.sh ios_sim
+
+ - name: Build for visionOS Simulator (using the cache, we should make an archive of course)
+ run: |
+ ./scripts/build.sh xrsimulator release
+
+ - name: Test visionOS runtime
+ run: ./scripts/test.sh xrsimulator
+
+ - name: Build for tvOS Simulator (using the cache, we should make an archive of course)
+ run: |
+ ./scripts/build.sh appletvsimulator release
+
+ - name: Test tvOS runtime
+ run: ./scripts/test.sh appletvsimulator
diff --git a/.rive_head b/.rive_head
index 4fa06ac..5d21927 100644
--- a/.rive_head
+++ b/.rive_head
@@ -1 +1 @@
-f69757c8dd221c54942fee2e47bae55df8f6dc12
+6f70a0e803b1eaf43374b98cc4fda6e79163667d
diff --git a/Example-iOS/Assets/streaming.riv b/Example-iOS/Assets/streaming.riv
new file mode 100644
index 0000000..f62d8bd
Binary files /dev/null and b/Example-iOS/Assets/streaming.riv differ
diff --git a/Example-iOS/Example (tvOS)/Assets.xcassets/AccentColor.colorset/Contents.json b/Example-iOS/Example (tvOS)/Assets.xcassets/AccentColor.colorset/Contents.json
new file mode 100644
index 0000000..eb87897
--- /dev/null
+++ b/Example-iOS/Example (tvOS)/Assets.xcassets/AccentColor.colorset/Contents.json
@@ -0,0 +1,11 @@
+{
+ "colors" : [
+ {
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Content.imageset/Contents.json b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Content.imageset/Contents.json
new file mode 100644
index 0000000..2e00335
--- /dev/null
+++ b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Content.imageset/Contents.json
@@ -0,0 +1,11 @@
+{
+ "images" : [
+ {
+ "idiom" : "tv"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Contents.json b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Contents.json
new file mode 100644
index 0000000..73c0059
--- /dev/null
+++ b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Contents.json b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Contents.json
new file mode 100644
index 0000000..de59d88
--- /dev/null
+++ b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Contents.json
@@ -0,0 +1,17 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "layers" : [
+ {
+ "filename" : "Front.imagestacklayer"
+ },
+ {
+ "filename" : "Middle.imagestacklayer"
+ },
+ {
+ "filename" : "Back.imagestacklayer"
+ }
+ ]
+}
diff --git a/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Content.imageset/Contents.json b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Content.imageset/Contents.json
new file mode 100644
index 0000000..2e00335
--- /dev/null
+++ b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Content.imageset/Contents.json
@@ -0,0 +1,11 @@
+{
+ "images" : [
+ {
+ "idiom" : "tv"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Contents.json b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Contents.json
new file mode 100644
index 0000000..73c0059
--- /dev/null
+++ b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json
new file mode 100644
index 0000000..2e00335
--- /dev/null
+++ b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json
@@ -0,0 +1,11 @@
+{
+ "images" : [
+ {
+ "idiom" : "tv"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Contents.json b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Contents.json
new file mode 100644
index 0000000..73c0059
--- /dev/null
+++ b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json
new file mode 100644
index 0000000..795cce1
--- /dev/null
+++ b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json
@@ -0,0 +1,16 @@
+{
+ "images" : [
+ {
+ "idiom" : "tv",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "tv",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Contents.json b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Contents.json
new file mode 100644
index 0000000..73c0059
--- /dev/null
+++ b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Contents.json b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Contents.json
new file mode 100644
index 0000000..de59d88
--- /dev/null
+++ b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Contents.json
@@ -0,0 +1,17 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "layers" : [
+ {
+ "filename" : "Front.imagestacklayer"
+ },
+ {
+ "filename" : "Middle.imagestacklayer"
+ },
+ {
+ "filename" : "Back.imagestacklayer"
+ }
+ ]
+}
diff --git a/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json
new file mode 100644
index 0000000..795cce1
--- /dev/null
+++ b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json
@@ -0,0 +1,16 @@
+{
+ "images" : [
+ {
+ "idiom" : "tv",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "tv",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Contents.json b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Contents.json
new file mode 100644
index 0000000..73c0059
--- /dev/null
+++ b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json
new file mode 100644
index 0000000..795cce1
--- /dev/null
+++ b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json
@@ -0,0 +1,16 @@
+{
+ "images" : [
+ {
+ "idiom" : "tv",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "tv",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Contents.json b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Contents.json
new file mode 100644
index 0000000..73c0059
--- /dev/null
+++ b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Contents.json b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Contents.json
new file mode 100644
index 0000000..f47ba43
--- /dev/null
+++ b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Contents.json
@@ -0,0 +1,32 @@
+{
+ "assets" : [
+ {
+ "filename" : "App Icon - App Store.imagestack",
+ "idiom" : "tv",
+ "role" : "primary-app-icon",
+ "size" : "1280x768"
+ },
+ {
+ "filename" : "App Icon.imagestack",
+ "idiom" : "tv",
+ "role" : "primary-app-icon",
+ "size" : "400x240"
+ },
+ {
+ "filename" : "Top Shelf Image Wide.imageset",
+ "idiom" : "tv",
+ "role" : "top-shelf-image-wide",
+ "size" : "2320x720"
+ },
+ {
+ "filename" : "Top Shelf Image.imageset",
+ "idiom" : "tv",
+ "role" : "top-shelf-image",
+ "size" : "1920x720"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image Wide.imageset/Contents.json b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image Wide.imageset/Contents.json
new file mode 100644
index 0000000..795cce1
--- /dev/null
+++ b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image Wide.imageset/Contents.json
@@ -0,0 +1,16 @@
+{
+ "images" : [
+ {
+ "idiom" : "tv",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "tv",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/Contents.json b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/Contents.json
new file mode 100644
index 0000000..795cce1
--- /dev/null
+++ b/Example-iOS/Example (tvOS)/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/Contents.json
@@ -0,0 +1,16 @@
+{
+ "images" : [
+ {
+ "idiom" : "tv",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "tv",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Example-iOS/Example (tvOS)/Assets.xcassets/Contents.json b/Example-iOS/Example (tvOS)/Assets.xcassets/Contents.json
new file mode 100644
index 0000000..73c0059
--- /dev/null
+++ b/Example-iOS/Example (tvOS)/Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Example-iOS/Example (tvOS)/ContentView.swift b/Example-iOS/Example (tvOS)/ContentView.swift
new file mode 100644
index 0000000..443c7b3
--- /dev/null
+++ b/Example-iOS/Example (tvOS)/ContentView.swift
@@ -0,0 +1,107 @@
+//
+// ContentView.swift
+// Example (tvOS)
+//
+// Created by David Skuza on 10/29/24.
+// Copyright © 2024 Rive. All rights reserved.
+//
+
+import SwiftUI
+import UIKit
+import RiveRuntime
+
+class ContentViewModel: ObservableObject {
+ struct State: Equatable {
+ let first: Bool
+ let big: Bool
+
+ init(first: Bool = true, big: Bool = true) {
+ self.first = first
+ self.big = big
+ }
+ }
+
+ private let rive: RiveViewModel
+ private var state = State() {
+ didSet {
+ rive.setInput("Big", value: state.big)
+ rive.setInput("First", value: state.first)
+ }
+ }
+
+ init(rive: RiveViewModel) {
+ self.rive = rive
+ }
+
+ func start() {
+ let upGesture = UITapGestureRecognizer(target: self, action: #selector(up))
+ let up = UIPress.PressType.upArrow
+ upGesture.allowedPressTypes = [NSNumber(integerLiteral: up.rawValue)]
+ rive.riveView?.addGestureRecognizer(upGesture)
+
+ let downGesture = UITapGestureRecognizer(target: self, action: #selector(down))
+ let down = UIPress.PressType.downArrow
+ downGesture.allowedPressTypes = [NSNumber(integerLiteral: down.rawValue)]
+ rive.riveView?.addGestureRecognizer(downGesture)
+
+ let leftGesture = UITapGestureRecognizer(target: self, action: #selector(left))
+ let left = UIPress.PressType.leftArrow
+ leftGesture.allowedPressTypes = [NSNumber(integerLiteral: left.rawValue)]
+ rive.riveView?.addGestureRecognizer(leftGesture)
+
+ let rightGesture = UITapGestureRecognizer(target: self, action: #selector(right))
+ let right = UIPress.PressType.rightArrow
+ rightGesture.allowedPressTypes = [NSNumber(integerLiteral: right.rawValue)]
+ rive.riveView?.addGestureRecognizer(rightGesture)
+ }
+
+ @objc func up() {
+ let newState = State(first: state.first, big: true)
+ guard newState != state else { return }
+ state = newState
+ }
+
+ @objc func down() {
+ let newState = State(first: state.first, big: false)
+ guard newState != state else { return }
+ state = newState
+ }
+
+ @objc func left() {
+ let newState = State(first: true, big: state.big)
+ guard newState != state else { return }
+ state = newState
+
+ }
+
+ @objc func right() {
+ let newState = State(first: false, big: state.big)
+ guard newState != state else { return }
+ state = newState
+ }
+}
+
+struct ContentView: View {
+ @StateObject var rive: RiveViewModel
+ @StateObject var viewModel: ContentViewModel
+
+ init() {
+ let rive = RiveViewModel(fileName: "streaming")
+ _rive = StateObject(wrappedValue: rive)
+
+ let viewModel = ContentViewModel(rive: rive)
+ _viewModel = StateObject(wrappedValue: viewModel)
+ }
+
+ var body: some View {
+ rive
+ .view()
+ .onAppear {
+ viewModel.start()
+ }
+ }
+}
+
+#Preview {
+ ContentView()
+}
diff --git a/Example-iOS/Example (tvOS)/Example__tvOS_App.swift b/Example-iOS/Example (tvOS)/Example__tvOS_App.swift
new file mode 100644
index 0000000..466af92
--- /dev/null
+++ b/Example-iOS/Example (tvOS)/Example__tvOS_App.swift
@@ -0,0 +1,18 @@
+//
+// Example__tvOS_App.swift
+// Example (tvOS)
+//
+// Created by David Skuza on 10/29/24.
+// Copyright © 2024 Rive. All rights reserved.
+//
+
+import SwiftUI
+
+@main
+struct Example__tvOS_App: App {
+ var body: some Scene {
+ WindowGroup {
+ ContentView()
+ }
+ }
+}
diff --git a/Example-iOS/Example (tvOS)/Preview Content/Preview Assets.xcassets/Contents.json b/Example-iOS/Example (tvOS)/Preview Content/Preview Assets.xcassets/Contents.json
new file mode 100644
index 0000000..73c0059
--- /dev/null
+++ b/Example-iOS/Example (tvOS)/Preview Content/Preview Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Example-iOS/Example (visionOS)/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Content.imageset/Contents.json b/Example-iOS/Example (visionOS)/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Content.imageset/Contents.json
new file mode 100644
index 0000000..04056a5
--- /dev/null
+++ b/Example-iOS/Example (visionOS)/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Content.imageset/Contents.json
@@ -0,0 +1,12 @@
+{
+ "images" : [
+ {
+ "idiom" : "vision",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Example-iOS/Example (visionOS)/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Contents.json b/Example-iOS/Example (visionOS)/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Contents.json
new file mode 100644
index 0000000..73c0059
--- /dev/null
+++ b/Example-iOS/Example (visionOS)/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Example-iOS/Example (visionOS)/Assets.xcassets/AppIcon.solidimagestack/Contents.json b/Example-iOS/Example (visionOS)/Assets.xcassets/AppIcon.solidimagestack/Contents.json
new file mode 100644
index 0000000..950af4d
--- /dev/null
+++ b/Example-iOS/Example (visionOS)/Assets.xcassets/AppIcon.solidimagestack/Contents.json
@@ -0,0 +1,17 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ },
+ "layers" : [
+ {
+ "filename" : "Front.solidimagestacklayer"
+ },
+ {
+ "filename" : "Middle.solidimagestacklayer"
+ },
+ {
+ "filename" : "Back.solidimagestacklayer"
+ }
+ ]
+}
diff --git a/Example-iOS/Example (visionOS)/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Content.imageset/Contents.json b/Example-iOS/Example (visionOS)/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Content.imageset/Contents.json
new file mode 100644
index 0000000..04056a5
--- /dev/null
+++ b/Example-iOS/Example (visionOS)/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Content.imageset/Contents.json
@@ -0,0 +1,12 @@
+{
+ "images" : [
+ {
+ "idiom" : "vision",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Example-iOS/Example (visionOS)/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Contents.json b/Example-iOS/Example (visionOS)/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Contents.json
new file mode 100644
index 0000000..73c0059
--- /dev/null
+++ b/Example-iOS/Example (visionOS)/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Example-iOS/Example (visionOS)/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Content.imageset/Contents.json b/Example-iOS/Example (visionOS)/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Content.imageset/Contents.json
new file mode 100644
index 0000000..04056a5
--- /dev/null
+++ b/Example-iOS/Example (visionOS)/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Content.imageset/Contents.json
@@ -0,0 +1,12 @@
+{
+ "images" : [
+ {
+ "idiom" : "vision",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Example-iOS/Example (visionOS)/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Contents.json b/Example-iOS/Example (visionOS)/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Contents.json
new file mode 100644
index 0000000..73c0059
--- /dev/null
+++ b/Example-iOS/Example (visionOS)/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Example-iOS/Example (visionOS)/Assets.xcassets/Contents.json b/Example-iOS/Example (visionOS)/Assets.xcassets/Contents.json
new file mode 100644
index 0000000..da4a164
--- /dev/null
+++ b/Example-iOS/Example (visionOS)/Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/Example-iOS/Example (visionOS)/ContentView.swift b/Example-iOS/Example (visionOS)/ContentView.swift
new file mode 100644
index 0000000..66caccd
--- /dev/null
+++ b/Example-iOS/Example (visionOS)/ContentView.swift
@@ -0,0 +1,22 @@
+//
+// ContentView.swift
+// Example (visionOS)
+//
+// Created by David Skuza on 10/25/24.
+// Copyright © 2024 Rive. All rights reserved.
+//
+
+import SwiftUI
+import RiveRuntime
+
+struct ContentView: View {
+ @StateObject var viewModel = RiveViewModel(fileName: "streaming", fit: .fill)
+
+ var body: some View {
+ viewModel.view()
+ }
+}
+
+#Preview(windowStyle: .automatic) {
+ ContentView()
+}
diff --git a/Example-iOS/Example (visionOS)/Example__visionOS_App.swift b/Example-iOS/Example (visionOS)/Example__visionOS_App.swift
new file mode 100644
index 0000000..01d14a5
--- /dev/null
+++ b/Example-iOS/Example (visionOS)/Example__visionOS_App.swift
@@ -0,0 +1,18 @@
+//
+// Example__visionOS_App.swift
+// Example (visionOS)
+//
+// Created by David Skuza on 10/25/24.
+// Copyright © 2024 Rive. All rights reserved.
+//
+
+import SwiftUI
+
+@main
+struct Example__visionOS_App: App {
+ var body: some Scene {
+ WindowGroup {
+ ContentView()
+ }
+ }
+}
diff --git a/Example-iOS/Example (visionOS)/Info.plist b/Example-iOS/Example (visionOS)/Info.plist
new file mode 100644
index 0000000..20f75e2
--- /dev/null
+++ b/Example-iOS/Example (visionOS)/Info.plist
@@ -0,0 +1,15 @@
+
+
+
+
+ UIApplicationSceneManifest
+
+ UIApplicationPreferredDefaultSceneSessionRole
+ UIWindowSceneSessionRoleApplication
+ UIApplicationSupportsMultipleScenes
+
+ UISceneConfigurations
+
+
+
+
diff --git a/Example-iOS/Example (visionOS)/Preview Content/Preview Assets.xcassets/Contents.json b/Example-iOS/Example (visionOS)/Preview Content/Preview Assets.xcassets/Contents.json
new file mode 100644
index 0000000..73c0059
--- /dev/null
+++ b/Example-iOS/Example (visionOS)/Preview Content/Preview Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/Example-iOS/Packages/RealityKitContent/Package.realitycomposerpro/ProjectData/main.json b/Example-iOS/Packages/RealityKitContent/Package.realitycomposerpro/ProjectData/main.json
new file mode 100644
index 0000000..4a8c74b
--- /dev/null
+++ b/Example-iOS/Packages/RealityKitContent/Package.realitycomposerpro/ProjectData/main.json
@@ -0,0 +1,11 @@
+{
+ "pathsToIds" : {
+ "\/RealityKitContent\/Sources\/RealityKitContent\/RealityKitContent.rkassets\/GridMaterial.usda" : "440DE5B4-E4E4-459B-AABF-9ACE96319272",
+ "\/RealityKitContent\/Sources\/RealityKitContent\/RealityKitContent.rkassets\/procedural_sphere_grid.usda" : "34C460AE-CA1B-4348-BD05-621ACBDFFE97",
+ "\/RealityKitContent\/Sources\/RealityKitContent\/RealityKitContent.rkassets\/Scene.usda" : "0A9B4653-B11E-4D6A-850E-C6FCB621626C",
+ "\/RealityKitContent\/Sources\/RealityKitContent\/RealityKitContent.rkassets\/Untitled Scene.usda" : "03E02005-EFA6-48D6-8A76-05B2822A74E9",
+ "RealityKitContent\/Sources\/RealityKitContent\/RealityKitContent.rkassets\/GridMaterial.usda" : "FBD8436F-6B8B-4B82-99B5-995D538B4704",
+ "RealityKitContent\/Sources\/RealityKitContent\/RealityKitContent.rkassets\/procedural_sphere_grid.usda" : "1CBF3893-ABFD-408C-8B91-045BFD257808",
+ "RealityKitContent\/Sources\/RealityKitContent\/RealityKitContent.rkassets\/Scene.usda" : "26DBAE76-5DD8-47B6-A085-1B4ADA111097"
+ }
+}
\ No newline at end of file
diff --git a/Example-iOS/Packages/RealityKitContent/Package.realitycomposerpro/WorkspaceData/SceneMetadataList.json b/Example-iOS/Packages/RealityKitContent/Package.realitycomposerpro/WorkspaceData/SceneMetadataList.json
new file mode 100644
index 0000000..1d84a75
--- /dev/null
+++ b/Example-iOS/Packages/RealityKitContent/Package.realitycomposerpro/WorkspaceData/SceneMetadataList.json
@@ -0,0 +1,209 @@
+{
+ "0A9B4653-B11E-4D6A-850E-C6FCB621626C" : {
+ "cameraTransform" : [
+ 0.9807314,
+ -1.9820146e-10,
+ -0.195361,
+ 0,
+ -0.10051192,
+ 0.85749435,
+ -0.5045798,
+ 0,
+ 0.16752096,
+ 0.51449335,
+ 0.84097165,
+ 0,
+ 0.09084191,
+ 0.05849296,
+ 0.13903293,
+ 1
+ ],
+ "objectMetadataList" : [
+ [
+ "0A9B4653-B11E-4D6A-850E-C6FCB621626C",
+ "Root"
+ ],
+ {
+ "isExpanded" : true,
+ "isLocked" : false
+ },
+ [
+ "0A9B4653-B11E-4D6A-850E-C6FCB621626C",
+ "Root",
+ "GridMaterial"
+ ],
+ {
+ "isExpanded" : true,
+ "isLocked" : false
+ },
+ [
+ "0A9B4653-B11E-4D6A-850E-C6FCB621626C",
+ "Root",
+ "Sphere"
+ ],
+ {
+ "isExpanded" : true,
+ "isLocked" : false
+ }
+ ]
+ },
+ "1CBF3893-ABFD-408C-8B91-045BFD257808" : {
+ "cameraTransform" : [
+ 0.99999994,
+ 0,
+ -0,
+ 0,
+ -0,
+ 0.8660255,
+ -0.49999988,
+ 0,
+ 0,
+ 0.49999988,
+ 0.8660255,
+ 0,
+ 0,
+ 0.27093542,
+ 0.46927398,
+ 1
+ ],
+ "objectMetadataList" : [
+
+ ]
+ },
+ "03E02005-EFA6-48D6-8A76-05B2822A74E9" : {
+ "cameraTransform" : [
+ 0.99999994,
+ 0,
+ -0,
+ 0,
+ -0,
+ 0.8660254,
+ -0.49999994,
+ 0,
+ 0,
+ 0.49999994,
+ 0.8660254,
+ 0,
+ 0,
+ 0.5981957,
+ 1.0361054,
+ 1
+ ],
+ "objectMetadataList" : [
+
+ ]
+ },
+ "26DBAE76-5DD8-47B6-A085-1B4ADA111097" : {
+ "cameraTransform" : [
+ 1,
+ 0,
+ -0,
+ 0,
+ -0,
+ 0.7071069,
+ -0.7071067,
+ 0,
+ 0,
+ 0.7071067,
+ 0.7071069,
+ 0,
+ 0,
+ 0.2681068,
+ 0.26850593,
+ 1
+ ],
+ "objectMetadataList" : [
+ [
+ "26DBAE76-5DD8-47B6-A085-1B4ADA111097",
+ "Root"
+ ],
+ {
+ "isExpanded" : true,
+ "isLocked" : false
+ }
+ ]
+ },
+ "34C460AE-CA1B-4348-BD05-621ACBDFFE97" : {
+ "cameraTransform" : [
+ 0.99999994,
+ 0,
+ -0,
+ 0,
+ -0,
+ 0.8660255,
+ -0.49999988,
+ 0,
+ 0,
+ 0.49999988,
+ 0.8660255,
+ 0,
+ 0,
+ 0.27093542,
+ 0.46927398,
+ 1
+ ],
+ "objectMetadataList" : [
+
+ ]
+ },
+ "440DE5B4-E4E4-459B-AABF-9ACE96319272" : {
+ "cameraTransform" : [
+ 0.99999994,
+ 0,
+ -0,
+ 0,
+ -0,
+ 0.8660254,
+ -0.49999994,
+ 0,
+ 0,
+ 0.49999994,
+ 0.8660254,
+ 0,
+ 0,
+ 0.5981957,
+ 1.0361054,
+ 1
+ ],
+ "objectMetadataList" : [
+ [
+ "440DE5B4-E4E4-459B-AABF-9ACE96319272",
+ "Root"
+ ],
+ {
+ "isExpanded" : true,
+ "isLocked" : false
+ }
+ ]
+ },
+ "FBD8436F-6B8B-4B82-99B5-995D538B4704" : {
+ "cameraTransform" : [
+ 0.99999994,
+ 0,
+ -0,
+ 0,
+ -0,
+ 0.8660254,
+ -0.49999994,
+ 0,
+ 0,
+ 0.49999994,
+ 0.8660254,
+ 0,
+ 0,
+ 0.5981957,
+ 1.0361054,
+ 1
+ ],
+ "objectMetadataList" : [
+ [
+ "FBD8436F-6B8B-4B82-99B5-995D538B4704",
+ "Root"
+ ],
+ {
+ "isExpanded" : true,
+ "isLocked" : false
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/Example-iOS/Packages/RealityKitContent/Package.realitycomposerpro/WorkspaceData/Settings.rcprojectdata b/Example-iOS/Packages/RealityKitContent/Package.realitycomposerpro/WorkspaceData/Settings.rcprojectdata
new file mode 100644
index 0000000..6dea95c
--- /dev/null
+++ b/Example-iOS/Packages/RealityKitContent/Package.realitycomposerpro/WorkspaceData/Settings.rcprojectdata
@@ -0,0 +1,17 @@
+{
+ "cameraPresets" : {
+
+ },
+ "secondaryToolbarData" : {
+ "isGridVisible" : true,
+ "sceneReverbPreset" : -1
+ },
+ "unitDefaults" : {
+ "°" : "°",
+ "kg" : "g",
+ "m" : "cm",
+ "m\/s" : "m\/s",
+ "m\/s²" : "m\/s²",
+ "s" : "s"
+ }
+}
\ No newline at end of file
diff --git a/Example-iOS/Packages/RealityKitContent/Package.swift b/Example-iOS/Packages/RealityKitContent/Package.swift
new file mode 100644
index 0000000..d043ae1
--- /dev/null
+++ b/Example-iOS/Packages/RealityKitContent/Package.swift
@@ -0,0 +1,25 @@
+// swift-tools-version:5.9
+// The swift-tools-version declares the minimum version of Swift required to build this package.
+
+import PackageDescription
+
+let package = Package(
+ name: "RealityKitContent",
+ products: [
+ // Products define the executables and libraries a package produces, and make them visible to other packages.
+ .library(
+ name: "RealityKitContent",
+ targets: ["RealityKitContent"]),
+ ],
+ dependencies: [
+ // Dependencies declare other packages that this package depends on.
+ // .package(url: /* package url */, from: "1.0.0"),
+ ],
+ targets: [
+ // Targets are the basic building blocks of a package. A target can define a module or a test suite.
+ // Targets can depend on other targets in this package, and on products in packages this package depends on.
+ .target(
+ name: "RealityKitContent",
+ dependencies: []),
+ ]
+)
\ No newline at end of file
diff --git a/Example-iOS/Packages/RealityKitContent/README.md b/Example-iOS/Packages/RealityKitContent/README.md
new file mode 100644
index 0000000..486b575
--- /dev/null
+++ b/Example-iOS/Packages/RealityKitContent/README.md
@@ -0,0 +1,3 @@
+# RealityKitContent
+
+A description of this package.
\ No newline at end of file
diff --git a/Example-iOS/Packages/RealityKitContent/Sources/RealityKitContent/RealityKitContent.rkassets/Materials/GridMaterial.usda b/Example-iOS/Packages/RealityKitContent/Sources/RealityKitContent/RealityKitContent.rkassets/Materials/GridMaterial.usda
new file mode 100644
index 0000000..b7afd02
--- /dev/null
+++ b/Example-iOS/Packages/RealityKitContent/Sources/RealityKitContent/RealityKitContent.rkassets/Materials/GridMaterial.usda
@@ -0,0 +1,216 @@
+#usda 1.0
+(
+ defaultPrim = "Root"
+ metersPerUnit = 1
+ upAxis = "Y"
+)
+
+def Xform "Root"
+{
+ def Material "GridMaterial"
+ {
+ reorder nameChildren = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "DefaultSurfaceShader", "MaterialXPreviewSurface", "Texcoord", "Add", "Multiply", "Fractional", "LineCounts", "Multiply_1", "Separate2", "Separate2_1", "Ifgreater", "Ifgreater_1", "Max", "Background_Color"]
+ token outputs:mtlx:surface.connect =
+ token outputs:realitykit:vertex
+ token outputs:surface
+ float2 ui:nodegraph:realitykit:subgraphOutputs:pos = (2222, 300.5)
+ float2 ui:nodegraph:realitykit:subgraphOutputs:size = (182, 89)
+ int ui:nodegraph:realitykit:subgraphOutputs:stackingOrder = 749
+
+ def Shader "DefaultSurfaceShader"
+ {
+ uniform token info:id = "UsdPreviewSurface"
+ color3f inputs:diffuseColor = (1, 1, 1)
+ float inputs:roughness = 0.75
+ token outputs:surface
+ }
+
+ def Shader "MaterialXPreviewSurface"
+ {
+ uniform token info:id = "ND_UsdPreviewSurface_surfaceshader"
+ float inputs:clearcoat
+ float inputs:clearcoatRoughness
+ color3f inputs:diffuseColor.connect =
+ color3f inputs:emissiveColor
+ float inputs:ior
+ float inputs:metallic = 0.15
+ float3 inputs:normal
+ float inputs:occlusion
+ float inputs:opacity
+ float inputs:opacityThreshold
+ float inputs:roughness = 0.5
+ token outputs:out
+ float2 ui:nodegraph:node:pos = (1967, 300.5)
+ float2 ui:nodegraph:node:size = (208, 297)
+ int ui:nodegraph:node:stackingOrder = 870
+ string[] ui:nodegraph:realitykit:node:attributesShowingChildren = ["Advanced"]
+ }
+
+ def Shader "Texcoord"
+ {
+ uniform token info:id = "ND_texcoord_vector2"
+ float2 outputs:out
+ float2 ui:nodegraph:node:pos = (94.14453, 35.29297)
+ float2 ui:nodegraph:node:size = (182, 43)
+ int ui:nodegraph:node:stackingOrder = 1358
+ }
+
+ def Shader "Multiply"
+ {
+ uniform token info:id = "ND_multiply_vector2"
+ float2 inputs:in1.connect =
+ float2 inputs:in2 = (32, 15)
+ float2 inputs:in2.connect =
+ float2 outputs:out
+ float2 ui:nodegraph:node:pos = (275.64453, 47.29297)
+ float2 ui:nodegraph:node:size = (61, 36)
+ int ui:nodegraph:node:stackingOrder = 1348
+ string[] ui:nodegraph:realitykit:node:attributesShowingChildren = ["inputs:in2"]
+ }
+
+ def Shader "Fractional"
+ {
+ uniform token info:id = "ND_realitykit_fractional_vector2"
+ float2 inputs:in.connect =
+ float2 outputs:out
+ float2 ui:nodegraph:node:pos = (440.5, 49.5)
+ float2 ui:nodegraph:node:size = (155, 99)
+ int ui:nodegraph:node:stackingOrder = 1345
+ }
+
+ def Shader "BaseColor"
+ {
+ uniform token info:id = "ND_constant_color3"
+ color3f inputs:value = (0.89737034, 0.89737034, 0.89737034) (
+ colorSpace = "Input - Texture - sRGB - sRGB"
+ )
+ color3f inputs:value.connect = None
+ color3f outputs:out
+ float2 ui:nodegraph:node:pos = (1537.5977, 363.07812)
+ float2 ui:nodegraph:node:size = (150, 43)
+ int ui:nodegraph:node:stackingOrder = 1353
+ }
+
+ def Shader "LineColor"
+ {
+ uniform token info:id = "ND_constant_color3"
+ color3f inputs:value = (0.55945957, 0.55945957, 0.55945957) (
+ colorSpace = "Input - Texture - sRGB - sRGB"
+ )
+ color3f inputs:value.connect = None
+ color3f outputs:out
+ float2 ui:nodegraph:node:pos = (1536.9844, 287.86328)
+ float2 ui:nodegraph:node:size = (146, 43)
+ int ui:nodegraph:node:stackingOrder = 1355
+ }
+
+ def Shader "LineWidths"
+ {
+ uniform token info:id = "ND_combine2_vector2"
+ float inputs:in1 = 0.1
+ float inputs:in2 = 0.1
+ float2 outputs:out
+ float2 ui:nodegraph:node:pos = (443.64453, 233.79297)
+ float2 ui:nodegraph:node:size = (151, 43)
+ int ui:nodegraph:node:stackingOrder = 1361
+ }
+
+ def Shader "LineCounts"
+ {
+ uniform token info:id = "ND_combine2_vector2"
+ float inputs:in1 = 24
+ float inputs:in2 = 12
+ float2 outputs:out
+ float2 ui:nodegraph:node:pos = (94.14453, 138.29297)
+ float2 ui:nodegraph:node:size = (153, 43)
+ int ui:nodegraph:node:stackingOrder = 1359
+ }
+
+ def Shader "Remap"
+ {
+ uniform token info:id = "ND_remap_color3"
+ color3f inputs:in.connect =
+ color3f inputs:inhigh.connect = None
+ color3f inputs:inlow.connect = None
+ color3f inputs:outhigh.connect =
+ color3f inputs:outlow.connect =
+ color3f outputs:out
+ float2 ui:nodegraph:node:pos = (1755.5, 300.5)
+ float2 ui:nodegraph:node:size = (95, 171)
+ int ui:nodegraph:node:stackingOrder = 1282
+ string[] ui:nodegraph:realitykit:node:attributesShowingChildren = ["inputs:outlow"]
+ }
+
+ def Shader "Separate2"
+ {
+ uniform token info:id = "ND_separate2_vector2"
+ float2 inputs:in.connect =
+ float outputs:outx
+ float outputs:outy
+ float2 ui:nodegraph:node:pos = (1212.6445, 128.91797)
+ float2 ui:nodegraph:node:size = (116, 117)
+ int ui:nodegraph:node:stackingOrder = 1363
+ }
+
+ def Shader "Combine3"
+ {
+ uniform token info:id = "ND_combine3_color3"
+ float inputs:in1.connect =
+ float inputs:in2.connect =
+ float inputs:in3.connect =
+ color3f outputs:out
+ float2 ui:nodegraph:node:pos = (1578.1445, 128.91797)
+ float2 ui:nodegraph:node:size = (146, 54)
+ int ui:nodegraph:node:stackingOrder = 1348
+ }
+
+ def Shader "Range"
+ {
+ uniform token info:id = "ND_range_vector2"
+ bool inputs:doclamp = 1
+ float2 inputs:gamma = (2, 2)
+ float2 inputs:in.connect =
+ float2 inputs:inhigh.connect =
+ float2 inputs:inlow = (0.02, 0.02)
+ float2 inputs:outhigh
+ float2 inputs:outlow
+ float2 outputs:out
+ float2 ui:nodegraph:node:pos = (990.64453, 128.91797)
+ float2 ui:nodegraph:node:size = (98, 207)
+ int ui:nodegraph:node:stackingOrder = 1364
+ }
+
+ def Shader "Subtract"
+ {
+ uniform token info:id = "ND_subtract_vector2"
+ float2 inputs:in1.connect =
+ float2 inputs:in2.connect =
+ float2 outputs:out
+ float2 ui:nodegraph:node:pos = (612.64453, 87.04297)
+ float2 ui:nodegraph:node:size = (63, 36)
+ int ui:nodegraph:node:stackingOrder = 1348
+ }
+
+ def Shader "Absval"
+ {
+ uniform token info:id = "ND_absval_vector2"
+ float2 inputs:in.connect =
+ float2 outputs:out
+ float2 ui:nodegraph:node:pos = (765.64453, 87.04297)
+ float2 ui:nodegraph:node:size = (123, 43)
+ int ui:nodegraph:node:stackingOrder = 1348
+ }
+
+ def Shader "Min"
+ {
+ uniform token info:id = "ND_min_float"
+ float inputs:in1.connect =
+ float inputs:in2.connect =
+ float outputs:out
+ float2 ui:nodegraph:node:pos = (1388.1445, 128.91797)
+ float2 ui:nodegraph:node:size = (114, 36)
+ int ui:nodegraph:node:stackingOrder = 1363
+ }
+ }
+}
+
diff --git a/Example-iOS/Packages/RealityKitContent/Sources/RealityKitContent/RealityKitContent.rkassets/Scene.usda b/Example-iOS/Packages/RealityKitContent/Sources/RealityKitContent/RealityKitContent.rkassets/Scene.usda
new file mode 100644
index 0000000..4cb070b
--- /dev/null
+++ b/Example-iOS/Packages/RealityKitContent/Sources/RealityKitContent/RealityKitContent.rkassets/Scene.usda
@@ -0,0 +1,59 @@
+#usda 1.0
+(
+ defaultPrim = "Root"
+ metersPerUnit = 1
+ upAxis = "Y"
+)
+
+def Xform "Root"
+{
+ reorder nameChildren = ["GridMaterial", "Sphere"]
+ rel material:binding = None (
+ bindMaterialAs = "weakerThanDescendants"
+ )
+
+ def Sphere "Sphere" (
+ active = true
+ prepend apiSchemas = ["MaterialBindingAPI"]
+ )
+ {
+ rel material:binding = (
+ bindMaterialAs = "weakerThanDescendants"
+ )
+ double radius = 0.05
+ quatf xformOp:orient = (1, 0, 0, 0)
+ float3 xformOp:scale = (1, 1, 1)
+ float3 xformOp:translate = (0, 0, 0.0004)
+ uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
+
+ def RealityKitComponent "Collider"
+ {
+ uint group = 1
+ uniform token info:id = "RealityKit.Collider"
+ uint mask = 4294967295
+ token type = "Default"
+
+ def RealityKitStruct "Shape"
+ {
+ float3 extent = (0.2, 0.2, 0.2)
+ float radius = 0.05
+ token shapeType = "Sphere"
+ }
+ }
+
+ def RealityKitComponent "InputTarget"
+ {
+ uniform token info:id = "RealityKit.InputTarget"
+ }
+ }
+
+ def "GridMaterial" (
+ active = true
+ prepend references = @Materials/GridMaterial.usda@
+ )
+ {
+ float3 xformOp:scale = (1, 1, 1)
+ uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
+ }
+}
+
diff --git a/Example-iOS/Packages/RealityKitContent/Sources/RealityKitContent/RealityKitContent.swift b/Example-iOS/Packages/RealityKitContent/Sources/RealityKitContent/RealityKitContent.swift
new file mode 100644
index 0000000..5caba4e
--- /dev/null
+++ b/Example-iOS/Packages/RealityKitContent/Sources/RealityKitContent/RealityKitContent.swift
@@ -0,0 +1,4 @@
+import Foundation
+
+/// Bundle for the RealityKitContent project
+public let realityKitContentBundle = Bundle.module
diff --git a/Example-iOS/RiveExample.xcodeproj/project.pbxproj b/Example-iOS/RiveExample.xcodeproj/project.pbxproj
index 7d1408f..de5afdb 100644
--- a/Example-iOS/RiveExample.xcodeproj/project.pbxproj
+++ b/Example-iOS/RiveExample.xcodeproj/project.pbxproj
@@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
- objectVersion = 54;
+ objectVersion = 55;
objects = {
/* Begin PBXBuildFile section */
@@ -210,8 +210,8 @@
049091642BC948AA00F2C12B /* SwiftOutOfBandAudioAssets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 049091622BC948AA00F2C12B /* SwiftOutOfBandAudioAssets.swift */; };
04C4C83E2646FE410047E614 /* StateMachine.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04C4C83D2646FE410047E614 /* StateMachine.swift */; };
04D5B06C266A460C004ACA5B /* nothing.riv in Resources */ = {isa = PBXBuildFile; fileRef = 04D5B069266A460C004ACA5B /* nothing.riv */; };
- 04DB5937266A348C0020A7E8 /* RiveRuntime.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 04A8F6BD26452E10002C909A /* RiveRuntime.framework */; };
- 04DB5938266A348C0020A7E8 /* RiveRuntime.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 04A8F6BD26452E10002C909A /* RiveRuntime.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+ 04DB5937266A348C0020A7E8 /* RiveRuntime.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 04A8F6BD26452E10002C909A /* RiveRuntime.framework */; platformFilters = (ios, xros, ); };
+ 04DB5938266A348C0020A7E8 /* RiveRuntime.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 04A8F6BD26452E10002C909A /* RiveRuntime.framework */; platformFilters = (ios, xros, ); settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
04E51C362A151A1E0075E473 /* Example__macOS_App.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04E51C352A151A1E0075E473 /* Example__macOS_App.swift */; };
04E51C382A151A1E0075E473 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04E51C372A151A1E0075E473 /* ContentView.swift */; };
04E51C3A2A151A1F0075E473 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 04E51C392A151A1F0075E473 /* Assets.xcassets */; };
@@ -320,10 +320,26 @@
E5B5C2192B238829006E57C8 /* asset_load_check.riv in Resources */ = {isa = PBXBuildFile; fileRef = E5B5C2172B238829006E57C8 /* asset_load_check.riv */; };
E5CD7D7127DC331900BFE5E2 /* SwiftMeshAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5CD7D7027DC331900BFE5E2 /* SwiftMeshAnimation.swift */; };
E5E87A012AE5A83800E7295F /* SwiftVariableFPS.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5E87A002AE5A83700E7295F /* SwiftVariableFPS.swift */; };
+ F221387F2CCBEDD400A25BA7 /* Example__visionOS_App.swift in Sources */ = {isa = PBXBuildFile; fileRef = F221387E2CCBEDD400A25BA7 /* Example__visionOS_App.swift */; };
+ F22138812CCBEDD400A25BA7 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F22138802CCBEDD400A25BA7 /* ContentView.swift */; };
+ F22138832CCBEDD500A25BA7 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F22138822CCBEDD500A25BA7 /* Assets.xcassets */; };
+ F22138862CCBEDD500A25BA7 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F22138852CCBEDD500A25BA7 /* Preview Assets.xcassets */; };
+ F221388B2CCBEDE100A25BA7 /* marty.riv in Resources */ = {isa = PBXBuildFile; fileRef = 83C89ACE2988709400044C17 /* marty.riv */; };
+ F26E20AC2CF0E21000130111 /* streaming.riv in Resources */ = {isa = PBXBuildFile; fileRef = F26E20A92CF0E21000130111 /* streaming.riv */; };
+ F2AB95D12CF0EB800055376E /* streaming.riv in Resources */ = {isa = PBXBuildFile; fileRef = F26E20A92CF0E21000130111 /* streaming.riv */; };
+ F2AC7F3C2CCBEEDC00E3ED79 /* RiveRuntime.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 04A8F6BD26452E10002C909A /* RiveRuntime.framework */; };
+ F2AC7F3D2CCBEEDC00E3ED79 /* RiveRuntime.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 04A8F6BD26452E10002C909A /* RiveRuntime.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
F2C623362C874E3A0006E0CA /* fallback_fonts.riv in Resources */ = {isa = PBXBuildFile; fileRef = F2C623352C874E3A0006E0CA /* fallback_fonts.riv */; };
F2C623372C874E3A0006E0CA /* fallback_fonts.riv in Resources */ = {isa = PBXBuildFile; fileRef = F2C623352C874E3A0006E0CA /* fallback_fonts.riv */; };
F2C623392C874E690006E0CA /* SwiftFallbackFonts.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2C623382C874E690006E0CA /* SwiftFallbackFonts.swift */; };
F2C6233A2C874E690006E0CA /* SwiftFallbackFonts.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2C623382C874E690006E0CA /* SwiftFallbackFonts.swift */; };
+ F2C852D42CD1772300F0D81F /* Example__tvOS_App.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2C852D32CD1772300F0D81F /* Example__tvOS_App.swift */; };
+ F2C852D62CD1772300F0D81F /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2C852D52CD1772300F0D81F /* ContentView.swift */; };
+ F2C852D82CD1772400F0D81F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F2C852D72CD1772400F0D81F /* Assets.xcassets */; };
+ F2C852DB2CD1772400F0D81F /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F2C852DA2CD1772400F0D81F /* Preview Assets.xcassets */; };
+ F2C852EB2CD17B8200F0D81F /* RiveRuntime.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 04A8F6BD26452E10002C909A /* RiveRuntime.framework */; };
+ F2C852EC2CD17B8200F0D81F /* RiveRuntime.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 04A8F6BD26452E10002C909A /* RiveRuntime.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+ F2C852F22CD19F6A00F0D81F /* marty.riv in Resources */ = {isa = PBXBuildFile; fileRef = 83C89ACE2988709400044C17 /* marty.riv */; };
F8772AF02AD94A4400AB5920 /* marty.riv in Resources */ = {isa = PBXBuildFile; fileRef = 83C89ACE2988709400044C17 /* marty.riv */; };
F8772AF12AD94A4400AB5920 /* paper.riv in Resources */ = {isa = PBXBuildFile; fileRef = 83C89AD0298870A700044C17 /* paper.riv */; };
F8772AF22AD94A4400AB5920 /* Bear.riv in Resources */ = {isa = PBXBuildFile; fileRef = 83DE4CB42AB3974300B88B72 /* Bear.riv */; };
@@ -371,6 +387,28 @@
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
+ F2AC7F3E2CCBEEDC00E3ED79 /* Embed Frameworks */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "";
+ dstSubfolderSpec = 10;
+ files = (
+ F2AC7F3D2CCBEEDC00E3ED79 /* RiveRuntime.framework in Embed Frameworks */,
+ );
+ name = "Embed Frameworks";
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ F2C852ED2CD17B8200F0D81F /* Embed Frameworks */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "";
+ dstSubfolderSpec = 10;
+ files = (
+ F2C852EC2CD17B8200F0D81F /* RiveRuntime.framework in Embed Frameworks */,
+ );
+ name = "Embed Frameworks";
+ runOnlyForDeploymentPostprocessing = 0;
+ };
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
@@ -481,8 +519,21 @@
E5B5C2172B238829006E57C8 /* asset_load_check.riv */ = {isa = PBXFileReference; lastKnownFileType = file; path = asset_load_check.riv; sourceTree = ""; };
E5CD7D7027DC331900BFE5E2 /* SwiftMeshAnimation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftMeshAnimation.swift; sourceTree = ""; };
E5E87A002AE5A83700E7295F /* SwiftVariableFPS.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwiftVariableFPS.swift; sourceTree = ""; };
+ F221387A2CCBEDD400A25BA7 /* Example (visionOS).app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Example (visionOS).app"; sourceTree = BUILT_PRODUCTS_DIR; };
+ F221387E2CCBEDD400A25BA7 /* Example__visionOS_App.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Example__visionOS_App.swift; sourceTree = ""; };
+ F22138802CCBEDD400A25BA7 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; };
+ F22138822CCBEDD500A25BA7 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
+ F22138852CCBEDD500A25BA7 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; };
+ F22138872CCBEDD500A25BA7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+ F26E20A92CF0E21000130111 /* streaming.riv */ = {isa = PBXFileReference; lastKnownFileType = file; path = streaming.riv; sourceTree = ""; };
+ F2B7F2F72C5AC09200F47FBC /* RealityKitContent */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = RealityKitContent; sourceTree = ""; };
F2C623352C874E3A0006E0CA /* fallback_fonts.riv */ = {isa = PBXFileReference; lastKnownFileType = file; path = fallback_fonts.riv; sourceTree = ""; };
F2C623382C874E690006E0CA /* SwiftFallbackFonts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftFallbackFonts.swift; sourceTree = ""; };
+ F2C852D12CD1772300F0D81F /* Example (tvOS).app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Example (tvOS).app"; sourceTree = BUILT_PRODUCTS_DIR; };
+ F2C852D32CD1772300F0D81F /* Example__tvOS_App.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Example__tvOS_App.swift; sourceTree = ""; };
+ F2C852D52CD1772300F0D81F /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; };
+ F2C852D72CD1772400F0D81F /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
+ F2C852DA2CD1772400F0D81F /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; };
F8DA7B442AF523A800FF3CBF /* DismissableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DismissableView.swift; sourceTree = ""; };
/* End PBXFileReference section */
@@ -519,6 +570,22 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ F22138772CCBEDD400A25BA7 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ F2AC7F3C2CCBEEDC00E3ED79 /* RiveRuntime.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ F2C852CE2CD1772300F0D81F /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ F2C852EB2CD17B8200F0D81F /* RiveRuntime.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
@@ -600,6 +667,7 @@
C9696B0E24FC6FD10041502A /* Assets */ = {
isa = PBXGroup;
children = (
+ F26E20A92CF0E21000130111 /* streaming.riv */,
2E974F942CB3509200642588 /* layout_test.riv */,
F2C623352C874E3A0006E0CA /* fallback_fonts.riv */,
2E83910C2C050BC4003BCF2A /* runtime_nested_inputs.riv */,
@@ -694,6 +762,9 @@
C9696B0E24FC6FD10041502A /* Assets */,
C9C73E9624FC471E00EF9516 /* Source */,
04E51C342A151A1E0075E473 /* Example (macOS) */,
+ F2B7F2F62C5AC09200F47FBC /* Packages */,
+ F221387B2CCBEDD400A25BA7 /* Example (visionOS) */,
+ F2C852D22CD1772300F0D81F /* Example (tvOS) */,
C9C73E9524FC471E00EF9516 /* Products */,
C9C741FF24FC53CF00EF9516 /* Frameworks */,
);
@@ -706,6 +777,8 @@
04E51C332A151A1E0075E473 /* Example (macOS).app */,
040553C72B7A274B008F076A /* Preview (macOS).app */,
040554302B7A2858008F076A /* Preview (iOS).app */,
+ F221387A2CCBEDD400A25BA7 /* Example (visionOS).app */,
+ F2C852D12CD1772300F0D81F /* Example (tvOS).app */,
);
name = Products;
sourceTree = "";
@@ -743,6 +816,53 @@
name = Frameworks;
sourceTree = "";
};
+ F221387B2CCBEDD400A25BA7 /* Example (visionOS) */ = {
+ isa = PBXGroup;
+ children = (
+ F221387E2CCBEDD400A25BA7 /* Example__visionOS_App.swift */,
+ F22138802CCBEDD400A25BA7 /* ContentView.swift */,
+ F22138822CCBEDD500A25BA7 /* Assets.xcassets */,
+ F22138872CCBEDD500A25BA7 /* Info.plist */,
+ F22138842CCBEDD500A25BA7 /* Preview Content */,
+ );
+ path = "Example (visionOS)";
+ sourceTree = "";
+ };
+ F22138842CCBEDD500A25BA7 /* Preview Content */ = {
+ isa = PBXGroup;
+ children = (
+ F22138852CCBEDD500A25BA7 /* Preview Assets.xcassets */,
+ );
+ path = "Preview Content";
+ sourceTree = "";
+ };
+ F2B7F2F62C5AC09200F47FBC /* Packages */ = {
+ isa = PBXGroup;
+ children = (
+ F2B7F2F72C5AC09200F47FBC /* RealityKitContent */,
+ );
+ path = Packages;
+ sourceTree = "";
+ };
+ F2C852D22CD1772300F0D81F /* Example (tvOS) */ = {
+ isa = PBXGroup;
+ children = (
+ F2C852D32CD1772300F0D81F /* Example__tvOS_App.swift */,
+ F2C852D52CD1772300F0D81F /* ContentView.swift */,
+ F2C852D72CD1772400F0D81F /* Assets.xcassets */,
+ F2C852D92CD1772400F0D81F /* Preview Content */,
+ );
+ path = "Example (tvOS)";
+ sourceTree = "";
+ };
+ F2C852D92CD1772400F0D81F /* Preview Content */ = {
+ isa = PBXGroup;
+ children = (
+ F2C852DA2CD1772400F0D81F /* Preview Assets.xcassets */,
+ );
+ path = "Preview Content";
+ sourceTree = "";
+ };
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@@ -822,13 +942,51 @@
productReference = C9C73E9424FC471E00EF9516 /* Example (iOS).app */;
productType = "com.apple.product-type.application";
};
+ F22138792CCBEDD400A25BA7 /* Example (visionOS) */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = F22138882CCBEDD500A25BA7 /* Build configuration list for PBXNativeTarget "Example (visionOS)" */;
+ buildPhases = (
+ F22138762CCBEDD400A25BA7 /* Sources */,
+ F22138772CCBEDD400A25BA7 /* Frameworks */,
+ F22138782CCBEDD400A25BA7 /* Resources */,
+ F2AC7F3E2CCBEEDC00E3ED79 /* Embed Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = "Example (visionOS)";
+ packageProductDependencies = (
+ );
+ productName = "Example (visionOS)";
+ productReference = F221387A2CCBEDD400A25BA7 /* Example (visionOS).app */;
+ productType = "com.apple.product-type.application";
+ };
+ F2C852D02CD1772300F0D81F /* Example (tvOS) */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = F2C852DC2CD1772400F0D81F /* Build configuration list for PBXNativeTarget "Example (tvOS)" */;
+ buildPhases = (
+ F2C852CD2CD1772300F0D81F /* Sources */,
+ F2C852CE2CD1772300F0D81F /* Frameworks */,
+ F2C852CF2CD1772300F0D81F /* Resources */,
+ F2C852ED2CD17B8200F0D81F /* Embed Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = "Example (tvOS)";
+ productName = "Example (tvOS)";
+ productReference = F2C852D12CD1772300F0D81F /* Example (tvOS).app */;
+ productType = "com.apple.product-type.application";
+ };
/* End PBXNativeTarget section */
/* Begin PBXProject section */
C9C73E8C24FC471E00EF9516 /* Project object */ = {
isa = PBXProject;
attributes = {
- LastSwiftUpdateCheck = 1500;
+ LastSwiftUpdateCheck = 1540;
LastUpgradeCheck = 1310;
ORGANIZATIONNAME = Rive;
TargetAttributes = {
@@ -838,6 +996,12 @@
C9C73E9324FC471E00EF9516 = {
CreatedOnToolsVersion = 11.6;
};
+ F22138792CCBEDD400A25BA7 = {
+ CreatedOnToolsVersion = 15.4;
+ };
+ F2C852D02CD1772300F0D81F = {
+ CreatedOnToolsVersion = 15.4;
+ };
};
};
buildConfigurationList = C9C73E8F24FC471E00EF9516 /* Build configuration list for PBXProject "RiveExample" */;
@@ -866,6 +1030,8 @@
040553822B7A274B008F076A /* Preview (macOS) */,
C9C73E9324FC471E00EF9516 /* Example (iOS) */,
04E51C322A151A1E0075E473 /* Example (macOS) */,
+ F22138792CCBEDD400A25BA7 /* Example (visionOS) */,
+ F2C852D02CD1772300F0D81F /* Example (tvOS) */,
);
};
/* End PBXProject section */
@@ -1154,6 +1320,28 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ F22138782CCBEDD400A25BA7 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ F221388B2CCBEDE100A25BA7 /* marty.riv in Resources */,
+ F22138862CCBEDD500A25BA7 /* Preview Assets.xcassets in Resources */,
+ F26E20AC2CF0E21000130111 /* streaming.riv in Resources */,
+ F22138832CCBEDD500A25BA7 /* Assets.xcassets in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ F2C852CF2CD1772300F0D81F /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ F2C852F22CD19F6A00F0D81F /* marty.riv in Resources */,
+ F2C852DB2CD1772400F0D81F /* Preview Assets.xcassets in Resources */,
+ F2AB95D12CF0EB800055376E /* streaming.riv in Resources */,
+ F2C852D82CD1772400F0D81F /* Assets.xcassets in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
@@ -1263,6 +1451,24 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ F22138762CCBEDD400A25BA7 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ F22138812CCBEDD400A25BA7 /* ContentView.swift in Sources */,
+ F221387F2CCBEDD400A25BA7 /* Example__visionOS_App.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ F2C852CD2CD1772300F0D81F /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ F2C852D62CD1772300F0D81F /* ContentView.swift in Sources */,
+ F2C852D42CD1772300F0D81F /* Example__tvOS_App.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
@@ -1550,7 +1756,7 @@
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 6;
DEVELOPMENT_ASSET_PATHS = "\"Source/Preview Content\"";
- DEVELOPMENT_TEAM = NJ3JMFUNS9;
+ DEVELOPMENT_TEAM = "";
ENABLE_PREVIEWS = YES;
INFOPLIST_FILE = Source/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
@@ -1560,8 +1766,11 @@
);
PRODUCT_BUNDLE_IDENTIFIER = rive.app.ios.RiveExample;
PRODUCT_NAME = "$(TARGET_NAME)";
+ SUPPORTED_PLATFORMS = "iphoneos iphonesimulator xros xrsimulator";
+ SUPPORTS_MACCATALYST = NO;
SWIFT_VERSION = 5.0;
- TARGETED_DEVICE_FAMILY = "1,2";
+ TARGETED_DEVICE_FAMILY = "1,2,7";
+ XROS_DEPLOYMENT_TARGET = 1.0;
};
name = Debug;
};
@@ -1571,7 +1780,7 @@
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 6;
DEVELOPMENT_ASSET_PATHS = "\"Source/Preview Content\"";
- DEVELOPMENT_TEAM = NJ3JMFUNS9;
+ DEVELOPMENT_TEAM = "";
ENABLE_PREVIEWS = YES;
INFOPLIST_FILE = Source/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
@@ -1581,8 +1790,145 @@
);
PRODUCT_BUNDLE_IDENTIFIER = rive.app.ios.RiveExample;
PRODUCT_NAME = "$(TARGET_NAME)";
+ SUPPORTED_PLATFORMS = "iphoneos iphonesimulator xros xrsimulator";
+ SUPPORTS_MACCATALYST = NO;
SWIFT_VERSION = 5.0;
- TARGETED_DEVICE_FAMILY = "1,2";
+ TARGETED_DEVICE_FAMILY = "1,2,7";
+ XROS_DEPLOYMENT_TARGET = 1.0;
+ };
+ name = Release;
+ };
+ F22138892CCBEDD500A25BA7 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
+ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ DEVELOPMENT_ASSET_PATHS = "\"Example (visionOS)/Preview Content\"";
+ DEVELOPMENT_TEAM = 8N4K3S3FJ4;
+ ENABLE_PREVIEWS = YES;
+ ENABLE_USER_SCRIPT_SANDBOXING = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu17;
+ GENERATE_INFOPLIST_FILE = YES;
+ INFOPLIST_FILE = "$(TARGET_NAME)/Info.plist";
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
+ MARKETING_VERSION = 1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = "app.rive.Example--visionOS-";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = xros;
+ SUPPORTED_PLATFORMS = "xros xrsimulator";
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2,7";
+ XROS_DEPLOYMENT_TARGET = 1.0;
+ };
+ name = Debug;
+ };
+ F221388A2CCBEDD500A25BA7 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
+ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ DEVELOPMENT_ASSET_PATHS = "\"Example (visionOS)/Preview Content\"";
+ DEVELOPMENT_TEAM = 8N4K3S3FJ4;
+ ENABLE_PREVIEWS = YES;
+ ENABLE_USER_SCRIPT_SANDBOXING = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu17;
+ GENERATE_INFOPLIST_FILE = YES;
+ INFOPLIST_FILE = "$(TARGET_NAME)/Info.plist";
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
+ MARKETING_VERSION = 1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = "app.rive.Example--visionOS-";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = xros;
+ SUPPORTED_PLATFORMS = "xros xrsimulator";
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2,7";
+ XROS_DEPLOYMENT_TARGET = 1.0;
+ };
+ name = Release;
+ };
+ F2C852DD2CD1772400F0D81F /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image";
+ ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
+ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ DEVELOPMENT_ASSET_PATHS = "\"Example (tvOS)/Preview Content\"";
+ DEVELOPMENT_TEAM = 8N4K3S3FJ4;
+ ENABLE_PREVIEWS = YES;
+ ENABLE_USER_SCRIPT_SANDBOXING = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu17;
+ GENERATE_INFOPLIST_FILE = YES;
+ INFOPLIST_KEY_UILaunchScreen_Generation = YES;
+ INFOPLIST_KEY_UIUserInterfaceStyle = Automatic;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
+ MARKETING_VERSION = 1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = "david.app.rive.Example--tvOS-";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = appletvos;
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = 3;
+ TVOS_DEPLOYMENT_TARGET = 16.0;
+ };
+ name = Debug;
+ };
+ F2C852DE2CD1772400F0D81F /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image";
+ ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
+ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ DEVELOPMENT_ASSET_PATHS = "\"Example (tvOS)/Preview Content\"";
+ DEVELOPMENT_TEAM = 8N4K3S3FJ4;
+ ENABLE_PREVIEWS = YES;
+ ENABLE_USER_SCRIPT_SANDBOXING = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu17;
+ GENERATE_INFOPLIST_FILE = YES;
+ INFOPLIST_KEY_UILaunchScreen_Generation = YES;
+ INFOPLIST_KEY_UIUserInterfaceStyle = Automatic;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
+ MARKETING_VERSION = 1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = "david.app.rive.Example--tvOS-";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = appletvos;
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = 3;
+ TVOS_DEPLOYMENT_TARGET = 16.0;
};
name = Release;
};
@@ -1634,6 +1980,24 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
+ F22138882CCBEDD500A25BA7 /* Build configuration list for PBXNativeTarget "Example (visionOS)" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ F22138892CCBEDD500A25BA7 /* Debug */,
+ F221388A2CCBEDD500A25BA7 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ F2C852DC2CD1772400F0D81F /* Build configuration list for PBXNativeTarget "Example (tvOS)" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ F2C852DD2CD1772400F0D81F /* Debug */,
+ F2C852DE2CD1772400F0D81F /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
/* End XCConfigurationList section */
/* Begin XCRemoteSwiftPackageReference section */
diff --git a/Example-iOS/RiveExample.xcodeproj/xcshareddata/xcschemes/Example (tvOS).xcscheme b/Example-iOS/RiveExample.xcodeproj/xcshareddata/xcschemes/Example (tvOS).xcscheme
new file mode 100644
index 0000000..1126c34
--- /dev/null
+++ b/Example-iOS/RiveExample.xcodeproj/xcshareddata/xcschemes/Example (tvOS).xcscheme
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Example-iOS/Source/Examples/Storyboard/StressTest.swift b/Example-iOS/Source/Examples/Storyboard/StressTest.swift
index 1b7944e..8b7e026 100644
--- a/Example-iOS/Source/Examples/Storyboard/StressTest.swift
+++ b/Example-iOS/Source/Examples/Storyboard/StressTest.swift
@@ -30,7 +30,11 @@ class StressTestViewController: UIViewController {
viewModel!.setView(rView!)
view.addSubview(rView!)
let f = view.frame
+ #if os(visionOS)
+ let h: CGFloat = 0
+ #else
let h = UIApplication.shared.statusBarFrame.height + 40
+ #endif
rView!.frame = CGRect(x:f.minX, y:f.minY + h, width:f.width, height:f.height - h)
let gesture = UITapGestureRecognizer(target: self, action: #selector (self.onTap (_:)))
@@ -48,10 +52,17 @@ class CustomRiveView: RiveView {
super.init()
rModel = model
}
-
+
+ #if os(visionOS)
+ required init?(coder aDecoder: NSCoder) {
+ super.init(coder: aDecoder)
+ }
+ #else
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
+ #endif
+
override func drawRive(_ rect: CGRect, size: CGSize) {
// This prevents breaking when loading RiveFile async
guard let artboard = rModel?.artboard else { return }
diff --git a/Example-iOS/Source/Examples/SwiftUI/SwiftEvents.swift b/Example-iOS/Source/Examples/SwiftUI/SwiftEvents.swift
index b3f7c2a..0867929 100644
--- a/Example-iOS/Source/Examples/SwiftUI/SwiftEvents.swift
+++ b/Example-iOS/Source/Examples/SwiftUI/SwiftEvents.swift
@@ -45,7 +45,7 @@ class RiveEventsVMExample: RiveViewModel {
if let openUrlEvent = riveEvent as? RiveOpenUrlEvent {
debugPrint("Open URL Event Properties: \(openUrlEvent.properties())")
if let url = URL(string: openUrlEvent.url()) {
- #if os(iOS)
+ #if os(iOS) || os(visionOS) || os(tvOS)
UIApplication.shared.open(url)
#else
NSWorkspace.shared.open(url)
diff --git a/RiveRuntime.xcodeproj/project.pbxproj b/RiveRuntime.xcodeproj/project.pbxproj
index 0bc2900..a349b9c 100644
--- a/RiveRuntime.xcodeproj/project.pbxproj
+++ b/RiveRuntime.xcodeproj/project.pbxproj
@@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
- objectVersion = 54;
+ objectVersion = 50;
objects = {
/* Begin PBXBuildFile section */
@@ -80,7 +80,7 @@
C38BB5F4287629C20039E385 /* defaultstatemachine.riv in Resources */ = {isa = PBXBuildFile; fileRef = C38BB5F3287629C20039E385 /* defaultstatemachine.riv */; };
C38BB5F628762B720039E385 /* RiveStateMachineTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C38BB5F528762B720039E385 /* RiveStateMachineTest.swift */; };
C3E2B580282F242400A8651B /* RiveStateMachineInstance+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3E2B57F282F242400A8651B /* RiveStateMachineInstance+Extensions.swift */; };
- C9161A81263CBCBC007749A1 /* RiveRuntime.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C9C73ED124FC478800EF9516 /* RiveRuntime.framework */; platformFilter = ios; };
+ C9161A81263CBCBC007749A1 /* RiveRuntime.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C9C73ED124FC478800EF9516 /* RiveRuntime.framework */; };
C9601F2B250C25930032AA07 /* CoreGraphicsRenderer.mm in Sources */ = {isa = PBXBuildFile; fileRef = C9601F2A250C25930032AA07 /* CoreGraphicsRenderer.mm */; };
C9C73EE024FC478900EF9516 /* RiveRuntimeTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = C9C73EDF24FC478900EF9516 /* RiveRuntimeTests.mm */; };
C9C73EE224FC478900EF9516 /* RiveRuntime.h in Headers */ = {isa = PBXBuildFile; fileRef = C9C73ED424FC478800EF9516 /* RiveRuntime.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -95,14 +95,15 @@
E599DCFA2AAFA06100D1E49A /* rating_animation.riv in Resources */ = {isa = PBXBuildFile; fileRef = E599DCF82AAFA06100D1E49A /* rating_animation.riv */; };
F21F08142C66526D00FFA205 /* RiveFallbackFontDescriptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = F21F08132C66526D00FFA205 /* RiveFallbackFontDescriptor.swift */; };
F23626AA2C8F90FA00727D9A /* nested_text_run.riv in Resources */ = {isa = PBXBuildFile; fileRef = F23626A92C8F90FA00727D9A /* nested_text_run.riv */; };
+ F23992E72CB9C1C60021EF61 /* RenderContextTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F23992E62CB9C1C60021EF61 /* RenderContextTests.m */; };
F2610DD22CA5B4C40090D50B /* RiveLogger+StateMachine.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2610DD12CA5B4C40090D50B /* RiveLogger+StateMachine.swift */; };
F2610DD42CA5B5460090D50B /* RiveLogger+Artboard.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2610DD32CA5B5460090D50B /* RiveLogger+Artboard.swift */; };
F2610DD62CA5B5DD0090D50B /* RiveLogger+ViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2610DD52CA5B5DD0090D50B /* RiveLogger+ViewModel.swift */; };
F2610DD82CA5B6570090D50B /* RiveLogger+Model.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2610DD72CA5B6570090D50B /* RiveLogger+Model.swift */; };
F2610DDA2CA5B84B0090D50B /* RiveLogger+File.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2610DD92CA5B84B0090D50B /* RiveLogger+File.swift */; };
F2610DE12CA5FBE30090D50B /* RiveLogger+View.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2610DE02CA5FBE30090D50B /* RiveLogger+View.swift */; };
- F23992E72CB9C1C60021EF61 /* RenderContextTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F23992E62CB9C1C60021EF61 /* RenderContextTests.m */; };
F28DE4532C5002D900F3C379 /* RiveModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F28DE4522C5002D900F3C379 /* RiveModelTests.swift */; };
+ F2C003E82C933D2300339E67 /* RiveMetalDrawableView.h in Headers */ = {isa = PBXBuildFile; fileRef = F2C003E72C933D2300339E67 /* RiveMetalDrawableView.h */; settings = {ATTRIBUTES = (Public, ); }; };
F2CCA9792C9B2799007DC0D2 /* referenced_image_asset.riv in Resources */ = {isa = PBXBuildFile; fileRef = F2CCA9782C9B2799007DC0D2 /* referenced_image_asset.riv */; };
F2CCA9C22C9E13BA007DC0D2 /* RiveLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2CCA9C12C9E13BA007DC0D2 /* RiveLogger.swift */; };
F2D285492C6D469900728340 /* RiveFallbackFontProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2D285482C6D469900728340 /* RiveFallbackFontProvider.swift */; };
@@ -215,14 +216,15 @@
E599DCF82AAFA06100D1E49A /* rating_animation.riv */ = {isa = PBXFileReference; lastKnownFileType = file; name = rating_animation.riv; path = "Example-iOS/Assets/rating_animation.riv"; sourceTree = SOURCE_ROOT; };
F21F08132C66526D00FFA205 /* RiveFallbackFontDescriptor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RiveFallbackFontDescriptor.swift; sourceTree = ""; };
F23626A92C8F90FA00727D9A /* nested_text_run.riv */ = {isa = PBXFileReference; lastKnownFileType = file; path = nested_text_run.riv; sourceTree = ""; };
+ F23992E62CB9C1C60021EF61 /* RenderContextTests.m */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; path = RenderContextTests.m; sourceTree = ""; };
F2610DD12CA5B4C40090D50B /* RiveLogger+StateMachine.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RiveLogger+StateMachine.swift"; sourceTree = ""; };
F2610DD32CA5B5460090D50B /* RiveLogger+Artboard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RiveLogger+Artboard.swift"; sourceTree = ""; };
F2610DD52CA5B5DD0090D50B /* RiveLogger+ViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RiveLogger+ViewModel.swift"; sourceTree = ""; };
F2610DD72CA5B6570090D50B /* RiveLogger+Model.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RiveLogger+Model.swift"; sourceTree = ""; };
F2610DD92CA5B84B0090D50B /* RiveLogger+File.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RiveLogger+File.swift"; sourceTree = ""; };
F2610DE02CA5FBE30090D50B /* RiveLogger+View.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RiveLogger+View.swift"; sourceTree = ""; };
- F23992E62CB9C1C60021EF61 /* RenderContextTests.m */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; path = RenderContextTests.m; sourceTree = ""; };
F28DE4522C5002D900F3C379 /* RiveModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RiveModelTests.swift; sourceTree = ""; };
+ F2C003E72C933D2300339E67 /* RiveMetalDrawableView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RiveMetalDrawableView.h; sourceTree = ""; };
F2CCA9782C9B2799007DC0D2 /* referenced_image_asset.riv */ = {isa = PBXFileReference; lastKnownFileType = file; path = referenced_image_asset.riv; sourceTree = ""; };
F2CCA9C12C9E13BA007DC0D2 /* RiveLogger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RiveLogger.swift; sourceTree = ""; };
F2D285482C6D469900728340 /* RiveFallbackFontProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RiveFallbackFontProvider.swift; sourceTree = ""; };
@@ -281,6 +283,7 @@
043025F92AFA860E00320F2E /* FileAssetLoaderAdapter.hpp */,
043025FD2AFA8FCF00320F2E /* RiveFileAsset.h */,
043026012AFB9FCD00320F2E /* RiveFactory.h */,
+ F2C003E72C933D2300339E67 /* RiveMetalDrawableView.h */,
);
path = include;
sourceTree = "";
@@ -474,6 +477,7 @@
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
+ C9C741F424FC510200EF9516 /* Rive.h in Headers */,
046FB7F7264EAA60000129B1 /* RiveFile.h in Headers */,
046FB7FC264EAA61000129B1 /* RiveArtboard.h in Headers */,
2A7079352726277C00C035A1 /* rive_renderer_view.hh in Headers */,
@@ -488,6 +492,7 @@
043025F22AF90D4800320F2E /* RiveFileAssetLoader.h in Headers */,
043025FE2AFA8FCF00320F2E /* RiveFileAsset.h in Headers */,
E5964A962A965A9300140479 /* RiveEvent.h in Headers */,
+ F2C003E82C933D2300339E67 /* RiveMetalDrawableView.h in Headers */,
043026022AFB9FCD00320F2E /* RiveFactory.h in Headers */,
C9C741F424FC510200EF9516 /* Rive.h in Headers */,
F2FD94052CC9492B00C1FC85 /* RiveFont.h in Headers */,
@@ -638,6 +643,7 @@
F2610DDA2CA5B84B0090D50B /* RiveLogger+File.swift in Sources */,
C9601F2B250C25930032AA07 /* CoreGraphicsRenderer.mm in Sources */,
C9601F2B250C25930032AA07 /* CoreGraphicsRenderer.mm in Sources */,
+ C9601F2B250C25930032AA07 /* CoreGraphicsRenderer.mm in Sources */,
043025F42AF90EAC00320F2E /* RiveFileAssetLoader.mm in Sources */,
F2D285492C6D469900728340 /* RiveFallbackFontProvider.swift in Sources */,
043025FC2AFA862E00320F2E /* FileAssetLoaderAdapter.mm in Sources */,
@@ -691,7 +697,6 @@
/* Begin PBXTargetDependency section */
C9C73EDD24FC478900EF9516 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
- platformFilter = ios;
target = C9C73ED024FC478800EF9516 /* RiveRuntime */;
targetProxy = C9C73EDC24FC478900EF9516 /* PBXContainerItemProxy */;
};
@@ -849,7 +854,6 @@
"HEADER_SEARCH_PATHS[arch=*]" = (
dependencies/includes/rive/include,
dependencies/includes/renderer/include,
- dependencies/includes/renderer/include,
dependencies/includes/cg_renderer/include,
);
INFOPLIST_FILE = Source/Info.plist;
@@ -874,6 +878,32 @@
"$(OTHER_CFLAGS)",
"-DYOGA_EXPORT=",
);
+ "OTHER_LDFLAGS[sdk=appletvos*]" = (
+ "-lrive_appletvos",
+ "-lrive_harfbuzz_appletvos",
+ "-lrive_sheenbidi_appletvos",
+ "-lrive_yoga_appletvos",
+ "-lrive_pls_renderer_appletvos",
+ "-lrive_cg_renderer_appletvos",
+ "-lrive_decoders_appletvos",
+ "-lrive_png_appletvos",
+ "-lrive_zlib_appletvos",
+ "-lrive_jpeg_appletvos",
+ "-lrive_webp_appletvos",
+ );
+ "OTHER_LDFLAGS[sdk=appletvsimulator*]" = (
+ "-lrive_appletvsimulator",
+ "-lrive_harfbuzz_appletvsimulator",
+ "-lrive_sheenbidi_appletvsimulator",
+ "-lrive_yoga_appletvsimulator",
+ "-lrive_pls_renderer_appletvsimulator",
+ "-lrive_cg_renderer_appletvsimulator",
+ "-lrive_decoders_appletvsimulator",
+ "-lrive_png_appletvsimulator",
+ "-lrive_zlib_appletvsimulator",
+ "-lrive_jpeg_appletvsimulator",
+ "-lrive_webp_appletvsimulator",
+ );
"OTHER_LDFLAGS[sdk=iphoneos*]" = (
"-lrive",
"-lrive_harfbuzz",
@@ -901,16 +931,37 @@
"-lrive_cg_renderer_macos",
"-lrive_decoders_macos",
);
+ "OTHER_LDFLAGS[sdk=xros*]" = (
+ "-lrive_xros",
+ "-lrive_harfbuzz_xros",
+ "-lrive_sheenbidi_xros",
+ "-lrive_yoga_xros",
+ "-lrive_pls_renderer_xros",
+ "-lrive_cg_renderer_xros",
+ "-lrive_decoders_xros",
+ );
+ "OTHER_LDFLAGS[sdk=xrsimulator*]" = (
+ "-lrive_xrsimulator",
+ "-lrive_harfbuzz_xrsimulator",
+ "-lrive_sheenbidi_xrsimulator",
+ "-lrive_yoga_xrsimulator",
+ "-lrive_pls_renderer_xrsimulator",
+ "-lrive_cg_renderer_xrsimulator",
+ "-lrive_decoders_xrsimulator",
+ );
PRODUCT_BUNDLE_IDENTIFIER = rive.app.ios.runtime.RiveRuntime;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
PROVISIONING_PROFILE_SPECIFIER = "";
+ SDKROOT = iphoneos;
SKIP_INSTALL = YES;
- SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx";
+ SUPPORTED_PLATFORMS = "appletvos appletvsimulator iphoneos iphonesimulator macosx xros xrsimulator";
SUPPORTS_MACCATALYST = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
- TARGETED_DEVICE_FAMILY = "1,2,6";
+ TARGETED_DEVICE_FAMILY = "1,2,3,6,7";
+ TVOS_DEPLOYMENT_TARGET = 16.0;
+ XROS_DEPLOYMENT_TARGET = 1.0;
};
name = Debug;
};
@@ -935,7 +986,6 @@
"HEADER_SEARCH_PATHS[arch=*]" = (
dependencies/includes/rive/include,
dependencies/includes/renderer/include,
- dependencies/includes/renderer/include,
dependencies/includes/cg_renderer/include,
);
INFOPLIST_FILE = Source/Info.plist;
@@ -962,6 +1012,32 @@
"$(OTHER_CFLAGS)",
"-DYOGA_EXPORT=",
);
+ "OTHER_LDFLAGS[sdk=appletvos*]" = (
+ "-lrive_appletvos",
+ "-lrive_harfbuzz_appletvos",
+ "-lrive_sheenbidi_appletvos",
+ "-lrive_yoga_appletvos",
+ "-lrive_pls_renderer_appletvos",
+ "-lrive_cg_renderer_appletvos",
+ "-lrive_decoders_appletvos",
+ "-lrive_png_appletvos",
+ "-lrive_zlib_appletvos",
+ "-lrive_jpeg_appletvos",
+ "-lrive_webp_appletvos",
+ );
+ "OTHER_LDFLAGS[sdk=appletvsimulator*]" = (
+ "-lrive_appletvsimulator",
+ "-lrive_harfbuzz_appletvsimulator",
+ "-lrive_sheenbidi_appletvsimulator",
+ "-lrive_yoga_appletvsimulator",
+ "-lrive_pls_renderer_appletvsimulator",
+ "-lrive_cg_renderer_appletvsimulator",
+ "-lrive_decoders_appletvsimulator",
+ "-lrive_png_appletvsimulator",
+ "-lrive_zlib_appletvsimulator",
+ "-lrive_jpeg_appletvsimulator",
+ "-lrive_webp_appletvsimulator",
+ );
"OTHER_LDFLAGS[sdk=iphoneos*]" = (
"-lrive",
"-lrive_harfbuzz",
@@ -989,16 +1065,37 @@
"-lrive_cg_renderer_macos",
"-lrive_decoders_macos",
);
+ "OTHER_LDFLAGS[sdk=xros*]" = (
+ "-lrive_xros",
+ "-lrive_harfbuzz_xros",
+ "-lrive_sheenbidi_xros",
+ "-lrive_yoga_xros",
+ "-lrive_pls_renderer_xros",
+ "-lrive_cg_renderer_xros",
+ "-lrive_decoders_xros",
+ );
+ "OTHER_LDFLAGS[sdk=xrsimulator*]" = (
+ "-lrive_xrsimulator",
+ "-lrive_harfbuzz_xrsimulator",
+ "-lrive_sheenbidi_xrsimulator",
+ "-lrive_yoga_xrsimulator",
+ "-lrive_pls_renderer_xrsimulator",
+ "-lrive_cg_renderer_xrsimulator",
+ "-lrive_decoders_xrsimulator",
+ );
PRODUCT_BUNDLE_IDENTIFIER = rive.app.ios.runtime.RiveRuntime;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
PROVISIONING_PROFILE_SPECIFIER = "";
+ SDKROOT = iphoneos;
SKIP_INSTALL = YES;
- SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx";
+ SUPPORTED_PLATFORMS = "appletvos appletvsimulator iphoneos iphonesimulator macosx xros xrsimulator";
SUPPORTS_MACCATALYST = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_VERSION = 5.0;
- TARGETED_DEVICE_FAMILY = "1,2,6";
+ TARGETED_DEVICE_FAMILY = "1,2,3,6,7";
+ TVOS_DEPLOYMENT_TARGET = 16.0;
+ XROS_DEPLOYMENT_TARGET = 1.0;
};
name = Release;
};
@@ -1017,12 +1114,12 @@
);
PRODUCT_BUNDLE_IDENTIFIER = rive.app.ios.runtime.RiveRuntimeTests;
PRODUCT_NAME = "$(TARGET_NAME)";
- SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx";
+ SUPPORTED_PLATFORMS = "appletvos appletvsimulator iphoneos iphonesimulator macosx xros xrsimulator";
SUPPORTS_MACCATALYST = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
- TARGETED_DEVICE_FAMILY = "1,2";
+ TARGETED_DEVICE_FAMILY = "1,2,3,7";
};
name = Debug;
};
@@ -1041,11 +1138,11 @@
);
PRODUCT_BUNDLE_IDENTIFIER = rive.app.ios.runtime.RiveRuntimeTests;
PRODUCT_NAME = "$(TARGET_NAME)";
- SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx";
+ SUPPORTED_PLATFORMS = "appletvos appletvsimulator iphoneos iphonesimulator macosx xros xrsimulator";
SUPPORTS_MACCATALYST = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
SWIFT_VERSION = 5.0;
- TARGETED_DEVICE_FAMILY = "1,2";
+ TARGETED_DEVICE_FAMILY = "1,2,3,7";
};
name = Release;
};
diff --git a/Source/Fonts/RiveFallbackFontDescriptor+Extensions.swift b/Source/Fonts/RiveFallbackFontDescriptor+Extensions.swift
index 8ad1d79..90d7acd 100644
--- a/Source/Fonts/RiveFallbackFontDescriptor+Extensions.swift
+++ b/Source/Fonts/RiveFallbackFontDescriptor+Extensions.swift
@@ -7,7 +7,7 @@
//
import Foundation
-#if os(iOS)
+#if os(iOS) || os(visionOS) || os(tvOS)
import UIKit
public typealias RiveNativeFont = UIFont
private typealias RiveNativeFontDescriptor = UIFontDescriptor
@@ -120,7 +120,7 @@ extension RiveFallbackFontDescriptor: RiveFallbackFontProvider {
/// - Returns: The font generated from all values of a `RiveFallbackFontDescriptor`.
@objc public var fallbackFont: RiveNativeFont {
let font: RiveNativeFont?
- #if os(iOS)
+ #if os(iOS) || os(visionOS) || os(tvOS)
font = RiveNativeFont(descriptor: toFontDescriptor(), size: Self.defaultFontSize)
#elseif os(macOS)
font = RiveNativeFont(descriptor: toFontDescriptor(), size: Self.defaultFontSize)
diff --git a/Source/Renderer/RenderContextManager.mm b/Source/Renderer/RenderContextManager.mm
index d43ff5d..1dcec81 100644
--- a/Source/Renderer/RenderContextManager.mm
+++ b/Source/Renderer/RenderContextManager.mm
@@ -4,9 +4,11 @@
#import
#import
+#import
#import
#import
#import
+#import
#include "utils/auto_cf.hpp"
#include "cg_factory.hpp"
@@ -25,10 +27,12 @@ static CGSize Maximum2DTextureSizeFromDevice(id device)
{
size = CGSizeMake(16384, 16384);
}
+#if !TARGET_OS_VISION && !TARGET_OS_TV
else if ([device supportsFamily:MTLGPUFamilyApple9])
{
size = CGSizeMake(16384, 16384);
}
+#endif
else if ([device supportsFamily:MTLGPUFamilyApple8])
{
size = CGSizeMake(16384, 16384);
@@ -77,12 +81,12 @@ static CGSize Maximum2DTextureSizeFromDevice(id device)
return nil;
}
-- (rive::Renderer*)beginFrame:(MTKView*)view
+- (rive::Renderer*)beginFrame:(id)view
{
return nil;
}
-- (void)endFrame:(MTKView*)view
+- (void)endFrame:(id)view
withCompletion:(_Nullable MTLCommandBufferHandler)completionHandler;
{}
@@ -128,7 +132,6 @@ static CGSize Maximum2DTextureSizeFromDevice(id device)
#include "rive/renderer/rive_renderer.hpp"
@interface RiveRendererContext : RenderContext
-- (rive::Renderer*)beginFrame:(MTKView*)view;
@end
@implementation RiveRendererContext
@@ -178,7 +181,7 @@ static std::unique_ptr make_pls_context_native(
return _renderContext;
}
-- (rive::Renderer*)beginFrame:(MTKView*)view
+- (rive::Renderer*)beginFrame:(id)view
{
id surface = view.currentDrawable;
if (!surface.texture)
@@ -219,7 +222,7 @@ static std::unique_ptr make_pls_context_native(
return _renderer.get();
}
-- (void)endFrame:(MTKView*)view
+- (void)endFrame:(id)view
withCompletion:(_Nullable MTLCommandBufferHandler)completionHandler;
{
id flushCommandBuffer = [self.metalQueue commandBuffer];
@@ -249,7 +252,7 @@ static std::unique_ptr make_pls_context_native(
@end
@interface CGRendererContext : RenderContext
-- (rive::Renderer*)beginFrame:(MTKView*)view;
+- (rive::Renderer*)beginFrame:(id)view;
@end
constexpr static int kBufferRingSize = 3;
@@ -295,7 +298,7 @@ constexpr static int kBufferRingSize = 3;
return &factory;
}
-- (rive::Renderer*)beginFrame:(MTKView*)view
+- (rive::Renderer*)beginFrame:(id)view
{
uint32_t cgBitmapInfo;
switch (view.colorPixelFormat)
@@ -346,7 +349,7 @@ constexpr static int kBufferRingSize = 3;
return _renderer.get();
}
-- (void)endFrame:(MTKView*)view
+- (void)endFrame:(id)view
withCompletion:(_Nullable MTLCommandBufferHandler)completionHandler;
{
if (_cgContext != nil)
diff --git a/Source/Renderer/include/RenderContext.h b/Source/Renderer/include/RenderContext.h
index c8588d3..0261b7d 100644
--- a/Source/Renderer/include/RenderContext.h
+++ b/Source/Renderer/include/RenderContext.h
@@ -18,7 +18,7 @@ class Renderer;
NS_ASSUME_NONNULL_BEGIN
-@class MTKView;
+@protocol RiveMetalDrawableView;
/// RenderContext knows how to set up a backend-specific render context (e.g.,
/// CG, Rive, ...), and provides a rive::Factory and rive::Renderer for it.
@@ -28,11 +28,11 @@ NS_ASSUME_NONNULL_BEGIN
@property MTLPixelFormat depthStencilPixelFormat;
@property BOOL framebufferOnly;
- (rive::Factory*)factory;
-- (rive::Renderer*)beginFrame:(MTKView*)view;
-- (void)endFrame:(MTKView*)view
+- (rive::Renderer*)beginFrame:(id)view;
+- (void)endFrame:(id)view
withCompletion:(_Nullable MTLCommandBufferHandler)completionHandler;
- (BOOL)canDrawInRect:(CGRect)rect
- drawableSize:(CGSize)drawableSize
+ drawableSize:(CGSize)size
scale:(CGFloat)scale;
@end
diff --git a/Source/Renderer/include/RiveFactory.h b/Source/Renderer/include/RiveFactory.h
index 639d22b..70a0a7c 100644
--- a/Source/Renderer/include/RiveFactory.h
+++ b/Source/Renderer/include/RiveFactory.h
@@ -32,7 +32,7 @@ NS_ASSUME_NONNULL_BEGIN
*/
@interface RiveFactory : NSObject
- (RiveFont*)decodeFont:(NSData*)data;
-#if TARGET_OS_IPHONE
+#if TARGET_OS_IPHONE || TARGET_OS_VISION || TARGET_OS_TV
- (RiveFont*)decodeUIFont:(UIFont*)data NS_SWIFT_NAME(decodeFont(_:));
#else
- (RiveFont*)decodeNSFont:(NSFont*)data NS_SWIFT_NAME(decodeFont(_:));
diff --git a/Source/Renderer/include/RiveMetalDrawableView.h b/Source/Renderer/include/RiveMetalDrawableView.h
new file mode 100644
index 0000000..8bbce2d
--- /dev/null
+++ b/Source/Renderer/include/RiveMetalDrawableView.h
@@ -0,0 +1,30 @@
+//
+// RiveMetalDrawableView.h
+// RiveRuntime
+//
+// Created by David Skuza on 9/12/24.
+// Copyright © 2024 Rive. All rights reserved.
+//
+
+#ifndef RiveMetalDrawableView_h
+#define RiveMetalDrawableView_h
+
+#import
+
+@protocol RiveMetalDrawableView
+@property(nullable, nonatomic, retain) id device;
+@property(nonatomic) MTLPixelFormat
+ depthStencilPixelFormat; // Currently unused; not available in CAMetalLayer
+@property(nonatomic) BOOL framebufferOnly;
+@property(nonatomic)
+ NSUInteger sampleCount; // Currently unused; not available in CAMetalLayer
+@property(nonatomic) BOOL
+ enableSetNeedsDisplay; // Currently unused; not available in CAMetalLayer
+@property(nonatomic, getter=isPaused)
+ BOOL paused; // Currently unused; no internal display link used
+@property(nullable, nonatomic, readonly) id currentDrawable;
+@property(nonatomic) MTLPixelFormat colorPixelFormat;
+@property(nonatomic) CGSize drawableSize;
+@end
+
+#endif /* RiveMetalDrawableView_h */
diff --git a/Source/Renderer/include/rive_renderer_view.hh b/Source/Renderer/include/rive_renderer_view.hh
index 3cc120b..88b7f24 100644
--- a/Source/Renderer/include/rive_renderer_view.hh
+++ b/Source/Renderer/include/rive_renderer_view.hh
@@ -1,12 +1,22 @@
#import
#import
#import
+#import
#import
+#if TARGET_OS_VISION
+@interface RiveMTKView : UIView
+- (nonnull instancetype)initWithFrame:(CGRect) frameRect device:(nullable id) device;
+@end
+#else
+@interface RiveMTKView : MTKView
+@end
+#endif
+
NS_ASSUME_NONNULL_BEGIN
-@interface RiveRendererView : MTKView
+@interface RiveRendererView : RiveMTKView
- (instancetype)initWithFrame:(CGRect)frameRect;
/// Deprecated. Use `alignWithRect:contentRect:alignment:fit:scaleFactor:` instead.
diff --git a/Source/Renderer/rive_renderer_view.mm b/Source/Renderer/rive_renderer_view.mm
index d4b4455..dbaf075 100644
--- a/Source/Renderer/rive_renderer_view.mm
+++ b/Source/Renderer/rive_renderer_view.mm
@@ -3,7 +3,7 @@
#import
#import
-#if TARGET_OS_IPHONE
+#if TARGET_OS_IPHONE || TARGET_VISION_OS || TARGET_OS_TV
#import
#else
#import
@@ -17,6 +17,138 @@
#define WITH_RIVE_AUDIO
#include "rive/audio/audio_engine.hpp"
+#if TARGET_OS_VISION
+@implementation RiveMTKView
+{
+ id _currentDrawable;
+}
+
+@synthesize enableSetNeedsDisplay;
+
+@synthesize paused;
+
+@synthesize sampleCount;
+
+@synthesize depthStencilPixelFormat;
+
+- (instancetype)initWithFrame:(CGRect)frameRect device:(id)device
+{
+ self = [super initWithFrame:frameRect];
+ self.device = device;
+ return self;
+}
+
++ (Class)layerClass
+{
+ return [CAMetalLayer class];
+}
+
+- (nullable id)device
+{
+ return [self metalLayer].device;
+}
+
+- (void)setDevice:(nullable id)device
+{
+ [self metalLayer].device = device;
+}
+
+- (CAMetalLayer*)metalLayer
+{
+ return (CAMetalLayer*)self.layer;
+}
+
+- (void)setFramebufferOnly:(BOOL)framebufferOnly
+{
+ [self metalLayer].framebufferOnly = framebufferOnly;
+}
+
+- (BOOL)framebufferOnly
+{
+ return [self metalLayer].framebufferOnly;
+}
+
+- (void)setCurrentDrawable:(id _Nullable)currentDrawable
+{
+ return;
+}
+
+- (nullable id)currentDrawable
+{
+ if (_currentDrawable == nil)
+ {
+ _currentDrawable = [self metalLayer].nextDrawable;
+ }
+ return _currentDrawable;
+}
+
+- (void)setColorPixelFormat:(MTLPixelFormat)colorPixelFormat
+{
+ [self metalLayer].pixelFormat = colorPixelFormat;
+}
+
+- (MTLPixelFormat)colorPixelFormat
+{
+ return [self metalLayer].pixelFormat;
+}
+
+- (void)setDrawableSize:(CGSize)drawableSize
+{
+ [self metalLayer].drawableSize = drawableSize;
+}
+
+- (CGSize)drawableSize
+{
+ return [self metalLayer].drawableSize;
+}
+
+- (void)_updateDrawableSizeFromBounds
+{
+ CGSize newSize = self.bounds.size;
+ newSize.width *= self.traitCollection.displayScale;
+ newSize.height *= self.traitCollection.displayScale;
+ self.drawableSize = newSize;
+}
+
+- (void)setContentScaleFactor:(CGFloat)contentScaleFactor
+{
+ [super setContentScaleFactor:contentScaleFactor];
+ [self _updateDrawableSizeFromBounds];
+}
+
+- (void)layoutSubviews
+{
+ [super layoutSubviews];
+ [self _updateDrawableSizeFromBounds];
+}
+
+- (void)setFrame:(CGRect)frame
+{
+ [super setFrame:frame];
+ [self _updateDrawableSizeFromBounds];
+}
+
+- (void)setBounds:(CGRect)bounds
+{
+ [super setBounds:bounds];
+ [self _updateDrawableSizeFromBounds];
+}
+
+// For some reason, when setNeedsDisplay is called, drawRect is not called
+// But, we get a delegate callback when the layer should be displayed,
+// so we'll just piggyback off of that and draw for now.
+- (void)displayLayer:(CALayer*)layer
+{
+ _currentDrawable = [self metalLayer].nextDrawable;
+ [self drawRect:self.bounds];
+}
+
+@end
+#else
+@implementation RiveMTKView
+@end
+#endif
+
@implementation RiveRendererView
{
RenderContext* _renderContext;
@@ -43,7 +175,7 @@
- (instancetype)initWithCoder:(NSCoder*)decoder
{
-#if TARGET_OS_IPHONE
+#if TARGET_OS_IPHONE || TARGET_OS_VISION || TARGET_OS_TV
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(didEnterBackground:)
diff --git a/Source/RiveView.swift b/Source/RiveView.swift
index 743c3c8..2093e93 100644
--- a/Source/RiveView.swift
+++ b/Source/RiveView.swift
@@ -26,7 +26,7 @@ open class RiveView: RiveRendererView {
/// Defaults to the "legacy" methods, which will be overridden
/// by window handlers in this view when the window changes.
private lazy var _layoutScaleFactor: Double = {
- #if os(iOS)
+ #if os(iOS) || os(visionOS) || os(tvOS)
return self.traitCollection.displayScale
#else
guard let scale = NSScreen.main?.backingScaleFactor else { return 1 }
@@ -86,27 +86,36 @@ open class RiveView: RiveRendererView {
try! setModel(model, autoPlay: autoPlay)
}
+
+ #if os(visionOS)
+ required public init?(coder aDecoder: NSCoder) {
+ super.init(coder: aDecoder)
+ }
+ #else
required public init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
+ #endif
private func commonInit() {
- #if os(iOS)
- if #available(iOS 17, *) {
+ #if os(iOS) || os(visionOS) || os(tvOS)
+ if #available(iOS 17, tvOS 17, visionOS 1, *) {
registerForTraitChanges([UITraitHorizontalSizeClass.self, UITraitVerticalSizeClass.self]) { [weak self] (_: UITraitEnvironment, traitCollection: UITraitCollection) in
guard let self else { return }
self.redrawIfNecessary()
}
}
- if #available(iOS 17, *) {
+ if #available(iOS 17, tvOS 17, visionOS 1, *) {
registerForTraitChanges([UITraitDisplayScale.self]) { [weak self] (_: UITraitEnvironment, traitCollection: UITraitCollection) in
guard let self else { return }
self._layoutScaleFactor = self.traitCollection.displayScale
}
}
+ #endif
+ #if os(iOS)
UIDevice.current.beginGeneratingDeviceOrientationNotifications()
orientationObserver = NotificationCenter.default.addObserver(forName: UIDevice.orientationDidChangeNotification, object: nil, queue: nil) { [weak self] _ in
guard let self else { return }
@@ -146,19 +155,25 @@ open class RiveView: RiveRendererView {
}
private func needsDisplay() {
- #if os(iOS)
+ #if os(iOS) || os(visionOS) || os(tvOS)
setNeedsDisplay()
#else
needsDisplay=true
#endif
}
- #if os(iOS)
+ #if os(iOS) || os(tvOS)
open override func didMoveToWindow() {
super.didMoveToWindow()
guard let scale = window?.windowScene?.screen.scale else { return }
_layoutScaleFactor = scale
}
+ #elseif os(visionOS)
+ open override func didMoveToWindow() {
+ super.didMoveToWindow()
+ let scale = traitCollection.displayScale
+ _layoutScaleFactor = scale
+ }
#else
open override func viewDidMoveToWindow() {
super.viewDidMoveToWindow()
@@ -172,7 +187,7 @@ open class RiveView: RiveRendererView {
stopTimer()
isPlaying = false
riveModel = model
- #if os(iOS)
+ #if os(iOS) || os(visionOS) || os(tvOS)
isOpaque = false
#else
layer?.isOpaque=false
@@ -188,7 +203,7 @@ open class RiveView: RiveRendererView {
setFPSCounterVisibility()
}
- #if os(iOS)
+ #if os(iOS) || os(visionOS) || os(tvOS)
/// Hints to underlying CADisplayLink the preferred FPS to run at
/// - Parameters:
/// - preferredFramesPerSecond: Integer number of seconds to set preferred FPS at
@@ -268,7 +283,7 @@ open class RiveView: RiveRendererView {
forMode: .common
)
}
- #if os(iOS)
+ #if os(iOS) || os(visionOS)
if displayLinkProxy?.displayLink?.isPaused == true {
displayLinkProxy?.displayLink?.isPaused = false
}
@@ -283,7 +298,7 @@ open class RiveView: RiveRendererView {
}
private func timestamp() -> CFTimeInterval {
- #if os(iOS)
+ #if os(iOS) || os(visionOS) || os(tvOS)
return displayLinkProxy?.displayLink?.targetTimestamp ?? Date().timeIntervalSince1970
#else
return Date().timeIntervalSince1970
@@ -310,7 +325,7 @@ open class RiveView: RiveRendererView {
// Calculate the time elapsed between ticks
let elapsedTime = timestamp - lastTime
- #if os(iOS)
+ #if os(iOS) || os(visionOS) || os(tvOS)
fpsCounter?.didDrawFrame(timestamp: timestamp)
#else
fpsCounter?.elapsed(time: elapsedTime)
@@ -394,7 +409,7 @@ open class RiveView: RiveRendererView {
}
align(with: newFrame, contentRect: artboard.bounds(), alignment: alignment, fit: fit, scaleFactor: scale)
draw(with: artboard)
-
+
}
// MARK: - UITraitCollection
@@ -416,7 +431,7 @@ open class RiveView: RiveRendererView {
#endif
// MARK: - UIResponder
- #if os(iOS)
+ #if os(iOS) || os(visionOS) || os(tvOS)
open override func touchesBegan(_ touches: Set, with event: UIEvent?) {
guard let touch = touches.first else { return }
@@ -692,7 +707,7 @@ open class RiveView: RiveRendererView {
func player(didAdvanceby seconds: Double, riveModel: RiveModel?)
}
-#if os(iOS)
+#if os(iOS) || os(visionOS) || os(tvOS)
fileprivate class DisplayLinkProxy {
var displayLink: CADisplayLink?
var handle: (() -> Void)?
diff --git a/Source/RiveViewModel.swift b/Source/RiveViewModel.swift
index 857a02c..de21dcd 100644
--- a/Source/RiveViewModel.swift
+++ b/Source/RiveViewModel.swift
@@ -203,7 +203,7 @@ import Combine
didSet { riveView?.forwardsListenerEvents = forwardsListenerEvents }
}
- #if os(iOS)
+ #if os(iOS) || os(visionOS) || os(tvOS)
/// Hints to underlying CADisplayLink in RiveView (if created) the preferred FPS to run at
/// For more, see: https://developer.apple.com/documentation/quartzcore/cadisplaylink/1648421-preferredframespersecond
/// - Parameters:
@@ -614,7 +614,7 @@ import Combine
}
}
-#if os(iOS)
+#if os(iOS) || os(visionOS) || os(tvOS)
/// This makes a SwiftUI digestable view from an `RiveViewModel` and its `RiveView`
public struct RiveViewRepresentable: UIViewRepresentable {
let viewModel: RiveViewModel
diff --git a/scripts/build.rive.sh b/scripts/build.rive.sh
index 9199ed7..33768d2 100755
--- a/scripts/build.rive.sh
+++ b/scripts/build.rive.sh
@@ -147,8 +147,186 @@ build_runtime_macosx() {
cp -r $RIVE_RUNTIME_DIR/decoders/out/$1/librive_decoders.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_decoders_macos.a
}
+build_runtime_xros() {
+ # Build the rive runtime.
+ pushd $RIVE_RUNTIME_DIR
+ ./build.sh -p xros clean
+ ./build.sh -p xros $1
+ popd
+ cp -r $RIVE_RUNTIME_DIR/build/xros/bin/$1/librive.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_xros.a
+ cp -r $RIVE_RUNTIME_DIR/dependencies/xros/cache/bin/$1/librive_harfbuzz.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_harfbuzz_xros.a
+ cp -r $RIVE_RUNTIME_DIR/dependencies/xros/cache/bin/$1/librive_sheenbidi.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_sheenbidi_xros.a
+ cp -r $RIVE_RUNTIME_DIR/dependencies/xros/cache/bin/$1/librive_yoga.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_yoga_xros.a
+ cp -r $RIVE_RUNTIME_DIR/include $DEV_SCRIPT_DIR/../dependencies/includes/rive
+
+ # Build rive_cg_renderer.
+ pushd $RIVE_RUNTIME_DIR/cg_renderer
+ premake5 --config=$1 --out=out/xros_$1 --arch=universal --scripts=$RIVE_RUNTIME_DIR/build --os=ios --variant=xros gmake2
+ make -C out/xros_$1 clean
+ make -C out/xros_$1 -j12 rive_cg_renderer
+ popd
+ cp -r $RIVE_RUNTIME_DIR/cg_renderer/out/xros_$1/librive_cg_renderer.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_cg_renderer_xros.a
+ cp -r $RIVE_RUNTIME_DIR/cg_renderer/include $DEV_SCRIPT_DIR/../dependencies/includes/cg_renderer
+
+ # Build rive_pls_renderer.
+ pushd $RIVE_PLS_DIR
+ premake5 --config=$1 --out=out/xros_$1 --arch=universal --scripts=$RIVE_RUNTIME_DIR/build --file=premake5_pls_renderer.lua --os=ios --variant=xros gmake2
+ make -C out/xros_$1 clean
+ make -C out/xros_$1 -j12 rive_pls_renderer
+ popd
+ cp -r $RIVE_PLS_DIR/out/xros_$1/librive_pls_renderer.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_pls_renderer_xros.a
+ $DEV_SCRIPT_DIR/strip_static_lib.sh $DEV_SCRIPT_DIR/../dependencies/$1/librive_pls_renderer_xros.a
+ cp -r $RIVE_PLS_DIR/include $DEV_SCRIPT_DIR/../dependencies/includes/renderer
+
+ # Build rive_decoders.
+ pushd $RIVE_RUNTIME_DIR/decoders
+ premake5 --file=premake5_v2.lua --config=$1 --out=out/xros_$1 --arch=universal --scripts=$RIVE_RUNTIME_DIR/build --os=ios --variant=xros gmake2
+ make -C out/xros_$1 clean
+ make -C out/xros_$1 -j12 rive_decoders
+ popd
+ cp -r $RIVE_RUNTIME_DIR/decoders/out/xros_$1/librive_decoders.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_decoders_xros.a
+}
+
+build_runtime_xrsimulator() {
+ # Build the rive runtime.
+ pushd $RIVE_RUNTIME_DIR
+ ./build.sh -p xrsimulator clean
+ ./build.sh -p xrsimulator $1
+ popd
+ cp -r $RIVE_RUNTIME_DIR/build/xrsimulator/bin/$1/librive.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_xrsimulator.a
+ cp -r $RIVE_RUNTIME_DIR/dependencies/xrsimulator/cache/bin/$1/librive_harfbuzz.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_harfbuzz_xrsimulator.a
+ cp -r $RIVE_RUNTIME_DIR/dependencies/xrsimulator/cache/bin/$1/librive_sheenbidi.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_sheenbidi_xrsimulator.a
+ cp -r $RIVE_RUNTIME_DIR/dependencies/xrsimulator/cache/bin/$1/librive_yoga.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_yoga_xrsimulator.a
+ cp -r $RIVE_RUNTIME_DIR/include $DEV_SCRIPT_DIR/../dependencies/includes/rive
+
+ # Build rive_cg_renderer.
+ pushd $RIVE_RUNTIME_DIR/cg_renderer
+ premake5 --config=$1 --out=out/xrsimulator_$1 --arch=universal --scripts=$RIVE_RUNTIME_DIR/build --os=ios --variant=xrsimulator gmake2
+
+ make -C out/xrsimulator_$1 clean
+ make -C out/xrsimulator_$1 -j12 rive_cg_renderer
+ popd
+ cp -r $RIVE_RUNTIME_DIR/cg_renderer/out/xrsimulator_$1/librive_cg_renderer.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_cg_renderer_xrsimulator.a
+ cp -r $RIVE_RUNTIME_DIR/cg_renderer/include $DEV_SCRIPT_DIR/../dependencies/includes/cg_renderer
+
+ # Build rive_pls_renderer.
+ pushd $RIVE_PLS_DIR
+ premake5 --config=$1 --out=out/xrsimulator_$1 --arch=universal --scripts=$RIVE_RUNTIME_DIR/build --file=premake5_pls_renderer.lua --os=ios --variant=xrsimulator gmake2
+ make -C out/xrsimulator_$1 clean
+ make -C out/xrsimulator_$1 -j12 rive_pls_renderer
+ popd
+ cp -r $RIVE_PLS_DIR/out/xrsimulator_$1/librive_pls_renderer.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_pls_renderer_xrsimulator.a
+ $DEV_SCRIPT_DIR/strip_static_lib_fat.sh $DEV_SCRIPT_DIR/../dependencies/$1/librive_pls_renderer_xrsimulator.a arm64 x86_64
+ cp -r $RIVE_PLS_DIR/include $DEV_SCRIPT_DIR/../dependencies/includes/renderer
+
+ # Build rive_decoders.
+ pushd $RIVE_RUNTIME_DIR/decoders
+ premake5 --file=premake5_v2.lua --config=$1 --out=out/xrsimulator_$1 --arch=universal --scripts=$RIVE_RUNTIME_DIR/build --os=ios --variant=xrsimulator gmake2
+ make -C out/xrsimulator_$1 clean
+ make -C out/xrsimulator_$1 -j12 rive_decoders
+ popd
+ cp -r $RIVE_RUNTIME_DIR/decoders/out/xrsimulator_$1/librive_decoders.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_decoders_xrsimulator.a
+}
+
+build_runtime_appletvos() {
+ # Build the rive runtime.
+ pushd $RIVE_RUNTIME_DIR
+ ./build.sh -p appletvos clean
+ ./build.sh -p appletvos $1
+ popd
+ cp -r $RIVE_RUNTIME_DIR/build/appletvos/bin/$1/librive.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_appletvos.a
+ cp -r $RIVE_RUNTIME_DIR/dependencies/appletvos/cache/bin/$1/librive_harfbuzz.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_harfbuzz_appletvos.a
+ cp -r $RIVE_RUNTIME_DIR/dependencies/appletvos/cache/bin/$1/librive_sheenbidi.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_sheenbidi_appletvos.a
+ cp -r $RIVE_RUNTIME_DIR/dependencies/appletvos/cache/bin/$1/librive_yoga.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_yoga_appletvos.a
+ cp -r $RIVE_RUNTIME_DIR/include $DEV_SCRIPT_DIR/../dependencies/includes/rive
+
+ # Build rive_cg_renderer.
+ pushd $RIVE_RUNTIME_DIR/cg_renderer
+ premake5 --config=$1 --out=out/appletvos_$1 --arch=universal --scripts=$RIVE_RUNTIME_DIR/build --os=ios --variant=appletvos gmake2
+ make -C out/appletvos_$1 clean
+ make -C out/appletvos_$1 -j12 rive_cg_renderer
+ popd
+ cp -r $RIVE_RUNTIME_DIR/cg_renderer/out/appletvos_$1/librive_cg_renderer.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_cg_renderer_appletvos.a
+ cp -r $RIVE_RUNTIME_DIR/cg_renderer/include $DEV_SCRIPT_DIR/../dependencies/includes/cg_renderer
+
+ # Build rive_pls_renderer.
+ pushd $RIVE_PLS_DIR
+ premake5 --config=$1 --out=out/appletvos_$1 --arch=universal --scripts=$RIVE_RUNTIME_DIR/build --file=premake5_pls_renderer.lua --os=ios --variant=appletvos gmake2
+ make -C out/appletvos_$1 clean
+ make -C out/appletvos_$1 -j12 rive_pls_renderer
+ popd
+ cp -r $RIVE_PLS_DIR/out/appletvos_$1/librive_pls_renderer.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_pls_renderer_appletvos.a
+ $DEV_SCRIPT_DIR/strip_static_lib.sh $DEV_SCRIPT_DIR/../dependencies/$1/librive_pls_renderer_appletvos.a
+ cp -r $RIVE_PLS_DIR/include $DEV_SCRIPT_DIR/../dependencies/includes/renderer
+
+ # Build rive_decoders.
+ pushd $RIVE_RUNTIME_DIR/decoders
+ premake5 --file=premake5_v2.lua --config=$1 --out=out/appletvos_$1 --arch=universal --scripts=$RIVE_RUNTIME_DIR/build --os=ios --variant=appletvos gmake2
+ make -C out/appletvos_$1 clean
+ make -C out/appletvos_$1 -j12 rive_decoders
+ make -C out/appletvos_$1 -j12 libpng
+ make -C out/appletvos_$1 -j12 zlib
+ make -C out/appletvos_$1 -j12 libjpeg
+ make -C out/appletvos_$1 -j12 libwebp
+ popd
+ cp -r $RIVE_RUNTIME_DIR/decoders/out/appletvos_$1/librive_decoders.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_decoders_appletvos.a
+ cp -r $RIVE_RUNTIME_DIR/decoders/out/appletvos_$1/liblibpng.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_png_appletvos.a
+ cp -r $RIVE_RUNTIME_DIR/decoders/out/appletvos_$1/libzlib.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_zlib_appletvos.a
+ cp -r $RIVE_RUNTIME_DIR/decoders/out/appletvos_$1/liblibjpeg.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_jpeg_appletvos.a
+ cp -r $RIVE_RUNTIME_DIR/decoders/out/appletvos_$1/liblibwebp.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_webp_appletvos.a
+}
+
+build_runtime_appletvsimulator() {
+ # Build the rive runtime.
+ pushd $RIVE_RUNTIME_DIR
+ ./build.sh -p appletvsimulator clean
+ ./build.sh -p appletvsimulator $1
+ popd
+ cp -r $RIVE_RUNTIME_DIR/build/appletvsimulator/bin/$1/librive.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_appletvsimulator.a
+ cp -r $RIVE_RUNTIME_DIR/dependencies/appletvsimulator/cache/bin/$1/librive_harfbuzz.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_harfbuzz_appletvsimulator.a
+ cp -r $RIVE_RUNTIME_DIR/dependencies/appletvsimulator/cache/bin/$1/librive_sheenbidi.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_sheenbidi_appletvsimulator.a
+ cp -r $RIVE_RUNTIME_DIR/dependencies/appletvsimulator/cache/bin/$1/librive_yoga.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_yoga_appletvsimulator.a
+ cp -r $RIVE_RUNTIME_DIR/include $DEV_SCRIPT_DIR/../dependencies/includes/rive
+
+ # Build rive_cg_renderer.
+ pushd $RIVE_RUNTIME_DIR/cg_renderer
+ premake5 --config=$1 --out=out/appletvsimulator_$1 --arch=universal --scripts=$RIVE_RUNTIME_DIR/build --os=ios --variant=appletvsimulator gmake2
+
+ make -C out/appletvsimulator_$1 clean
+ make -C out/appletvsimulator_$1 -j12 rive_cg_renderer
+ popd
+ cp -r $RIVE_RUNTIME_DIR/cg_renderer/out/appletvsimulator_$1/librive_cg_renderer.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_cg_renderer_appletvsimulator.a
+ cp -r $RIVE_RUNTIME_DIR/cg_renderer/include $DEV_SCRIPT_DIR/../dependencies/includes/cg_renderer
+
+ # Build rive_pls_renderer.
+ pushd $RIVE_PLS_DIR
+ premake5 --config=$1 --out=out/appletvsimulator_$1 --arch=universal --scripts=$RIVE_RUNTIME_DIR/build --file=premake5_pls_renderer.lua --os=ios --variant=appletvsimulator gmake2
+ make -C out/appletvsimulator_$1 clean
+ make -C out/appletvsimulator_$1 -j12 rive_pls_renderer
+ popd
+ cp -r $RIVE_PLS_DIR/out/appletvsimulator_$1/librive_pls_renderer.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_pls_renderer_appletvsimulator.a
+ $DEV_SCRIPT_DIR/strip_static_lib_fat.sh $DEV_SCRIPT_DIR/../dependencies/$1/librive_pls_renderer_appletvsimulator.a arm64 x86_64
+ cp -r $RIVE_PLS_DIR/include $DEV_SCRIPT_DIR/../dependencies/includes/renderer
+
+ # Build rive_decoders.
+ pushd $RIVE_RUNTIME_DIR/decoders
+ premake5 --file=premake5_v2.lua --config=$1 --out=out/appletvsimulator_$1 --arch=universal --scripts=$RIVE_RUNTIME_DIR/build --os=ios --variant=appletvsimulator gmake2
+ make -C out/appletvsimulator_$1 clean
+ make -C out/appletvsimulator_$1 -j12 rive_decoders
+ make -C out/appletvsimulator_$1 -j12 libpng
+ make -C out/appletvsimulator_$1 -j12 zlib
+ make -C out/appletvsimulator_$1 -j12 libjpeg
+ make -C out/appletvsimulator_$1 -j12 libwebp
+ popd
+ cp -r $RIVE_RUNTIME_DIR/decoders/out/appletvsimulator_$1/librive_decoders.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_decoders_appletvsimulator.a
+ cp -r $RIVE_RUNTIME_DIR/decoders/out/appletvsimulator_$1/liblibpng.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_png_appletvsimulator.a
+ cp -r $RIVE_RUNTIME_DIR/decoders/out/appletvsimulator_$1/libzlib.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_zlib_appletvsimulator.a
+ cp -r $RIVE_RUNTIME_DIR/decoders/out/appletvsimulator_$1/liblibjpeg.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_jpeg_appletvsimulator.a
+ cp -r $RIVE_RUNTIME_DIR/decoders/out/appletvsimulator_$1/liblibwebp.a $DEV_SCRIPT_DIR/../dependencies/$1/librive_webp_appletvsimulator.a
+}
+
usage() {
- echo "USAGE: $0 "
+ echo "USAGE: $0 "
exit 1
}
@@ -165,6 +343,14 @@ all)
build_runtime_sim release
build_runtime_macosx debug
build_runtime_macosx release
+ build_runtime_xros debug
+ build_runtime_xros release
+ build_runtime_xrsimulator debug
+ build_runtime_xrsimulator release
+ build_runtime_appletvos debug
+ build_runtime_appletvos release
+ build_runtime_appletvsimulator debug
+ build_runtime_appletvsimulator release
;;
macosx)
if (($# < 2)); then
@@ -214,6 +400,74 @@ ios_sim)
;;
esac
;;
+xros)
+ if (($# < 2)); then
+ usage
+ fi
+ case $2 in
+ release | debug)
+ make_dependency_directories
+ build_runtime_xros $2
+ ;;
+ *)
+ usage
+ ;;
+ esac
+ ;;
+xrsimulator)
+ if (($# < 2)); then
+ usage
+ fi
+ case $2 in
+ release | debug)
+ make_dependency_directories
+ build_runtime_xrsimulator $2
+ # TODO:
+ # to build for the example you need debug, but to profile you need release.
+ # each time you build, both version are removed. to imnprove this only remove
+ # the version being built, or add a "both" option.
+ # build_runtime_sim debug
+ # build_runtime_sim release
+ ;;
+ *)
+ usage
+ ;;
+ esac
+ ;;
+appletvos)
+ if (($# < 2)); then
+ usage
+ fi
+ case $2 in
+ release | debug)
+ make_dependency_directories
+ build_runtime_appletvos $2
+ ;;
+ *)
+ usage
+ ;;
+ esac
+ ;;
+appletvsimulator)
+ if (($# < 2)); then
+ usage
+ fi
+ case $2 in
+ release | debug)
+ make_dependency_directories
+ build_runtime_appletvsimulator $2
+ # TODO:
+ # to build for the example you need debug, but to profile you need release.
+ # each time you build, both version are removed. to imnprove this only remove
+ # the version being built, or add a "both" option.
+ # build_runtime_sim debug
+ # build_runtime_sim release
+ ;;
+ *)
+ usage
+ ;;
+ esac
+ ;;
*)
usage
;;
diff --git a/scripts/build_framework.sh b/scripts/build_framework.sh
index 1042a8f..4ba5b03 100755
--- a/scripts/build_framework.sh
+++ b/scripts/build_framework.sh
@@ -53,9 +53,53 @@ xcodebuild archive \
SKIP_INSTALL=NO \
BUILD_LIBRARY_FOR_DISTRIBUTION=YES
+xcodebuild archive \
+ -configuration ${CONFIGURATION} \
+ -project RiveRuntime.xcodeproj \
+ -scheme RiveRuntime \
+ -sdk xros \
+ -destination generic/platform=visionOS \
+ -archivePath ".build/archives/RiveRuntime_visionOS" \
+ SKIP_INSTALL=NO \
+ BUILD_LIBRARY_FOR_DISTRIBUTION=YES
+
+xcodebuild archive \
+ -configuration ${CONFIGURATION} \
+ -project RiveRuntime.xcodeproj \
+ -scheme RiveRuntime \
+ -sdk xrsimulator \
+ -destination "generic/platform=visionOS Simulator" \
+ -archivePath ".build/archives/RiveRuntime_visionOS_Simulator" \
+ SKIP_INSTALL=NO \
+ BUILD_LIBRARY_FOR_DISTRIBUTION=YES
+
+xcodebuild archive \
+ -configuration ${CONFIGURATION} \
+ -project RiveRuntime.xcodeproj \
+ -scheme RiveRuntime \
+ -sdk appletvos \
+ -destination generic/platform=tvOS \
+ -archivePath ".build/archives/RiveRuntime_tvOS" \
+ SKIP_INSTALL=NO \
+ BUILD_LIBRARY_FOR_DISTRIBUTION=YES
+
+xcodebuild archive \
+ -configuration ${CONFIGURATION} \
+ -project RiveRuntime.xcodeproj \
+ -scheme RiveRuntime \
+ -sdk appletvsimulator \
+ -destination "generic/platform=tvOS Simulator" \
+ -archivePath ".build/archives/RiveRuntime_tvOS_Simulator" \
+ SKIP_INSTALL=NO \
+ BUILD_LIBRARY_FOR_DISTRIBUTION=YES
+
xcodebuild \
-create-xcframework \
-framework .build/archives/RiveRuntime_iOS.xcarchive/Products/Library/Frameworks/RiveRuntime.framework \
-framework .build/archives/RiveRuntime_iOS_Simulator.xcarchive/Products/Library/Frameworks/RiveRuntime.framework \
-framework .build/archives/RiveRuntime_macOS.xcarchive/Products/Library/Frameworks/RiveRuntime.framework \
+ -framework .build/archives/RiveRuntime_visionOS.xcarchive/Products/Library/Frameworks/RiveRuntime.framework \
+ -framework .build/archives/RiveRuntime_visionOS_Simulator.xcarchive/Products/Library/Frameworks/RiveRuntime.framework \
+ -framework .build/archives/RiveRuntime_tvOS.xcarchive/Products/Library/Frameworks/RiveRuntime.framework \
+ -framework .build/archives/RiveRuntime_tvOS_Simulator.xcarchive/Products/Library/Frameworks/RiveRuntime.framework \
-output archive/RiveRuntime.xcframework
\ No newline at end of file
diff --git a/scripts/test.sh b/scripts/test.sh
index c5b37b7..ac69851 100755
--- a/scripts/test.sh
+++ b/scripts/test.sh
@@ -1,7 +1,52 @@
set -eo pipefail
-# test RiveRuntime on a simulator
-xcodebuild -workspace Rive.xcworkspace \
- -scheme RiveRuntime \
- -destination platform=iOS\ Simulator,name=iPhone\ 15 \
- clean test | xcpretty
+test_ios_simulator() {
+ echo "=== Running tests on iOS Simulator ==="
+ # Test RiveRuntime on a iOS simulator
+ xcodebuild -workspace Rive.xcworkspace \
+ -scheme RiveRuntime \
+ -destination platform=iOS\ Simulator,name=iPhone\ 15 \
+ clean test | xcpretty
+}
+
+test_visionos_simulator() {
+ echo "=== Running tests on visionOS Simulator ==="
+ # Test RiveRuntime on a visionOS simulator
+ xcodebuild -workspace Rive.xcworkspace \
+ -scheme RiveRuntime \
+ -destination platform=visionOS\ Simulator,name=Apple\ Vision\ Pro \
+ clean test | xcpretty
+}
+
+test_tvos_simulator() {
+ echo "=== Running tests on tvOS Simulator ==="
+ # Test RiveRuntime on a tvOS simulator
+ xcodebuild -workspace Rive.xcworkspace \
+ -scheme RiveRuntime \
+ -destination platform=tvOS\ Simulator,name=Apple\ TV\ 4K\ \(3rd\ generation\) \
+ clean test | xcpretty
+}
+
+usage() {
+ echo "USAGE: $0 ios_sim|xrsimulator|appletvsimulator"
+ exit 1
+}
+
+if [[ $# -ne 1 ]]; then
+ usage
+fi
+
+case $1 in
+ios_sim)
+ test_ios_simulator
+ ;;
+xrsimulator)
+ test_visionos_simulator
+ ;;
+appletvsimulator)
+ test_tvos_simulator
+ ;;
+*)
+ usage
+ ;;
+esac
diff --git a/submodules/rive-runtime b/submodules/rive-runtime
index e27fe66..f8c6fc4 160000
--- a/submodules/rive-runtime
+++ b/submodules/rive-runtime
@@ -1 +1 @@
-Subproject commit e27fe665377a770989307fbbb8dd65c0d2eb02c4
+Subproject commit f8c6fc41890792f5c6b92b3281cb2e5d710d91a8