【问题标题】:Get download progress from SCNScene url从 SCNScene url 获取下载进度
【发布时间】:2018-10-05 16:33:27
【问题描述】:

我正在使用 ARKit,我无法从 SCNScene 网址获取下载进度。这是我的代码:

func downloadModel(hitTestResult: ARHitTestResult) {
    DispatchQueue.global().async {
        // create loading view
        // I WANT TO GET DOWNLOAD PROGRESS HERE
        let loading = UIAlertController(title: nil, message: "Please wait...\(downloadProgressValueHere)%", preferredStyle: .alert)

        let loadingIndicator = UIActivityIndicatorView(frame: CGRect(x: 10, y: 5, width: 50, height: 50))
        loadingIndicator.hidesWhenStopped = true
        loadingIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.gray
        loadingIndicator.startAnimating();

        loading.view.addSubview(loadingIndicator)
        self.present(loading, animated: true, completion: nil)

        // download 3d model from server
        let myURL = URL(string: "http://www.mydownloadlink.com")
        let scene = try! SCNScene(url: myURL!, options: nil)
        let node = (scene.rootNode.childNode(withName: "parentNode", recursively: true))!
        self.sceneView.scene.rootNode.addChildNode(node)

        // dismiss loading view
        loading.dismiss(animated: true, completion: nil)
    }
}

如何获取“请稍候...”消息的下载进度?谢谢大家。

【问题讨论】:

    标签: ios swift scenekit arkit


    【解决方案1】:

    我的理解是,虽然下面的方法看起来会使用远程 URL,但实际上并没有(尽管我可能是错的):

    convenience init(url: URL, 
             options: [SCNSceneSource.LoadingOption : Any]? = nil) throws
    

    无论如何,在这里回答你的问题是你的一个例子(这可能有点 OTT,但希望它也能帮助其他人)。

    假设我们有一个SCNScene 文件,位于以下URL

    http://stackOverflow.com/stackOverFlow.scn
    

    首先我们需要为我们的ProgressInfo 创建变量,如下所示:

     var loading: UIAlertController!
     var loadingIndicator: UIActivityIndicatorView!
     var downloadString: String = "Downloading"
    

    然后我们要做的是创建一个 URLSession 来下载文件,如下所示:

     /// Downloads An SCNFile From A Remote URL
     func downloadSceneTask(){
    
            //1. Get The URL Of The SCN File
            guard let url = URL(string: "http://stackOverflow.com/stackOverFlow.scn") else { return }
    
            //2. Create The Download Session
            let downloadSession = URLSession(configuration: URLSession.shared.configuration, delegate: self, delegateQueue: nil)
    
            //3. Create The Download Task & Run It
            let downloadTask = downloadSession.downloadTask(with: url)
            downloadTask.resume()
    
            //4. Show The Progress Alert
            DispatchQueue.main.async {
    
               self.loading = UIAlertController(title: nil, message: self.downloadString , preferredStyle: .alert)
    
               let loadingIndicator = UIActivityIndicatorView(frame: CGRect(x: 10, y: 5, width: 50, height: 50))
               loadingIndicator.hidesWhenStopped = true
               loadingIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.gray
               loadingIndicator.startAnimating();
    
               self.loading.view.addSubview(loadingIndicator)
               self.present(self.loading, animated: true, completion: nil)
        }
    
     }
    

    请注意,我创建了一个 variable 导致 downloadString,我们稍后会更改它。

    然后我们将参考以下 URLSession 委托,例如:

    class ViewController: UIViewController, URLSessionDelegate, URLSessionDownloadDelegate {
    
    }
    

    对于我们的示例,它将调用以下函数:

    第一个跟踪我们的下载进度,您可以在其中处理诸如在HUD 中显示进度或使用progressIndicator 之类的事情:

    func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask,
                        didWriteData bytesWritten: Int64,
                        totalBytesWritten: Int64,
                        totalBytesExpectedToWrite: Int64) {
    
            print("Downloaded \(totalBytesWritten) / Of \(totalBytesExpectedToWrite) Bytes")
    
            DispatchQueue.main.async {
               self.loading.message = "Downloaded \(totalBytesWritten) / Of \(totalBytesExpectedToWrite) Bytes"
        }
    
    }
    

    文件下载后的第二个处理:

    func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
    
    //1. Remove The Loading View
        loading.dismiss(animated: true, completion: nil)
    
    //2. Create The Filename
    let fileURL = getDocumentsDirectory().appendingPathComponent("stackOverFlow.scn")
    
    //3. Copy It To The Documents Directory
    do {
        try FileManager.default.copyItem(at: location, to: fileURL)
    
        print("Successfuly Saved File \(fileURL)")
    
        //4. Load The Model
        loadModel()
    
    } catch {
    
        print("Error Saving: \(error)")
     }
    }
    

    请注意,在此方法中,我使用以下函数来检索下载的文件并将其复制到documents directory

    /// Returns The Documents Directory
    ///
    /// - Returns: URL
    func getDocumentsDirectory() -> URL {
    
    let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
    let documentsDirectory = paths[0]
    return documentsDirectory
    
    }
    

    一旦文件被下载并复制到我们(4)调用我们的loadModel function,如下所示:

    /// Loads The SCNFile From The Documents Directory
    func loadModel(){
    
        //1. Get The Path Of The Downloaded File
        let downloadedScenePath = getDocumentsDirectory().appendingPathComponent("stackOverFlow.scn")
    
        do {
    
            //2. Load The Scene Remembering The Init Takes ONLY A Local URL
            let modelScene =  try SCNScene(url: downloadedScenePath, options: nil)
    
            //3. Create A Node To Hold All The Content
            let modelHolderNode = SCNNode()
    
            //4. Get All The Nodes From The SCNFile
            let nodeArray = modelScene.rootNode.childNodes
    
            //5. Add Them To The Holder Node
            for childNode in nodeArray {
                modelHolderNode.addChildNode(childNode as SCNNode)
            }
    
            //6. Set The Position
            modelHolderNode.position = SCNVector3(0, 0, -1.5)
    
            //7. Add It To The Scene
            self.augmentedRealityView?.scene.rootNode.addChildNode(modelHolderNode)
    
    
        } catch  {
            print("Error Loading Scene")
        }
    
    }
    

    请注意,这是一个非常粗略的示例,不包括检查文件是否存在、缩放等内容,但它应该足以帮助您实现所需的内容...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-04-11
      • 2021-11-09
      • 1970-01-01
      • 2013-04-21
      • 1970-01-01
      • 2023-04-02
      • 2020-07-27
      • 1970-01-01
      相关资源
      最近更新 更多