如何在 Swift 包管理器中添加 Reality 文件?

Ene*_*man 5 ios swift swift-package-manager arkit swiftui

我听说 Xcode 12(现在是 Beta 6),Swift 包管理器现在能够包含资源。但我无法打开现实(.rcproject)文件。

这是我尝试过的;(你可以复制)

  1. 我创建了一个新Augmented Reality App项目。(RealityKit + SwiftUI + Swift)
  2. 现在,如果您尝试运行该项目,一切正常,您会看到一个默认的金属框。
  3. 现在我创建了一个新的SPM(Swift 包管理器)
  4. 现在我将本地创建的拖到SPM项目中,并将其添加到“常规”>“目标”选项卡中的框架中。(通知项目有关本地添加的 spm)
  5. 我将Experience.rcproject& ContentView(也复制了自动生成的Experience枚举,您可以通过 Cmd+Click 访问它)到SPM
  6. 修复了一些访问初始化程序问题,ContentViewplatforms: [.iOS(.v13)],SPM
  7. resources在存在SPM的路径中添加Experience.rcproject

完成这些步骤后,我希望有一个包含 AR 的 swift 包管理器。
但是自动生成的Experience枚举会引发.fileNotFound("Experience.reality")错误。
好像还是没能在 Bundle 中找到真人档案?

你有没有尝试过类似的东西。等待任何帮助。谢谢..


文件夹结构

Package.swift

// swift-tools-version:5.3
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
    name: "ARSPM",
    platforms: [.iOS(.v13)],
    products: [
        .library(
            name: "ARSPM",
            targets: ["ARSPM"]),
    ],
    dependencies: [],
    targets: [
        .target(
            name: "ARSPM",
            dependencies: [], resources: [
                .copy("Resources")
            ]),
        .testTarget(
            name: "ARSPMTests",
            dependencies: ["ARSPM"]),
    ]
)

Run Code Online (Sandbox Code Playgroud)

ARView.swift

import SwiftUI
import RealityKit

public struct EKARView : View {
    public init() { }
    public var body: some View {
        return ARViewContainer().edgesIgnoringSafeArea(.all)
    }
}

public struct ARViewContainer: UIViewRepresentable {
    
    public func makeUIView(context: Context) -> ARView {
        
        let arView = ARView(frame: .zero)
        
        // Load the "Box" scene from the "Experience" Reality File
        let boxAnchor = try! Experience.loadBox()
        
        // Add the box anchor to the scene
        arView.scene.anchors.append(boxAnchor)
        
        return arView
        
    }
    
    public func updateUIView(_ uiView: ARView, context: Context) {}
    
}

Run Code Online (Sandbox Code Playgroud)

GeneratedExperienceFile.swift

//
// Experience.swift
// GENERATED CONTENT. DO NOT EDIT.
//

import Foundation
import RealityKit
import simd
import Combine

internal enum Experience {

    public enum LoadRealityFileError: Error {
        case fileNotFound(String)
    }

    private static var streams = [Combine.AnyCancellable]()

    public static func loadBox() throws -> Experience.Box {
        guard let realityFileURL =
//                Also tried >> Foundation.Bundle.module
                Foundation.Bundle(for: Experience.Box.self)
                    .url(forResource: "Experience", withExtension: "reality") else {
            throw Experience.LoadRealityFileError.fileNotFound("Experience.reality")
        }

        let realityFileSceneURL = realityFileURL.appendingPathComponent("Box", isDirectory: false)
        let anchorEntity = try Experience.Box.loadAnchor(contentsOf: realityFileSceneURL)
        return createBox(from: anchorEntity)
    }

    public static func loadBoxAsync(completion: @escaping (Swift.Result<Experience.Box, Swift.Error>) -> Void) {
        guard let realityFileURL = Foundation.Bundle(for: Experience.Box.self).url(forResource: "Experience", withExtension: "reality") else {
            completion(.failure(Experience.LoadRealityFileError.fileNotFound("Experience.reality")))
            return
        }

        var cancellable: Combine.AnyCancellable?
        let realityFileSceneURL = realityFileURL.appendingPathComponent("Box", isDirectory: false)
        let loadRequest = Experience.Box.loadAnchorAsync(contentsOf: realityFileSceneURL)
        cancellable = loadRequest.sink(receiveCompletion: { loadCompletion in
            if case let .failure(error) = loadCompletion {
                completion(.failure(error))
            }
            streams.removeAll { $0 === cancellable }
        }, receiveValue: { entity in
            completion(.success(Experience.createBox(from: entity)))
        })
        cancellable?.store(in: &streams)
    }

    private static func createBox(from anchorEntity: RealityKit.AnchorEntity) -> Experience.Box {
        let box = Experience.Box()
        box.anchoring = anchorEntity.anchoring
        box.addChild(anchorEntity)
        return box
    }

    public class Box: RealityKit.Entity, RealityKit.HasAnchoring {

        public var steelBox: RealityKit.Entity? {
            return self.findEntity(named: "Steel Box")
        }

    }

}

Run Code Online (Sandbox Code Playgroud)

ContentView文件中,我简单地显示EKARView.

ric*_*zza 3

Xcode 知道如何将.rcproject文件处理成.reality构建应用程序时所需的文件。不幸的是,当使用 Swift 包访问项目文件时,不会完成此处理。

您概述的步骤几乎可以工作。归根结底就是使用已经编译的.reality文件来代替该.rcproject文件。为了转换默认.rcproject文件,您需要使用 Apple 的Reality Composer应用程序。

使用 Xcode 12 概述的步骤...

  • 选择文件后Experience.rcproject,单击“在 Reality Composer 中打开”按钮。
  • 打开后,通过“文件”菜单导出项目。
  • 选择“项目”并单击导出。这会生成一个Experience.reality文件。
  • 将该文件放入您的 swift 包资源中。
  • 确保将文件Bundle中的引用替换Experience.swiftBundle.module,因为现有引用将针对您的应用程序包。