【问题标题】:iPhone UIWebView: loadData does not work with certain types (Excel, MSWord, PPT, RTF)iPhone UIWebView:loadData 不适用于某些类型(Excel、MSWord、PPT、RTF)
【发布时间】:2011-02-15 10:07:04
【问题描述】:

我的任务是在装有 OS 3.x 的 iPhone 上显示支持的文档类型,例如 .pdf、.rtf、.doc、.ppt、.png、.tiff 等。

现在,我已将这些文件仅加密存储在磁盘上。出于安全原因,我想避免将它们未加密地存储在磁盘上。

因此,我更喜欢使用loadData:MIMEType:textEncodingName:baseURL: 而不是loadRequest: 来显示文档,因为loadData 允许我在NSData 对象中传递内容,即我可以在内存中解密文件而无需存储它在磁盘上,因为在使用 loadRequest 时需要它。

问题在于loadData 似乎不适用于所有文件类型:

测试表明,所有图片类型似乎都可以正常工作,PDF 也是如此,而更复杂的类型则不然。我收到如下错误:

NSURLErrorDomain Code=100
NSURLErrorDomain Code=102

WebView 似乎需要一个真正有效的 URL 才能将文档作为文件访问,尽管我已经通过 NSData 对象提供了所有内容。

这是我用来显示内容的代码:

[webView loadData:data MIMEType:type textEncodingName:@"utf-8" baseURL:nil];

mime-type 设置正确,例如.doc 文件的“应用程序/msword”。

有谁知道我如何让loadData 与 loadRequest 支持的所有类型一起工作?或者,有什么方法可以告诉我哪些类型确实可以使用 loadData(即 Apple 正式批准)?然后我可以双重工作,只为那些 loadData 不喜欢的情况创建一个临时未加密文件。

更新

看起来我不是第一个遇到这种情况的人。见这里:

http://osdir.com/ml/iPhoneSDKDevelopment/2010-03/msg00216.html

所以,我想,这就是现状,我对此无能为力。

有人提出了一种可能可行的解决方法:

http://osdir.com/ml/iPhoneSDKDevelopment/2010-03/msg00219.html

基本上,这个想法是提供一个小型 http 服务器来服务文件(在我的例子中是从内存中),然后使用 loadRequest。但是,这可能会占用更多内存,因为服务器和 webview 可能都将整个内容作为两个副本保存在内存中,而不是使用 loadData,两者都宁愿共享相同的数据对象。 (请注意,我必须将解密的数据保存在内存中,这就是重点)。

【问题讨论】:

  • UIWebView 中处理非 html 文件时,我也遇到了一些奇怪的事情。恐怕UIWebView 似乎会查看它试图加载的文件的 URL。加载带有文件 URL 的临时未加密文件可能是您唯一的“安全”出路(据我所知)。

标签: iphone uiwebview webkit


【解决方案1】:

我遇到了一个非常相似的问题(但是我从服务器获取我的文件)并且看到了你的帖子并认为这是一个死胡同,然后偶然开始在设备上进行实验(在这种情况下是 iPad)并且它当我将baseURL作为我用来从服务器获取它的内容时工作,它工作但在模拟器上不起作用。我会尝试这样做,否则我会向 Apple 提交错误报告。

【讨论】:

  • 我刚刚在 iPhone 4 设备上尝试过,但仍然无法显示“application/msword”类型的文件。但是,也许我只是传递了错误的类型。什么特定的数据 + 类型适合您?
  • 啊!设置一个非零的 baseURL 很重要。有了它,它现在甚至可以在模拟器中处理 msword 文件,运行 iOS 4.0 或 3.2,以及在我的 iPhone4 和 iPad 上。现在我需要一个 OS 3.0 设备来检查它现在是否也可以在那里工作。不幸的是,我最近将我的 iPod Touch 升级到了 4.0。愚蠢的举动,现在证明。无论如何,您刚刚在 SO 上获得了第一分!欢迎:)
  • 原来这可能是 iOS 3.2 中引入的一个新“功能”,或者更确切地说是错误修复。因此,如果您支持 iOS 3.1.3 或更低版本,您仍然需要对类型进行特殊处理并为上述复杂文件类型编写临时文件。
  • 对我从来没有检查过 3.1.3 或更低版本是否有效,因为我一直只使用 loadRequest: 并且从不需要 loadData:(我使用 ASIHTTPRequest 在 iPad 上下载)。并将触摸升级到 4.0-ouch。幸运的是,我的工作场所有人安装了各种操作系统(我们的老板还在摇摆 2.2.1!)
  • 感谢您提醒我不要发送 nil baseURL: @ThomasTempelmann - 即使只是发送 [NSURL urlWithString: @"http://" 也解决了我自己的 UIWebView 方法调用问题。
【解决方案2】:

这是NSURLProtocol的解决方案:

class CoreDataFileURLProtocol : NSURLProtocol {
    var connection: NSURLConnection!

    override class func canInitWithRequest(request: NSURLRequest) -> Bool {
        return (request.URL.scheme == "coredatafile")
    }

    override class func canonicalRequestForRequest(request: NSURLRequest) -> NSURLRequest {
        return request
    }

    override func startLoading() {
        if let file_id = self.request.URL.absoluteString?.lastPathComponent {
            if let file = SAFile.MR_findFirstByAttribute("file_id", withValue: file_id) as? SAFile {
                let response = NSURLResponse(URL: request.URL, MIMEType: file.mime, expectedContentLength: Int(file.filesize), textEncodingName: "utf-8")
                client?.URLProtocol(self, didReceiveResponse: response, cacheStoragePolicy: .NotAllowed)
                client?.URLProtocol(self, didLoadData: file.data)
                client?.URLProtocolDidFinishLoading(self)
            }
        }
    }

    override func stopLoading() {
    }
}

现在你只需要注册类:

NSURLProtocol.registerClass(CoreDataFileURLProtocol.self)

并使用file_id 创建一个请求:

let url = NSURL(scheme: "coredatafile", host: "myapp.com", path: "/\(file.file_id)")
webView.loadRequest(NSURLRequest(URL: url!))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-12-31
    • 1970-01-01
    • 2021-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多