4

を使用してiOSアプリにWebサイトを表示したいUiWebView。サイトの一部のコンポーネント(つまり、AJAX呼び出しを使用してロードされたWebサービスの結果)は、ローカルデータに置き換える必要があります。

次の例を考えてみましょう。

text.txt:

foo

page1.html:

<html><head>
    <title>test</title>
    <script type="text/javascript" src="jquery.js"></script>
</head>
<body>
<div id="target"></div>
<script type="text/javascript">
    function init(){
        $.get("text.txt",function(text){    
            $("#target").text(text);
        });
    }
    $(init);
</script>
</body></html>

ビューコントローラ:

@interface ViewController : UIViewController <UIWebViewDelegate>
    @property (nonatomic,assign) IBOutlet UIWebView *webview;
@end


@implementation ViewController
    @synthesize webview;
    //some stuff here
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        [NSURLProtocol registerClass:[MyProtocol class]];
        NSString *url = @"http://remote-url/page1.html";
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
        [request setCachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData];
        [webview loadRequest:request];
    }
@end

MyProtocol:

@interface MyProtocol : NSURLProtocol

@end

@implementation MyProtocol

+ (BOOL) canInitWithRequest:(NSURLRequest *)req{
    NSLog(@"%@",[[req URL] lastPathComponent]);
    return [[[req URL] lastPathComponent] caseInsensitiveCompare:@"text.txt"] == NSOrderedSame;
}

+ (NSURLRequest*) canonicalRequestForRequest:(NSURLRequest *)req{
    return req;
}

- (void) startLoading{

    NSLog(@"Request for: %@",self.request.URL);
    NSString *response_ns = @"bar";
    NSData *data = [response_ns dataUsingEncoding:NSASCIIStringEncoding];
    NSURLResponse *response = [[NSURLResponse alloc] initWithURL:[self.request URL] MIMEType:@"text/plain" expectedContentLength:[data length] textEncodingName:nil];

    [[self client] URLProtocol: self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];
    [[self client] URLProtocol:self didLoadData:data];
    [[self client] URLProtocolDidFinishLoading:self];
    [response release];
}

- (void) stopLoading{
    NSLog(@"stopLoading");
}

@end

カスタムURLProtocolを登録しないと、ページが正しく表示されます。私startLoading()が呼び出されると、コンテンツが読み込まれ、stopLoading()後でトリガーされます。しかし、UIWebViewでは何も起こりません。didFailLoadWithErrorエラー処理を試みましたが、JS AJAXエラーはスローされず、UIWebViewDelegate呼び出されません。

別のシナリオを試し、画像を読み込むだけのHTMLページを作成しました。

<img src="image.png" />

そして、画像の読み込みを処理するようにURLProtocolを変更しました。これは正しく機能します。多分これはAJAX呼び出しと関係がありますか?

問題が何であるかについて何か考えがありますか?

前もって感謝します!

4

1 に答える 1

9

私は同じ問題を抱えていて、何日も髪を引っ張った後、最終的にそれを解決しました:

問題は、応答の作成方法に起因します。ステータス200の応答を作成し、必要に応じてWebViewにクロスドメイン要求を許可するように強制する必要があります。

NSDictionary *headers = @{@"Access-Control-Allow-Origin" : @"*", @"Access-Control-Allow-Headers" : @"Content-Type"};
NSHTTPURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:request.URL statusCode:200 HTTPVersion:@"1.1" headerFields:headers];

あなたはここで私の答えで私の完全に機能する実装を見ることができます:

NSURLProtocolでAJAX呼び出しをモックする方法は?

これがお役に立てば幸い、ヴィンセント

于 2013-03-05T21:50:39.437 に答える