2012-08-03 29 views
4

我想使用UiWebView在iOS應用中顯示網站。該站點的某些組件(即使用AJAX調用加載的Web服務結果)應由本地數據替換。使用自定義NSURLProtocol在UIWebView中通過AJAX調用加載文本文件

考慮下面的例子:

的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上什麼也沒有發生。我試圖做一些錯誤處理,但也不是拋出JS AJAX錯誤,也不是調用UIWebViewDelegatedidFailLoadWithError

我嘗試另一種情況下,創造了一個HTML頁面,只是加載圖像:

<img src="image.png" /> 

,並修改了我的URLProtocol只處理圖像的加載 - 這個工作正常。也許這與AJAX調用有什麼關係?

你有什麼想法可能是什麼問題?

在此先感謝!

回答

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

你可以看到我的完整的工作落實在我的答案在這裏:

How to mock AJAX call with NSURLProtocol?

希望這會有所幫助, Vincent