WebViewProxy 1.0.1

WebViewProxy 1.0.1

测试已测试
语言语言 Obj-CObjective C
许可 MIT
发布上次发布2015年2月

Marcus WestinMarcus WestinMarcus Westin维护。



  • marcuswestin

为web视图代理请求,容易且无需与NSURLProtocol纠缠。

适用于iOS和OSX。

对拦截请求的响应可以是同步的或异步的 - 这与UIWebViewDelegate方法-(NSCachedURLResponse *)cachedResponseForRequest:url:host:path:形成对比,该方法只能同步拦截请求和响应(这使得无法在例如不阻塞网络请求的情况下通过网络代理请求)。

如果您喜欢WebViewProxy,还应该查看WebViewJavascriptBridge

API

1:使用WebViewProxy注册处理器以拦截请求

+ (void) handleRequestsWithScheme:(NSString*)scheme handler:(WVPHandler)handler;

拦截所有具有给定方案的UIWebView请求。

示例

[WebViewProxy handleRequestsWithScheme:@"my_custom_scheme" handler:^(NSURLRequest* req, WVPResponse *res) {
    [res respondWithText:@"Hi!"];
}];
+ (void) handleRequestsWithHost:(NSString*)host handler:(WVPHandler)handler;

拦截所有具有给定主机的UIWebView请求。

示例

[WebViewProxy handleRequestsWithHost:@"foo" handler:^(NSURLRequest* req, WVPResponse *res) {
    [res respondWithText:@"Hi!"];
}];
+ (void) handleRequestsWithHost:(NSString*)host path:(NSString*)path handler:(WVPHandler)handler;

拦截所有匹配给定主机和URL路径的UIWebView请求。

示例

[WebViewProxy handleRequestsWithHost:@"foo.com" path:@"/bar" handler:^(NSURLRequest* req, WVPResponse *res) {
    [res respondWithText:@"Hi!"];
}];
+ (void) handleRequestsWithHost:(NSString*)host pathPrefix:(NSString*)pathPrefix handler:(WVPHandler)handler;

拦截所有匹配给定主机和URL路径前缀的UIWebView请求。

例如,使用[WebViewProxy handleRequestsWithHost:@"foo.com" pathPrefix:@"/bar" handler:...]注册的处理器将拦截对http://foo.com/barhttps://foo.com/bar/cat?wee=yeshttp://foo.com/bar/arbitrarily/long/subpath等请求的请求。

示例

[WebViewProxy handleRequestsWithHost:@"foo.com" pathPrefix:@"/bar" handler:^(NSURLRequest* req, WVPResponse *res) {
    [res respondWithText:@"Hi!"];
}];
+ (void) handleRequestsMatching:(NSPredicate*)predicate handler:(WVPHandler)handler;

拦截所有满足给定NSPredicateNSURL的UIWebView请求。

示例

[WebViewProxy handleRequestsMatching:[NSPredicate predicateWithFormat:@"absoluteString MATCHES[cd] '^http:'"] handler:^(NSURLRequest* req, WVPResponse *res) {
    [res respondWithText:@"Hi!"];
}];

[WebViewProxy handleRequestsMatching:[NSPredicate predicateWithFormat:@"host MATCHES[cd] '[foo|bar]'"]  handler:^(NSURLRequest* req, WVPResponse *res) {
    [res respondWithText:@"Hi!"];
}];

2:通过WVPResponse响应

所有注册的处理器都获得一个WVPRespone* res。您通过调用此对象的方法对请求进行响应。

响应请求有3种类型的API

  • 用于响应图像、文本、HTML或JSON的高级API
  • 用于响应特定HTTP头和NSData的低级API
  • 管道API用于将数据/错误从NSURLConnection通过WVPResponse传递

高级响应API

描述和示例将详细说明。

- (void) respondWithImage:(UIImage*)image;

以图像响应(默认使用Content-Type "image/png",对于以.jpg.jpeg结尾的请求,使用"image/jpg")

示例

[WebViewProxy handleRequestsWithHost:@"imageExample" path:@"GoogleLogo.png" handler:^(NSURLRequest* req, WVPResponse *res) {
    UIImage* image = [UIImage imageNamed:@"GoogleLogo.png"];
    [res respondWithImage:image];
}];
- (void) respondWithImage:(UIImage*)image mimeType:(NSString*)mimeType;

以图像和给定的MIME类型响应。

示例

[WebViewProxy handleRequestsWithHost:@"imageExample" handler:^(NSURLRequest* req, WVPResponse *res) {
    UIImage* image = [UIImage imageNamed:@"GoogleLogo.png"];
    [res respondWithImage:image mimeType:@"image/png"];
}];
- (void) respondWithText:(NSString*)text;

以文本形式响应(默认使用Content-Type "text/plain")

[WebViewProxy handleRequestsWithHost:@"textExample" handler:^(NSURLRequest* req, WVPResponse *res) {
    [res respondWithText:@"Hi!"];
}];
- (void) respondWithHTML:(NSString*)html;

以HTML形式响应(默认使用Content-Type "text/html")

[WebViewProxy handleRequestsWithHost:@"htmlExample" handler:^(NSURLRequest* req, WVPResponse *res) {
    [res respondWithText:@"<div class='notification'>Hi!</div>"];
}];
- (void) respondWithJSON:(NSDictionary*)jsonObject;

以JSON形式响应(默认使用Content-Type "application/json")

[WebViewProxy handleRequestsWithHost:@"textExample" handler:^(NSURLRequest* req, WVPResponse *res) {
    NSDictionary* jsonObject = [NSDictionary dictionaryWithObject:@"foo" forKey:@"bar"];
    [res respondWithJSON:jsonObject]; // sends '{ "bar":"foo" }'
}];

低级响应API

描述和示例将详细说明。

- (void) respondWithStatusCode:(NSInteger)statusCode text:(NSString*)text;

以指定的HTTP状态代码和文本响应。

示例

[res respondWithStatusCode:400 text:@"Bad request"];
[res respondWithStatusCode:404 text:@"Not found"];
- (void) setHeader:(NSString*)headerName value:(NSString*)headerValue;

在响应前设置响应头。

示例

[res setHeader:@"Content-Type" value:@"image/gif"];
[res setHeader:@"Content-Type" value:@"audio/wav"];
[res setHeader:@"Host" value:@"WebViewProxy"];
- (void) setHeaders:(NSDictionary*)headers;

在响应前设置多个响应头。

示例

[res setHeaders:@{ @"Content-Type":@"image/gif", @"Host":@"WebViewProxy" }];
- (void) respondWithData:(NSData*)data mimeType:(NSString*)mimeType;

以给定数据和MIME类型响应(MIME类型作为HTTP头Content-Type发送)。

如果mimeType为nil,则WebWiewProxy将尝试从请求URL路径扩展名推断它。

示例

NSString* greeting = @"Hi!";
NSData* data = [greeting dataUsingEncoding:NSUTF8StringEncoding];
[res respondWithData:data mimeType:@"text/plain"];
- (void) respondWithData:(NSData*)data mimeType:(NSString*)mimeType statusCode:(NSInteger)statusCode;

以给定数据、MIME类型和HTTP状态代码响应(MIME类型作为HTTP头Content-Type发送)。

如果mimeType为nil,则WebWiewProxy将尝试从请求URL路径扩展名推断它。

示例

NSData* data = [@"<div>Item has been created</div>" dataUsingEncoding:NSUTF8StringEncoding];
[res respondWithData:data mimeType:@"text/html" statusCode:201];
[res respondWithData:nil mimeType:nil statusCode:304]; // HTTP status code 304 "Not modified"
[res respondWithData:nil mimeType:nil statusCode:204]; // HTTP status code 204 "No Content"
NSURLCacheStoragePolicy cachePolicy (属性)

响应的缓存策略。默认值是NSURLCacheStorageNotAllowed

示例

response.cachePolicy = NSURLCacheStorageAllowed;
response.cachePolicy = NSURLCacheStorageAllowedInMemoryOnly;
response.cachePolicy = NSURLCacheStorageNotAllowed;

代理请求到远程服务器

有几种方法可以使用WebViewProxy代理远程请求。

最简单的方法是将WebViewProxyResponse作为NSURLConnection的代理。这将通过代理响应管道响应

[WebViewProxy handleRequestsWithHost:@"example.proxy" handler:^(NSURLRequest *req, WVPResponse *res) {
    NSString* proxyUrl = [req.URL.absoluteString stringByReplacingOccurrencesOfString:@"example.proxy" withString:@"example.com"];
    NSURLRequest* proxyReq = [NSURLRequest requestWithURL:[NSURL URLWithString:proxyUrl]];
    [NSURLConnection connectionWithRequest:proxyReq delegate:res];
}];

另一种方法可以提供更多控制,但会将整个响应读入内存中

[WebViewProxy handleRequestsWithHost:@"example.proxy" handler:^(NSURLRequest *req, WVPResponse *res) {
    NSString* proxyUrl = [req.URL.absoluteString stringByReplacingOccurrencesOfString:@"example.proxy" withString:@"example.com"];
    NSURLRequest* proxyReq = [NSURLRequest requestWithURL:[NSURL URLWithString:proxyUrl]];
    NSOperationQueue* queue = [NSOperationQueue new];
    [NSURLConnection sendAsynchronousRequest:proxyReq queue:queue completionHandler:^(NSURLResponse* proxyRes, NSData* proxyData, NSError* proxyErr) {
        if (proxyErr) {
            return [res pipeError:proxyErr];
        } else {
            NSInteger statusCode = [(NSHTTPURLResponse*)proxyRes statusCode];
            [res setHeaders:[(NSHTTPURLResponse*)proxyRes allHeaderFields]];
            [res respondWithData:proxyData mimeType:proxyRes.MIMEType statusCode:statusCode];
        }
    }];
}];

管道响应API

将一个 NSURLResponse 及其数据传入 WVPResponse。这使得通过 NSURLConnection 代理请求及其响应变得简单。

待编写示例。

- (void) pipeResponse:(NSURLResponse*)response;

将一个 NSURLResponse 传入响应。

- (void) pipeData:(NSData*)data;

将数据传入响应。

- (void) pipeError:(NSError*)error;

将错误传入响应(例如:网络错误)。

- (void) pipeEnd;

完成管道响应。

3: (可选)处理“停止加载”事件

请求处理器可能会被告知“停止加载”。这可能会发生在,例如在底层的 NSURLRequest 上调用 cancel: 的结果。您可以通过 WVPResponse 上的 handleStopLoadingRequest: 方法获取通知。

此 API 可以用于停止在请求处理器中执行昂贵计算等操作。

示例

[WebViewProxy handleRequestsMatching:predicate handler:^(NSURLRequest* req, WVPResponse *res) {
    NSOperation* expensiveOperation = [self startExpensiveOperation];
    [res handleStopLoadingRequest:^{
        [expensiveOperation cancel]
    }];
}];

贡献者