Насколько я понимаю, хотя следующий метод в действительности использует удаленный 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 {
}
, которые для нашего примера вызовутследующие функции:
1-й для отслеживания прогресса нашей загрузки, в котором вы можете обрабатывать такие вещи, как отображение прогресса в 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"
}
}
2-й для обработки, когда файл загружен:
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")
}
}
Обратите внимание, что это очень грубый пример, и он не охватывает такие вещи, как проверка существования файла, масштабирование и т. д.,но этого должно быть достаточно, чтобы помочь вам достичь того, что вы ищете ...