Skip to content

Commit 3bde6bd

Browse files
committed
fix(ios): refresh after updating the asset
1 parent 47e3abc commit 3bde6bd

File tree

6 files changed

+207
-50
lines changed

6 files changed

+207
-50
lines changed

example/ios/Podfile.lock

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ PODS:
88
- hermes-engine (0.79.2):
99
- hermes-engine/Pre-built (= 0.79.2)
1010
- hermes-engine/Pre-built (0.79.2)
11-
- NitroModules (0.31.3):
11+
- NitroModules (0.31.4):
1212
- DoubleConversion
1313
- glog
1414
- hermes-engine
@@ -1357,7 +1357,7 @@ PODS:
13571357
- React-jsiexecutor
13581358
- React-RCTFBReactNativeSpec
13591359
- ReactCommon/turbomodule/core
1360-
- react-native-safe-area-context (5.4.0):
1360+
- react-native-safe-area-context (5.6.2):
13611361
- DoubleConversion
13621362
- glog
13631363
- hermes-engine
@@ -1372,8 +1372,8 @@ PODS:
13721372
- React-hermes
13731373
- React-ImageManager
13741374
- React-jsi
1375-
- react-native-safe-area-context/common (= 5.4.0)
1376-
- react-native-safe-area-context/fabric (= 5.4.0)
1375+
- react-native-safe-area-context/common (= 5.6.2)
1376+
- react-native-safe-area-context/fabric (= 5.6.2)
13771377
- React-NativeModulesApple
13781378
- React-RCTFabric
13791379
- React-renderercss
@@ -1383,7 +1383,7 @@ PODS:
13831383
- ReactCommon/turbomodule/bridging
13841384
- ReactCommon/turbomodule/core
13851385
- Yoga
1386-
- react-native-safe-area-context/common (5.4.0):
1386+
- react-native-safe-area-context/common (5.6.2):
13871387
- DoubleConversion
13881388
- glog
13891389
- hermes-engine
@@ -1407,7 +1407,7 @@ PODS:
14071407
- ReactCommon/turbomodule/bridging
14081408
- ReactCommon/turbomodule/core
14091409
- Yoga
1410-
- react-native-safe-area-context/fabric (5.4.0):
1410+
- react-native-safe-area-context/fabric (5.6.2):
14111411
- DoubleConversion
14121412
- glog
14131413
- hermes-engine
@@ -1781,7 +1781,31 @@ PODS:
17811781
- RiveRuntime (= 6.12.0)
17821782
- Yoga
17831783
- RiveRuntime (6.12.0)
1784-
- RNGestureHandler (2.25.0):
1784+
- RNCPicker (2.11.4):
1785+
- DoubleConversion
1786+
- glog
1787+
- hermes-engine
1788+
- RCT-Folly (= 2024.11.18.00)
1789+
- RCTRequired
1790+
- RCTTypeSafety
1791+
- React-Core
1792+
- React-debug
1793+
- React-Fabric
1794+
- React-featureflags
1795+
- React-graphics
1796+
- React-hermes
1797+
- React-ImageManager
1798+
- React-jsi
1799+
- React-NativeModulesApple
1800+
- React-RCTFabric
1801+
- React-renderercss
1802+
- React-rendererdebug
1803+
- React-utils
1804+
- ReactCodegen
1805+
- ReactCommon/turbomodule/bridging
1806+
- ReactCommon/turbomodule/core
1807+
- Yoga
1808+
- RNGestureHandler (2.29.1):
17851809
- DoubleConversion
17861810
- glog
17871811
- hermes-engine
@@ -1883,6 +1907,7 @@ DEPENDENCIES:
18831907
- ReactCodegen (from `build/generated/ios`)
18841908
- ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`)
18851909
- Rive (from `../..`)
1910+
- "RNCPicker (from `../node_modules/@react-native-picker/picker`)"
18861911
- RNGestureHandler (from `../node_modules/react-native-gesture-handler`)
18871912
- Yoga (from `../node_modules/react-native/ReactCommon/yoga`)
18881913

@@ -2037,6 +2062,8 @@ EXTERNAL SOURCES:
20372062
:path: "../node_modules/react-native/ReactCommon"
20382063
Rive:
20392064
:path: "../.."
2065+
RNCPicker:
2066+
:path: "../node_modules/@react-native-picker/picker"
20402067
RNGestureHandler:
20412068
:path: "../node_modules/react-native-gesture-handler"
20422069
Yoga:
@@ -2050,7 +2077,7 @@ SPEC CHECKSUMS:
20502077
fmt: a40bb5bd0294ea969aaaba240a927bd33d878cdd
20512078
glog: 5683914934d5b6e4240e497e0f4a3b42d1854183
20522079
hermes-engine: 314be5250afa5692b57b4dd1705959e1973a8ebe
2053-
NitroModules: bb52372447b073b536ecc728f79fbd1242547738
2080+
NitroModules: 8229091083785ae690dc9071f07fc412e0cb8243
20542081
RCT-Folly: 36fe2295e44b10d831836cc0d1daec5f8abcf809
20552082
RCTDeprecation: 83ffb90c23ee5cea353bd32008a7bca100908f8c
20562083
RCTRequired: eb7c0aba998009f47a540bec9e9d69a54f68136e
@@ -2082,7 +2109,7 @@ SPEC CHECKSUMS:
20822109
React-logger: 368570a253f00879a1e4fea24ed4047e72e7bbf3
20832110
React-Mapbuffer: c04fcda1c6281fc0a6824c7dcc1633dd217ac1ec
20842111
React-microtasksnativemodule: ca2804a25fdcefffa0aa942aa23ab53b99614a34
2085-
react-native-safe-area-context: 00d03dc688ba86664be66f9e3f203fc7d747d899
2112+
react-native-safe-area-context: bc59472155ffb889a1ffe16c19a04c0cd451562b
20862113
React-NativeModulesApple: 452b86b29fae99ed0a4015dca3ad9cd222f88abf
20872114
React-oscompat: ef5df1c734f19b8003e149317d041b8ce1f7d29c
20882115
React-perflogger: 6fd2f6811533e9c19a61e855c3033eecbf4ad2a0
@@ -2114,9 +2141,10 @@ SPEC CHECKSUMS:
21142141
ReactAppDependencyProvider: d5dcc564f129632276bd3184e60f053fcd574d6b
21152142
ReactCodegen: fda99a79c866370190e162083a35602fdc314e5d
21162143
ReactCommon: 4d0da92a5eb8da86c08e3ec34bd23ab439fb2461
2117-
Rive: 3bd6bb2febc263defec083afd3a4fb29b82efeb9
2144+
Rive: b83a5c913ae79218b9e33f22bbe77d860de54eec
21182145
RiveRuntime: 8d819993126145fbf5a73089e7634b14b9aa577f
2119-
RNGestureHandler: 5d8431415d4b8518e86e289e9ad5bb9be78f6dba
2146+
RNCPicker: 83c74db2de8274d8a8f3e18d91dea174a708f8c4
2147+
RNGestureHandler: bff91bb5ab5688265c70f74180ef718b94f33fe3
21202148
SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748
21212149
Yoga: 9f110fc4b7aa538663cba3c14cbb1c335f43c13f
21222150

ios/HybridRiveFile.swift

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,28 @@ class HybridRiveFile: HybridRiveFileSpec {
66
var riveFile: RiveFile?
77
var referencedAssetCache: ReferencedAssetCache?
88
var assetLoader: ReferencedAssetLoader?
9+
private var weakViews: [Weak<RiveReactNativeView>] = []
910

1011
public func setRiveFile(_ riveFile: RiveFile) {
1112
self.riveFile = riveFile
1213
}
14+
15+
func registerView(_ view: RiveReactNativeView) {
16+
weakViews.append(Weak(value: view))
17+
}
18+
19+
func unregisterView(_ view: RiveReactNativeView) {
20+
weakViews.removeAll { $0.value === view }
21+
}
22+
23+
private func refreshAfterAssetChange() {
24+
weakViews = weakViews.filter { $0.value != nil }
25+
26+
for weakView in weakViews {
27+
guard let view = weakView.value else { continue }
28+
view.refreshAfterAssetChange()
29+
}
30+
}
1331

1432
var viewModelCount: Double? {
1533
guard let count = riveFile?.viewModelCount else { return nil }
@@ -53,15 +71,19 @@ class HybridRiveFile: HybridRiveFileSpec {
5371
guard let assetsData = referencedAssets.data,
5472
let cache = referencedAssetCache,
5573
let loader = assetLoader,
56-
let riveFile = riveFile else {
74+
let _ = riveFile else {
5775
return
5876
}
5977

60-
let factory = RiveFactory()
61-
78+
var hasChanged = false
6279
for (key, assetData) in assetsData {
6380
guard let asset = cache[key] else { continue }
64-
loader.loadAsset(source: assetData, asset: asset, factory: factory)
81+
loader.loadAsset(source: assetData, asset: asset)
82+
hasChanged = true
83+
}
84+
85+
if hasChanged {
86+
refreshAfterAssetChange()
6587
}
6688
}
6789

ios/HybridRiveFileFactory.swift

Lines changed: 42 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ import NitroModules
22
import RiveRuntime
33

44
final class HybridRiveFileFactory: HybridRiveFileFactorySpec {
5+
let assetLoader = ReferencedAssetLoader()
6+
57
private func buildRiveFile(data: Data, loadCdn: Bool, referencedAssets: ReferencedAssetsType?) throws -> (file: RiveFile, cache: ReferencedAssetCache, loader: ReferencedAssetLoader?) {
6-
var referencedAssetCache = Ref(ReferencedAssetCache())
7-
let assetLoader = ReferencedAssetLoader()
8+
var referencedAssetCache = SendableRef(ReferencedAssetCache())
89
let customLoader = assetLoader.createCustomLoader(referencedAssets: referencedAssets, cache: referencedAssetCache)
910

1011
let riveFile = if let customLoader = customLoader {
@@ -17,21 +18,20 @@ final class HybridRiveFileFactory: HybridRiveFileFactorySpec {
1718
}
1819

1920
// MARK: Public Methods
20-
func fromURL(url: String, loadCdn: Bool) throws -> Promise<(any HybridRiveFileSpec)> {
21-
// TODO: should we make use of the underlying Rive iOS URL asset loading instead
21+
func fromURL(url: String, loadCdn: Bool, referencedAssets: ReferencedAssetsType?) throws -> Promise<(any HybridRiveFileSpec)> {
2222
return Promise.async {
2323
do {
2424
guard let url = URL(string: url) else {
2525
throw RuntimeError.error(withMessage: "Invalid URL: \(url)")
2626
}
2727

28-
let riveFile = try await withCheckedThrowingContinuation { continuation in
28+
let result = try await withCheckedThrowingContinuation { continuation in
2929
DispatchQueue.global(qos: .userInitiated).async {
3030
do {
3131
let riveData = try Data(contentsOf: url)
32-
let riveFile = try RiveFile(data: riveData, loadCdn: true)
32+
let result = try self.buildRiveFile(data: riveData, loadCdn: loadCdn, referencedAssets: referencedAssets)
3333
DispatchQueue.main.async {
34-
continuation.resume(returning: riveFile)
34+
continuation.resume(returning: result)
3535
}
3636
} catch {
3737
DispatchQueue.main.async {
@@ -42,7 +42,9 @@ final class HybridRiveFileFactory: HybridRiveFileFactorySpec {
4242
}
4343

4444
let hybridRiveFile = HybridRiveFile()
45-
hybridRiveFile.riveFile = riveFile
45+
hybridRiveFile.riveFile = result.file
46+
hybridRiveFile.referencedAssetCache = result.cache
47+
hybridRiveFile.assetLoader = result.loader
4648
return hybridRiveFile
4749
} catch let error as NSError {
4850
throw RuntimeError.error(
@@ -53,7 +55,7 @@ final class HybridRiveFileFactory: HybridRiveFileFactorySpec {
5355
}
5456
}
5557

56-
func fromFileURL(fileURL: String, loadCdn: Bool) throws -> Promise<(any HybridRiveFileSpec)> {
58+
func fromFileURL(fileURL: String, loadCdn: Bool, referencedAssets: ReferencedAssetsType?) throws -> Promise<(any HybridRiveFileSpec)> {
5759
guard let url = URL(string: fileURL) else {
5860
throw RuntimeError.error(withMessage: "fromFileURL: Invalid URL: \(fileURL)")
5961
}
@@ -64,18 +66,30 @@ final class HybridRiveFileFactory: HybridRiveFileFactorySpec {
6466

6567
return Promise.async {
6668
do {
67-
let riveFile = try await withCheckedThrowingContinuation { continuation in
69+
let result = try await withCheckedThrowingContinuation { continuation in
6870
DispatchQueue.global(qos: .userInitiated).async {
6971
do {
7072
let data = try Data(contentsOf: url)
73+
let result = try self.buildRiveFile(data: data, loadCdn: loadCdn, referencedAssets: referencedAssets)
74+
DispatchQueue.main.async {
75+
continuation.resume(returning: result)
76+
}
77+
} catch {
78+
DispatchQueue.main.async {
79+
continuation.resume(throwing: error)
80+
}
81+
}
82+
}
83+
}
7184

7285
let hybridRiveFile = HybridRiveFile()
73-
hybridRiveFile.riveFile = riveFile.file
74-
hybridRiveFile.referencedAssetCache = riveFile.cache
75-
hybridRiveFile.assetLoader = riveFile.loader
86+
hybridRiveFile.riveFile = result.file
87+
hybridRiveFile.referencedAssetCache = result.cache
88+
hybridRiveFile.assetLoader = result.loader
7689
return hybridRiveFile
7790
} catch let error as NSError {
78-
throw RuntimeError.error(withMessage: "Failed to load Rive file: \(error.localizedDescription)")
91+
throw RuntimeError.error(
92+
withMessage: "Failed to load Rive file: \(error.localizedDescription)")
7993
} catch {
8094
throw RuntimeError.error(withMessage: "Unknown error occurred while loading Rive file")
8195
}
@@ -89,13 +103,13 @@ final class HybridRiveFileFactory: HybridRiveFileFactorySpec {
89103

90104
return Promise.async {
91105
do {
92-
106+
let assetLoader = self.assetLoader
107+
let referencedAssetCache = SendableRef(ReferencedAssetCache())
93108
let riveFile = try await withCheckedThrowingContinuation { continuation in
94109
DispatchQueue.global(qos: .userInitiated).async {
95110
do {
96-
var referencedAssetCache = Ref(ReferencedAssetCache())
97111
let riveFile =
98-
if let customLoader = self.assetLoader.createCustomLoader(referencedAssets: referencedAssets, cache: referencedAssetCache) {
112+
if let customLoader = assetLoader.createCustomLoader(referencedAssets: referencedAssets, cache: referencedAssetCache) {
99113
try RiveFile(resource: resource, loadCdn: loadCdn, customAssetLoader: customLoader)
100114
} else {
101115
try RiveFile(resource: resource, loadCdn: loadCdn)
@@ -113,6 +127,10 @@ final class HybridRiveFileFactory: HybridRiveFileFactorySpec {
113127

114128
let hybridRiveFile = HybridRiveFile()
115129
hybridRiveFile.riveFile = riveFile
130+
if referencedAssets != nil {
131+
hybridRiveFile.referencedAssetCache = referencedAssetCache.value
132+
hybridRiveFile.assetLoader = assetLoader
133+
}
116134
return hybridRiveFile
117135
} catch let error as NSError {
118136
throw RuntimeError.error(
@@ -157,25 +175,18 @@ final class HybridRiveFileFactory: HybridRiveFileFactorySpec {
157175
}
158176
}
159177

160-
func fromBytes(bytes: ArrayBufferHolder, loadCdn: Bool) throws -> Promise<
178+
func fromBytes(bytes: ArrayBufferHolder, loadCdn: Bool, referencedAssets: ReferencedAssetsType?) throws -> Promise<
161179
(any HybridRiveFileSpec)
162180
> {
163181
let data = bytes.toData(copyIfNeeded: false)
164182
return Promise.async {
165183
do {
166-
let riveFile = try await withCheckedThrowingContinuation { continuation in
184+
let result = try await withCheckedThrowingContinuation { continuation in
167185
DispatchQueue.global(qos: .userInitiated).async {
168186
do {
169-
var referencedAssetCache = Ref(ReferencedAssetCache())
170-
let riveFile =
171-
if let customLoader = self.assetLoader.createCustomLoader(referencedAssets: referencedAssets, cache: referencedAssetCache) {
172-
try RiveFile(data: data, loadCdn: loadCdn, customAssetLoader: customLoader)
173-
} else {
174-
try RiveFile(data: data, loadCdn: loadCdn)
175-
}
176-
187+
let result = try self.buildRiveFile(data: data, loadCdn: loadCdn, referencedAssets: referencedAssets)
177188
DispatchQueue.main.async {
178-
continuation.resume(returning: riveFile)
189+
continuation.resume(returning: result)
179190
}
180191
} catch {
181192
DispatchQueue.main.async {
@@ -186,7 +197,9 @@ final class HybridRiveFileFactory: HybridRiveFileFactorySpec {
186197
}
187198

188199
let hybridRiveFile = HybridRiveFile()
189-
hybridRiveFile.riveFile = riveFile
200+
hybridRiveFile.riveFile = result.file
201+
hybridRiveFile.referencedAssetCache = result.cache
202+
hybridRiveFile.assetLoader = result.loader
190203
return hybridRiveFile
191204
} catch let error as NSError {
192205
throw RuntimeError.error(

ios/HybridRiveView.swift

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,19 +83,21 @@ class HybridRiveView : HybridRiveViewSpec {
8383

8484
// MARK: Update
8585
func afterUpdate() {
86-
guard let file = (file as? HybridRiveFile)?.riveFile else { return }
87-
86+
guard let hybridFile = file as? HybridRiveFile,
87+
let file = hybridFile.riveFile else { return }
88+
8889
let config = ViewConfiguration(
8990
artboardName: artboardName,
9091
stateMachineName: stateMachineName,
9192
autoBind: autoBind ?? DefaultConfiguration.autoBind,
9293
autoPlay: autoPlay ?? DefaultConfiguration.autoPlay,
9394
riveFile: file,
95+
hybridRiveFile: hybridFile,
9496
alignment: convertAlignment(alignment) ?? DefaultConfiguration.alignment,
9597
fit: convertFit(fit) ?? DefaultConfiguration.fit,
9698
layoutScaleFactor: layoutScaleFactor ?? DefaultConfiguration.layoutScaleFactor
9799
)
98-
100+
99101
try? getRiveView().configure(config, reload: needsReload)
100102
needsReload = false
101103
}

0 commit comments

Comments
 (0)