Swift 4.2 - Cocoapods: Adding and accessing scnassets in resource_bundles

Viewed 1592

Attempting to create a cocoapod that utilizes an .scnassets folder. The folder is imported into Resources without any problems with the children objects, but I can't find a way to load the .dae files into an SCNScene. From my understanding there may be a problem with how XCode converts .dae into .scn assets.

.podspec includes:

  s.resource_bundles = {
      'ARUtilsScenes' => ['ARUtils/Assets/ARScenes.scnassets']
   }

which properly loads the ARScenes.scnassets into Resources folder. I'm attempting to load a scene inside of my Pod (inside the pod and not a project that uses the pod, and have tried a variety of methods):

let arrowScene = SCNScene(named: "arrow.dae")

let arrowScene = SCNScene(named: "Resources/ARScenes.scnassets/arrow.dae")

let arrowScene = SCNScene(named: "arrow.dae", inDirectory: "Resources/ARScenes.scnassets", options: nil)

I've tried a variety of file/folder names, and am able to load images but I'm not able to get a .dae loaded as an SCNScene. Do I need to add .xib files to my resource_bundles, or is there some other way to ensure .scnassets folder properly compiles these .dae to .scn as well as make them available for loading into an SCNScene?

3 Answers

Suppose ZARKit is your framework distributed in CocoaPods.

.podspec includes:

s.resource_bundles = {
      'ARUtilsScenes' => ['ARUtils/Assets/ARScenes.scnassets']
   }

then you should do this

let bundle = Bundle(for: #Your Class#.self).
let resourcePath = bundle.path(forResource: <#T##String?#>, ofType: <#T##String?#>)
let resourceBundle = Bundle(path: resourcePath)

let url = resourceBundle.url(forResource: "ARScenes.scnassets/<#YourResourceName-arrow#>", withExtension: "<#scn#>")
let arrowScene = SCNScene(url: url)

edit: by Z. Bagley

Accepted answer, but this was the actual code I used:

        // find bundle based on existing class in pod
        let frameworkBundle = Bundle(for: ARUtilsClass.self) //ARUtilsClass is an empty class, Pod is only extensions for existing classes
        // append the scenes bundle, scnassets, and scn/dae
        let arrowURL = frameworkBundle.resourceURL?.appendingPathComponent("ARUtilsScenes.bundle/ARScenes.scnassets/newArrow.scn")
        // create a node in parent
        var arrow = SCNNode()
        do {
            // get arrow scene from bundle
            let bundleArrowScene = try SCNScene(url: (arrowURL)!, options: nil)
            // add arrow node from scene
            arrow = bundleArrowScene.rootNode.childNode(withName: "arrow", recursively: true)!
        } catch {
            print("failed to find arrow resource")
        }

When accessing the .dae asset from the .scnassets folder, there should be no need to include the "Resources/" in the path

For example: let arrowScene = SCNScene(named: "ARScenes.scnassets/arrow.dae")

Assuming that your .scnassets folder is called that.

There is a known bug introduced with updated build system by Apple which causes asynchronous compilation of asset catalogs making them unaccessible in the final build. For reference see this thread on Cocoapods GitHub. There are several workarounds for this listed, but none of them guarantee the results, so for now we seem to have to live with it

Related