为 MTKTextureLoader 使用远程图像

Use a remote image for MTKTextureLoader

我正在尝试使用以下代码从 url 加载我的纹理:

let textureLoader = MTKTextureLoader(device: device)
var texture: MTLTexture?
let origin = NSString(string: MTKTextureLoader.Origin.bottomLeft.rawValue)
let textureLoaderOptions = [MTKTextureLoader.Option.SRGB: 0, MTKTextureLoader.Option.origin: origin] as [MTKTextureLoader.Option: Any]

do {
   texture = try textureLoader.newTexture(URL: my-url-here, options: textureLoaderOptions)
} catch {
   print("texture not created")
}

当我从应用程序中加载纹理时它工作正常,但我似乎无法使用外部 url 让它工作。有人对此有任何好运吗?

我试过 但无法让它按原样工作,而且我的知识还不够了解如何更新它。

这是 MTKTextureLoader 的扩展(与 Swift 5 兼容),它从远程 URL 下载图像并从中创建金属纹理。它遵循与 existing asynchronous loading API.

基本相同的模式
extension MTKTextureLoader {
    static let errorDomain = "com.example.MTKTextureLoader.RemoteExtensions"

    func newTexture(remoteURL url: URL, options: [MTKTextureLoader.Option : Any]? = nil, completionHandler: @escaping MTKTextureLoader.Callback) {
        let downloadTask = URLSession.shared.downloadTask(with: URLRequest(url: url)) { (maybeFileURL, maybeResponse, maybeError) in
            var anError: Swift.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(URL: cachedFileURL, options: options, completionHandler: completionHandler)
                } else {
                    anError = NSError(domain: MTKTextureLoader.errorDomain,
                                      code: 1,
                                      userInfo: [NSLocalizedDescriptionKey : "Unable to find user caches directory"])
                }
            } else {
                anError = NSError(domain: MTKTextureLoader.errorDomain,
                                  code: 2,
                                  userInfo: [NSLocalizedDescriptionKey : "Download from URL failed"])
            }
            completionHandler(nil, anError)
        }
        downloadTask.resume()
    }
}

请注意,如果您的应用是沙盒应用,您应该在您的授权中启用 "Outgoing Connections"(如果您尚未启用)。

此外,混合下载、缓存和纹理加载等问题并不是最佳做法,因此如果您要加载大量远程文件,我建议将其重构为更通用的远程资源缓存系统。这仅用于演示目的。