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

标签 ios swift swiftui arkit swift-package-manager

我听说 Xcode 12(现在是 Beta 6),Swift 包管理器现在能够包含资源。但我无法打开现实(.rcproject)文件。
这是我尝试过的; (你可以复制)

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

  • 完成这些步骤后,我希望有一个包含 AR 的 swift 包管理器。
    但自动生成 Experience枚举抛出 .fileNotFound("Experience.reality")错误。
    好像还是没能在 Bundle 中找到真人文件?
    你有没有尝试过类似的东西。等待任何帮助。谢谢..

    Folder StructurePackage.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"]),
        ]
    )
    
    
    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) {}
        
    }
    
    
    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")
            }
    
        }
    
    }
    
    
    而在 ContentView文件,我简单展示EKARView .

    最佳答案

    Xcode 知道如何处理 .rcproject文件放入 .reality构建应用程序时需要的文件。不幸的是,在使用 Swift 包访问项目文件时没有完成此处理。
    您概述的步骤几乎可以奏效。归根结底是使用已经编译好的 .reality文件代替 .rcproject文件。为了改造默认.rcproject文件,您需要使用 Apple 的 现实 Composer 应用。
    使用 Xcode 12 概述的步骤...

  • Experience.rcproject选择文件,单击“在 Reality Composer 中打开”按钮。
  • 打开后,通过"file"菜单导出项目。
  • 选择“项目”并单击“导出”。这会产生一个 Experience.reality文件。
  • 将该文件放在您的 swift 包资源中。
  • 确保更换 Bundle您的 Experience.swift 中的引用文件与 Bundle.module ,因为现有引用将针对您的应用程序包。
  • 关于ios - 如何在 Swift 包管理器中添加 Reality 文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63776624/

    相关文章:

    ios - 在 ForEach 循环 SwiftUI 中使用索引获取索引

    ios - SwiftUI导航栏标题

    ios - 使用自定义 Cordova 插件将原生 iOS 事件绑定(bind)到 webView

    ios - 我的 xcode 在源代码管理中显示同时打开两个分支

    swift - 快速过滤 CD 关系

    ios - 在我设置内容大小并测试它改变后,Scrollview 不滚动

    ios - 如何混入 Objective-C 方法的完成 block ?

    ios - 在自定义类下拉 Xcode 8.3.2 中找不到自定义 Controller 类

    ios - 如何从 iOS 自动填充密码中保存/检索密码?

    SwiftUI - 半模态?