我尝试使用此代码将远程图像加载到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.
如果我将网址复制粘贴到浏览器中,图片会毫无问题地展示(另外我在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 documentation没有提及任何有关外部网址的内容,但它是否只能处理内部资源?
答案 0 :(得分:3)
以下是如何扩展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()
}
}
理想情况下,您应该实现自己的缓存机制,以避免重复下载相同的图像,但这应该可以帮助您入门。