使用MTKTextureLoader加载远程图像 [英] Load a remote image using MTKTextureLoader

查看:211
本文介绍了使用MTKTextureLoader加载远程图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用此代码将远程图像加载到MTLTexture中,

I'm trying to load a remote image into a MTLTexture with this code,

    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资源,则可以正常工作,例如

If the URL comes from a Bundle resource, then it works, e.g.

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

但是,如果我通过这样的操作,它将失败,

However, it fails if I pass something like this,

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

出现此错误

Could not find resource bla_bla.jpg at specified location.

如果我将网址复制粘贴到浏览器中,则显示的图像没有问题(此外,我已经在Android中使用OpenGL实现了相同的操作,并且图像呈现正常).

If I copy-paste the url into the browser, the image is displayed without problems (plus I've implemented the same thing in Android using OpenGL and the image renders OK).

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

I've added my domain to the Info.plist, and I can load things like Json from that location. It's just the texture loader being funny... Info.plist looks like this,

<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,但是它可能仅处理内部资源吗?

The MTKTextureLoader documentation does not mention anything about external URLs, but could it be that it only handles internal resources?

推荐答案

下面是一个示例,该示例如何扩展MTKTextureLoader来加载默认实现不支持的远程URL.

Here's an example of how to extend MTKTextureLoader to load remote URLs, which are not supported by the default implementation.

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()
    }
}

理想情况下,您将实现自己的缓存机制,以避免重复下载同一图像,但这应该可以帮助您入门.

Ideally, you would implement your own caching mechanism to avoid repeatedly downloading the same image, but this should get you started.

这篇关于使用MTKTextureLoader加载远程图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆