2010-05-04 27 views
11

Nhiệm vụ của tôi là hiển thị các loại tài liệu được hỗ trợ trên iPhone có OS 3.x, chẳng hạn như .pdf, .rtf, .doc , .ppt, .png, .tiff, v.v.UIWebView iPhone: loadData không hoạt động với một số loại nhất định (Excel, MSWord, PPT, RTF)

Bây giờ, tôi đã lưu trữ các tệp này chỉ được mã hóa trên đĩa. Vì lý do bảo mật, tôi muốn tránh lưu trữ chúng không được mã hóa trên đĩa.

Do đó, tôi thích sử dụng loadData:MIMEType:textEncodingName:baseURL: thay vì loadRequest: để hiển thị tài liệu vì loadData cho phép tôi để vượt qua các nội dung trong một đối tượng NSData, tức là tôi có thể giải mã các tập tin trong bộ nhớ và không cần phải lưu trữ nó trên đĩa, như nó sẽ được yêu cầu khi sử dụng loadRequest.

Vấn đề là loadData không xuất hiện để làm việc với tất cả các loại tập tin:

kiểm tra cho thấy tất cả các loại hình ảnh có vẻ làm việc PDF tốt, cũng như, trong khi các loại phức tạp hơn thì không. Tôi gặp lỗi như:

NSURLErrorDomain Code=100 
NSURLErrorDomain Code=102 

WebView dường như cần URL thực sự hoạt động để truy cập tài liệu, mặc dù tôi đã cung cấp tất cả nội dung qua đối tượng NSData.

Dưới đây là đoạn code tôi sử dụng để hiển thị các nội dung:

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

Các mime-type được thiết lập đúng cách, ví dụ để "application/msword" cho các tệp .doc.

Có ai biết cách tôi có thể nhận được loadData để làm việc với tất cả các loại mà loadRequest hỗ trợ không? Hoặc, cách khác, có cách nào tôi có thể biết loại nào hoạt động cho chắc chắn (tức là bị xử phạt chính thức bởi Apple) với loadData? Sau đó, tôi có thể làm việc gấp đôi, tạo ra một tập tin tạm thời không mã hóa chỉ cho những trường hợp mà loadData sẽ không thích.

Cập nhật

Hình như tôi không phải là người đầu tiên chạy vào này. Xem ở đây:

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

Vì vậy, tôi đoán, đó là hiện trạng, và không có gì tôi có thể làm gì về nó.

Có người đề nghị một công việc xung quanh mà có thể làm việc, mặc dù:

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

Về cơ bản, ý tưởng là để cung cấp một máy chủ http nhỏ phục vụ các tập tin (từ bộ nhớ trong trường hợp của tôi), và sau đó sử dụng loadRequest. Mặc dù vậy, điều này có thể tốn nhiều bộ nhớ hơn vì cả máy chủ và webview có thể sẽ giữ toàn bộ nội dung trong bộ nhớ dưới dạng hai bản sao, ngược lại với việc sử dụng loadData, nơi cả hai sẽ chia sẻ cùng một đối tượng dữ liệu. (Tâm trí bạn, tôi sẽ phải giữ dữ liệu được giải mã trong bộ nhớ, đó là toàn bộ vấn đề ở đây).

+1

Tôi cũng trải qua oddities khi làm việc với các tệp không phải html trong 'UIWebView'. Tôi sợ nó có vẻ như 'UIWebView' trong số những thứ khác nhìn vào URL cho tập tin nó đang cố gắng để tải. Tải với một tập tin tạm thời không được mã hóa với một URL tập tin có thể là bạn chỉ "an toàn" cách ra (theo như tôi biết). – alleus

Trả lời

8

Tôi gặp phải sự cố tương tự (tôi nhận tệp từ máy chủ) và xem bài đăng của bạn và nghĩ rằng đó là một kết thúc chết và sau đó chỉ tình cờ bắt đầu thử nghiệm trên thiết bị (iPad, trong trường hợp này) và nó làm việc khi tôi đã cho baseURL như những gì tôi được sử dụng để có được nó từ máy chủ và nó đã làm việc nhưng không hoạt động trên giả lập. Tôi sẽ thử điều đó, nếu không tôi sẽ gửi một báo cáo lỗi cho Apple.

+1

Tôi vừa thử trên một thiết bị iPhone 4 và nó vẫn không hiển thị một tập tin kiểu "application/msword". Có lẽ tôi chỉ cần vượt qua các loại sai, tuy nhiên. Dữ liệu cụ thể + loại nào phù hợp với bạn? –

+3

Ah! Điều quan trọng là phải đặt một baseURL không phải là nil. Cùng với đó, nó thậm chí còn hoạt động với các tệp msword trong Trình mô phỏng, chạy iOS 4.0 hoặc 3.2, cũng như trên iPhone4 và iPad của tôi. Bây giờ tôi cần một thiết bị OS 3.0 để kiểm tra xem điều này cũng hoạt động ở đó ngay bây giờ. Thật không may, tôi đã nâng cấp iPod Touch lên 4.0 gần đây. Chuyển động ngu ngốc, nó bây giờ hóa ra. Trong mọi trường hợp, bạn vừa kiếm được điểm đầu tiên trên SO! Chào mừng :) –

+0

Hóa ra đây có lẽ là một "tính năng" mới, hay đúng hơn là bugfix, được giới thiệu trong iOS 3.2. Vì vậy, nếu bạn đang hỗ trợ iOS 3.1.3 trở xuống, bạn vẫn cần phải đặc biệt phân biệt các loại và viết một tệp tạm thời cho các loại tệp phức tạp được đề cập ở trên. –

0

Đây là giải pháp thông qua 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() { 
    } 
} 

Bây giờ bạn chỉ cần đăng ký lớp:

NSURLProtocol.registerClass(CoreDataFileURLProtocol.self) 

Và tạo một yêu cầu với file_id:

let url = NSURL(scheme: "coredatafile", host: "myapp.com", path: "/\(file.file_id)") 
webView.loadRequest(NSURLRequest(URL: url!)) 
Các vấn đề liên quan