2013-04-27 26 views
5

UIWebView không tự động hỗ trợ xử lý các tệp .pkpass Passbook.UIWebView Delegate nhận được MIME Type

Trong này technical note, Apple khuyên bạn nên triển khai kiểm tra thông qua các phương thức UIWebViewDelegate để loại bỏ loại MIME và xử lý theo đó.

Để thêm đèo sử dụng một UIWebView, thực hiện các phương pháp UIWebViewDelegate thích hợp để xác định khi xem tải dữ liệu với một loại MIME của application/vnd.apple.pkpass

Tuy nhiên, tôi không thể tìm thấy bất kỳ thứ gì trong số UIWebView Delegate Protocol Reference có khả năng cung cấp loại MIME.

Tôi có thể tải xuống và xử lý thành công tệp trực tiếp bằng cách sử dụng đại diện NSURLConnection mà không có vấn đề gì, nhưng những gì tôi muốn đạt được là để được xử lý đúng cách nếu người dùng nhấp vào nút Thêm vào sổ tiết kiệm trong khi duyệt trong UIWebView. Vì tôi không biết liên kết và nhiều nhà cung cấp không liên kết các liên kết của họ với phần mở rộng .pkpass, theo lời khuyên của Apple về kiểm tra loại MIME có vẻ là cách tốt nhất để đi.

Tôi đã thử thêm sau

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)newRequest 
               navigationType:(UIWebViewNavigationType)navigationType 
{ 

    NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:[newRequest URL]]; 

    // Spoof iOS Safari headers for sites that sniff the User Agent 
    [req addValue:@"Mozilla/5.0 (iPhone; CPU iPhone OS 6_1 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5376e Safari/8536.25" forHTTPHeaderField:@"User-Agent"]; 

    NSURLConnection *conn = [NSURLConnection connectionWithRequest:newRequest delegate:self]; 

    return YES; 
} 

NSURLConnection đại biểu của tôi:

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response 
{ 
    NSString *mime = [response MIMEType]; 

    if ([mime isEqualToString:@"application/vnd.apple.pkpass"] && ![_data length]) { 

     _data = nil; // clear any old data 
     _data = [[NSMutableData alloc] init]; 

     [_webPanel stopLoading]; 
    } 
} 

-(void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data 
{ 
    [_data appendData:data]; 
    NSLog(@"Size: %d", [_data length]); 
} 

-(void)connectionDidFinishLoading:(NSURLConnection*)connection 
{ 

    if ([_data length]) { 

     PKAddPassesViewController *pkvc = [PassKitAPI presentPKPassFileFromData:_data]; 
     pkvc.delegate = self; 
     [self presentViewController:pkvc 
          animated:YES 
         completion:nil]; 
    } 
} 

Các NSURLConnection đại biểu làm việc tốt khi một kết nối được gọi trực tiếp, mà không có sự UIWebView. Tuy nhiên, khi tôi thử khởi chạy một số NSURLConnection từ số UIWebView ủy quyền tải xuống không thành công vì chỉ 80% hoặc hơn .pkpass đang được tải xuống (tôi nhận được sự không khớp ngẫu nhiên của byte trong biến _data và tiêu đề Nội dung Độ dài).

Vì vậy, câu hỏi của tôi:

  1. Có một cách dễ dàng hơn để có được giữ của một loại MIME, trực tiếp từ UIWebView phương pháp đại biểu?
  2. Nếu không, thì tôi có đi đúng hướng với việc mở một NSURLConnection song song hay là có cách nào tốt hơn?
  3. Nếu một NSURLConnection là con đường để đi, thì điều gì có thể khiến nó ngừng tải xuống toàn bộ tệp?
+0

Bạn đã tìm thấy một giải pháp cho việc này? Nếu có, bạn có thể chia sẻ nó không? –

+0

Không - Tôi đã thảo luận với các kỹ sư của Apple tại WWDC và họ nói với tôi rằng không có giải pháp.Tôi có một vài báo cáo lỗi mở đối với tài liệu và các đại biểu UIWebView. – PassKit

+0

Bạn đã tìm ra cái này chưa? Tôi sắp phải thực hiện điều này và rất thích không phải tự tay nhấn lại máy chủ. – MrTristan

Trả lời

0
- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType { 

    NSURL *url = request.URL; 
    NSURLRequest *req = [NSURLRequest requestWithURL:url]; 
    NSURLConnection *conn = [NSURLConnection connectionWithRequest:req delegate:self]; 
    [conn start]; 
    return YES; 
} 

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{ 

    NSString *mime = [response MIMEType]; 
    NSLog(@"%@",mime); 

} 
+0

Trong khi công trình này, nó có một chi phí rất lớn kể từ khi mọi yêu cầu được tải xuống hai lần. Mã của bạn cũng dừng ở kiểu MIME - vấn đề của tôi là ứng dụng kiểu MIME/vnd.apple.pkpass không được hỗ trợ trực tiếp bởi UIWebView và vì vậy tôi cần phải có điều kiện (và hiệu quả) tải xuống các tệp này qua NSURLConnection, không tải xuống mọi thứ một cách bừa bãi song song. – PassKit

+0

Bạn có thể giải thích ở trên hai điểm 1) Tải xuống hai lần, 2) Dừng Loại MIME. Trong mã của tôi, tất cả các đại biểu này chỉ gọi một lần. shouldStartLoadWithRequest, didReceiveResponse, webViewDidStartLoad, webViewDidFinishLoad. – Zeeshan

+0

Khi các phương thức ủy nhiệm này kích hoạt, UIWebView cũng đang tải xuống tệp (nhưng cuối cùng sẽ bỏ nó vì nó không biết cách xử lý nó một cách tự nhiên). Sử dụng NSURLConnection yêu cầu hai yêu cầu độc lập cho máy chủ cho cùng một tài nguyên (bản gốc từ UIWebView + dạng thứ hai NSURLConnection). Tệp .pkpass là CPU chuyên sâu để tạo và có thể cân nhắc ở tối đa 500kb. Lý tưởng nhất là tôi có thể truy cập dữ liệu từ yêu cầu UIWebView ban đầu, nhưng đại biểu lỗi đã bỏ qua dữ liệu này. – PassKit

0

Bạn có thể thử subclassing NSURLProtocol và xử lý các thông tin phản ứng phân tích đó.

Nhìn vào

- (void)URLProtocol:(NSURLProtocol *)protocol didReceiveResponse:(NSURLResponse *)response cacheStoragePolicy:(NSURLCacheStoragePolicy)policy 

Đừng quên về subresources cũng sử dụng các móc.

+1

Bạn có thể cung cấp thêm một chút chi tiết về cách tiếp cận không? Có vẻ như chỉ waay để tránh phải tăng gấp đôi tải tài nguyên là sử dụng UIWebview hoặc NSURLConnection độc quyền, nhưng để làm seens thứ hai như rất nhiều công việc. – PassKit

+0

Bên trong NSURLProtocol của bạn, bạn sẽ bị ảnh hưởng bởi mọi yêu cầu mà mọi nguồn cấp dữ liệu phụ đều thực hiện. Bạn cũng có thể nhấn vào mọi phản hồi. Bạn có thể kiểm tra xem bạn có phải là tài khoản con dựa trên mainDocumentURL và URL của yêu cầu (đôi khi) hay không. Thông tin phản hồi có thuộc tính MIMEType mà bạn có thể xem. – cynistersix

0

Chỉ cần sử dụng js

let contentType = webView.stringByEvaluatingJavaScript(from: "document.contentType;") 
Các vấn đề liên quan