0

这是我第一次尝试将 AR 预览添加到应用程序中(也是我第一次使用文件系统)。我一直在尝试实施类似于此处解释的解决方案https://developer.apple.com/forums/thread/126377但是一个关键区别是我的 usdz 模型不在我的主包中,因为它是从生成和下载的运行时的外部源。我想知道是否可以显示存储在应用程序文档或缓存目录中的文件以及它是如何完成的。

该文件被下载并存储在缓存目录中,如下所示:

class ModelFetcher: NSObject{
    var modelUrl: URL?
    
    func generateModel() {
        guard let url = URL(string: "http://127.0.0.1:5000/model.usdz") else {return}
        let urlSession = URLSession(configuration: .default, delegate: self, delegateQueue: OperationQueue())
        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        let downloadTask = urlSession.downloadTask(with: request)
        downloadTask.resume()
    }
}

extension ModelFetcher: URLSessionDownloadDelegate {
    func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
        print("File Downloaded Location- ", location)
        
        guard let url = downloadTask.originalRequest?.url else {
            return
        }
        let docsPath = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask)[0]
        let destinationPath = docsPath.appendingPathComponent(url.lastPathComponent)
        
        try? FileManager.default.removeItem(at: destinationPath)
        
        do {
            try FileManager.default.copyItem(at: location, to: destinationPath)
            self.modelUrl = destinationPath
            print("File moved to: \(modelUrl!.absoluteURL)")
        } catch let error {
            print("Copy Error: \(error.localizedDescription)")
        }
    }
}

然后我尝试使用 ARQuicklookPreview 显示模型,如下所示:

import SwiftUI
import QuickLook
import ARKit

struct ARQuickLookView: UIViewControllerRepresentable {
    var allowScaling: Bool = true
    
    func makeCoordinator() -> ARQuickLookView.Coordinator {
        Coordinator(self)
    }
    
    func makeUIViewController(context: Context) -> QLPreviewController {
        let controller = QLPreviewController()
        controller.dataSource = context.coordinator
        return controller
    }
    
    func updateUIViewController(_ controller: QLPreviewController,
                                context: Context) {
        // nothing to do here
    }
    
    class Coordinator: NSObject, QLPreviewControllerDataSource {
        let parent: ARQuickLookView
        let destinationPath = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask)[0].appendingPathComponent("model.usdz")
        private lazy var fileURL: URL = destinationPath
        
        init(_ parent: ARQuickLookView) {
            self.parent = parent
            super.init()
        }
        
        func numberOfPreviewItems(in controller: QLPreviewController) -> Int {
            return 1
        }
        func previewController(
            _ controller: QLPreviewController,
            previewItemAt index: Int
        ) -> QLPreviewItem {
            let fileURL = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask)[0].appendingPathComponent("model.usdz")
            print(fileURL)
            let item = ARQuickLookPreviewItem(fileAt: fileURL)
            print(item)
            item.allowsContentScaling = parent.allowScaling
            return item
        }
    }
}

struct ARQuickLookView_Previews: PreviewProvider {
    static var previews: some View {
        ARQuickLookView()
    }
}

但是,我在控制台中收到错误“Unhandled item type 13: contentType is: (null) #PreviewItem”,在 UI 中它读取不支持的文件类型,我已执行测试以确保文件位于 URL 的位置我什至可以在我的 Mac 上预览打开它,所以它不像文件格式或位置是错误的。

从主包以外的位置显示模型的任何帮助都会有所帮助,或者可能是首先移动文件然后显示它的解决方法。

编辑:将预览控制器功能更改为

let fileURL = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask)[0].appendingPathComponent("model.usdz")
return fileUrl as QLPreviewItem

现在在 UI 中它只是说“模型通用场景描述包”

在控制台中,我仍然收到错误消息,但现在显示为:未处理的项目类型 13:contentType 是:com.pixar.universal-scene-description-mobile #PreviewItem

这没有意义,因为它是它支持的唯一类型之一

谢谢,

路易斯

4

0 回答 0