rive-app/rive-ios

Support custom Bundles in RiveFile convenience init

Closed this issue · 2 comments

Problem

By now RiveFile+Extensions.swift does not support user-defined modules. This results in boilerplate code when using Rive animations from SPM projects with a single bundle for each target/module.

Consider the following example:
Repo layout:

Sources/ModuleA/Resources/Animation.riv
Sources/ModuleA/A.swift
Sources/ModuleA/Resources/Animation.riv
Sources/ModuleA/B.swift

Code inside A.swift:

struct AView: View {
  var animation = { () -> RiveViewModel? in
    guard
      let url = Bundle.module.url(forResource: "Animation", withExtension: "riv"),
      var data = try? Data(contentsOf: url),
      let file = try? data.withUnsafeMutableBytes({ [count=data.count] (bytes) -> RiveFile? in
        guard let baseAddress = bytes.baseAddress else { return nil }
        return try RiveFile(
          bytes: baseAddress.bindMemory(to: UInt8.self, capacity: count),
          byteLength: UInt64(count)
        )
      })
    else { return nil }
    let model = RiveModel(riveFile: file)
    return RiveViewModel(model)
  }()
}

Proposal

Add bundle parameter to RiveFile.init(name:extension:), like this:

convenience init(name fileName: String, extension ext: String = ".riv", bundle: Bundle = .main) throws {
jaanus commented

I agree that it’s currently suboptimal for multiple bundles, something better is needed. I use a similar workaround for data.

For safer and shorter code when initializing from data, I just cast the data.

let data = Data(whatever)
let riveFile = RiveFile(byteArray: [UInt8](data))

Was implemented here: #250