IPhone UIWebView: loadData не работает с определенными типами (Excel, MSWord, PPT, RTF)
Моя задача - отобразить поддерживаемые типы документов на iPhone с ОС 3.x, такие как .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 правильно установлен, например. к "application/msword" для .doc файлов.
Кто-нибудь знает, как я мог бы loadData
работать со всеми типами, которые поддерживает loadRequest? Или, альтернативно, есть ли какой-то способ, я могу сказать, какие типы действительно работают (то есть официально санкционировано Apple) с loadData? Тогда я могу работать в два раза, создавая временный незашифрованный файл только для тех случаев, которые loadData не понравится.
Обновление
Похоже, я не первый, кто работает в этом. См. Здесь:
http://osdir.com/ml/iPhoneSDKDevelopment/2010-03/msg00216.html
Итак, я думаю, что статус-кво, и я ничего не могу с этим поделать.
Кто-то предложил работу, которая может работать, хотя:
http://osdir.com/ml/iPhoneSDKDevelopment/2010-03/msg00219.html
В принципе, идея состоит в том, чтобы предоставить крошечный http-сервер, который обслуживает файл (из памяти в моем случае), а затем использовать loadRequest. Это, вероятно, немного более интенсивно для памяти, хотя, как и сервер, так и веб-просмотр, вероятно, будут содержать все содержимое в памяти в виде двух копий тогда, в отличие от использования loadData, где оба будут иметь общий доступ к одному и тому же объекту данных. (Имейте в виду, мне придется хранить дешифрованные данные в памяти, что весь смысл здесь).
Ответы
Ответ 1
У меня возникла очень похожая проблема (я получил свои файлы с сервера) и увидел ваш пост и подумал, что это тупик, а затем просто случайно начал экспериментировать на устройстве (iPad в этом случае), и он работал, когда я дал baseURL как то, что я использовал для его получения с сервера, и он работал, но не работает на симуляторе. Я бы попробовал это, иначе я бы представил отчет об ошибке Apple.
Ответ 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!))