2013-04-27 8 views
5

UIWebViewは通帳の.pkpassファイルの処理を自動的にサポートしません。UIWebView代理人がMIMEタイプを取得

このtechnical noteでは、UIWebViewDelegateメソッドによるチェックを実装して、MIMEタイプを盗聴し、それに応じて処理することを推奨しています。

を識別するために適切な UIWebViewDelegateメソッドを実装する、のUIWebViewを使用して、パスを追加する場合、アプリケーションの MIMEタイプしかし/ vnd.apple.pkpass

有するビューデータをロードし、I MIMEタイプを提供できるものは、UIWebView Delegate Protocol Reference内に見つかりません。

NSURLConnectionデリゲートを使用して問題なく直接ファイルをダウンロードして処理することはできますが、ユーザーがUIWebView内をブラウズしているときに[手帳に追加]ボタンをクリックすると、パスが正しく処理されます。私はそのリンクを知らないので、多くのプロバイダは.pkpass拡張子とのリンクに接尾辞をつけていないので、AppleのMIMEタイプの調査のアドバイスに従って、最善の方法と思われます。

私は、次の

- (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デリゲートを追加しようとしている:

- (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]; 
    } 
} 

NSURLConnection代表が正常に動作し、接続がUIWebViewせずに、直接呼び出されたとき。しかし、私がをUIWebViewデリゲートから起動しようとすると、.pkpassの80%程度しかダウンロードされていないので、ダウンロードが失敗します(_data変数とContent-Lengthヘッダーのランダムな不一致が発生します)。

だから、私の質問:

  1. は直接UIWebViewデリゲートメソッドから、MIME種類のホールドを取得するための簡単な方法はありますか?
  2. もしそうでなければ、並列NSURLConnectionを開くことでこれを正しく行うつもりですか、それとも良い方法がありますか?
  3. NSURLConnectionを使用すると、完全なファイルをダウンロードできなくなる可能性があります。
+0

でしょうか?はいの場合はそれを共有することができますか? –

+0

いいえ - 私はWWDCのAppleエンジニアと話し合いましたが、解決策はない、と私は言いました。ドキュメントとUIWebViewのデリゲートに対していくつかのオープンなバグレポートがあります。 – PassKit

+0

あなたはこれを考え出しましたか?私はこれに着手しようとしており、手動でサーバを再度叩く必要がないのが大好きです。 – MrTristan

答えて

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

これは動作しますが、すべての要求が2回ダウンロードされるため、オーバーヘッドが大きくなります。私の問題は、MIMEタイプapplication/vnd.apple.pkpassがUIWebViewで直接サポートされていないため、条件付きで(そして効率的に)これらのファイルをNSURLConnection経由でダウンロードする必要があります。無差別にすべてをダウンロードする必要はありません。並行して。 – PassKit

+0

上記の2つの点について説明できますか?1)ダウンロードを2回、2)MIMEタイプを停止します。私のコードでは、これらの代理人はすべて一度だけ呼び出します。 shouldStartLoadWithRequest、didReceiveResponse、webViewDidStartLoad、webViewDidFinishLoad。 – Zeeshan

+0

これらのデリゲートメソッドがトリガされると、UIWebViewはファイルをダウンロードしています(ただし、ネイティブに処理する方法がわからないため、最終的に削除されます)。 NSURLConnectionを使用するには、同じリソース(UIWebView + 2番目のNSURLConnectionの元の元)のサーバーへの2つの独立した要求が必要です。 .pkpassファイルはCPUを集中的に使用して生成され、最大500KBまでの重さがあります。理想的には、元のUIWebViewリクエストからデータにアクセスできるはずですが、エラーデリゲートがこのデータを破棄します。 – PassKit

0

あなたはNSURLProtocolをサブクラス化し、そこに解析する応答情報を扱う試みることができます。

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

ルックはまた、これらのフックの使用についてのサブリソースに忘れないでください。

+1

これにアプローチする方法をもう少し詳しく説明できますか? UIWebviewまたはNSURLConnectionを排他的に使用するのは、リソースを2倍にする必要がないようにするための唯一の方法ですが、後者の方法では多くの作業が必要になります。 – PassKit

+0

あなたのNSURLProtocolの中には、すべてのサブリソースが作るすべてのリクエストにヒットします。あなたはすべての応答にもタップすることができます。 mainDocumentURLとリクエストのURL(時には)に基づいて、あなたがサブリソースであるかどうかを確認することができます。応答情報には、あなたが見ることができるMIMETypeプロパティがあります。 – cynistersix

0

はちょうどあなたがこのための解決策を見つけるか、JS

let contentType = webView.stringByEvaluatingJavaScript(from: "document.contentType;") 
関連する問題