使用MTKTextureLoader加载远程图像

我试图用这个代码加载一个远程图像到一个MTLTexture,

let textureLoader = MTKTextureLoader(device: device) textureLoader.newTexture(withContentsOf: url, options: options) { [weak self] (texture, error) in if let t = texture { completion(t) } else { if let desc = error?.localizedDescription { NSLog(desc) } completion(nil) } } 

如果URL来自Bundle资源,那么它就起作用,例如

 let url = Bundle.main.url(forResource: name, withExtension: ext) 

但是,如果我通过这样的事情,它会失败,

 let url = URL(string: "http://example.com/images/bla_bla.jpg") 

有了这个错误,

 Could not find resource bla_bla.jpg at specified location. 

如果我复制粘贴到浏览器的URL,图像显示没有问题(加上我已经在Android中使用OpenGL实现相同的东西,图像渲染确定)。

我已经将我的域添加到Info.plist中,并且可以从该位置加载Json之类的东西。 这只是纹理加载器很有趣… Info.plist看起来像这样,

 <key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <false/> <key>NSExceptionDomains</key> <dict> <key>example.com</key> <dict> <key>NSIncludesSubdomains</key> <true/> <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key> <true/> <key>NSTemporaryExceptionMinimumTLSVersion</key> <string>TLSv1.1</string> </dict> </dict> </dict> 

MTKTextureLoader文档没有提及任何有关外部URL的内容,但它可能只是处理内部资源?

以下是如何扩展MTKTextureLoader以加载远程URL的示例,默认实现不支持此URL。

 extension MTKTextureLoader { enum RemoteTextureLoaderError: Error { case noCachesDirectory case downloadFailed(URLResponse?) } func newTexture(withContentsOfRemote url: URL, options: [String : NSObject]? = nil, completionHandler: @escaping MTKTextureLoaderCallback) { let downloadTask = URLSession.shared.downloadTask(with: URLRequest(url: url)) { (maybeFileURL, maybeResponse, maybeError) in var anError: Error? = maybeError if let tempURL = maybeFileURL, let response = maybeResponse { if let cachePath = NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true).first { let cachesURL = URL(fileURLWithPath: cachePath, isDirectory: true) let cachedFileURL = cachesURL.appendingPathComponent(response.suggestedFilename ?? NSUUID().uuidString) try? FileManager.default.moveItem(at: tempURL, to: cachedFileURL) return self.newTexture(withContentsOf: cachedFileURL, options: options, completionHandler: completionHandler) } else { anError = RemoteTextureLoaderError.noCachesDirectory } } else { anError = RemoteTextureLoaderError.downloadFailed(maybeResponse) } completionHandler(nil, anError) } downloadTask.resume() } } 

理想情况下,你会实现自己的caching机制,以避免重复下载相同的图像,但这应该让你开始。