NSURLProtocol canInitWithRequest:仅适用于某些请求

时间:2013-12-23 16:26:21

标签: ios iphone objective-c macos

我有一个WebView,我想截取并修改来自不同站点的某些请求。我对每个截获的请求进行完全相同的修改,无论它来自哪个站点。由于看似没有理由,它适用于除了一个以外的每个站点。这是我的代码:

在我的ResourceLoadDelegate

- (NSURLRequest *)webView:(WebView *)sender resource:(id)identifier willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse fromDataSource:(WebDataSource *)dataSource
{
    //predicates
    const NSPredicate *site1Predicate = [NSPredicate predicateWithFormat:@"SELF like \"/*predicate1*/""];
    const NSPredicate *site2Predicate = [NSPredicate predicateWithFormat:@"SELF like \"/*predicate2*/""];
    const NSPredicate *site3Predicate = [NSPredicate predicateWithFormat:@"SELF like \"/*predicate3*/""];
    const NSPredicate *site4Predicate = [NSPredicate predicateWithFormat:@"SELF like \"/*predicate4*/""];
    const NSPredicate *site5Predicate = [NSPredicate predicateWithFormat:@"SELF like \"/*predicate5*/""];

    //predicate arrays
    const NSArray *songPredicates = [NSArray arrayWithObjects:site1Predicate, site2Predicate, site3Predicate, site4Predicate, site5Predicate, nil];

    //site is an int with its defined in an enum
    if ([[songPredicates objectAtIndex:site-1] evaluateWithObject:request.URL.host])
    {
        NSMutableURLRequest* newRequest = [request mutableCopy];
        [InterceptionProtocol setProperty:self forKey:@"MyApp" inRequest:newRequest];
        dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            /* Do stuff */
        });
        return newRequest;
    }
    return request;
}

在InterceptionProtocol.m

+ (BOOL) canInitWithRequest:(NSURLRequest*)request
{
    id delegate = [NSURLProtocol propertyForKey:@"MyApp" inRequest:request];
    if (delegate) NSLog(@"Can init: %@", request);
    return (delegate != nil);
}

出于某种原因,除了站点4之外,这对于除了站点4之外的所有内容都非常有效。我已经完成了代码,我知道谓词正确匹配。我不知道这对其他网站有什么用,但不是这个。有什么想法吗?

修改

完整的源代码可以在这里找到: http://github.com/garrett-davidson/iLikeMusic

3 个答案:

答案 0 :(得分:1)

似乎问题是predicate4site4不匹配。关于单步执行代码并且正确匹配的说明令人困惑 - 如果是这种情况,一切都会正常工作,不是吗?

可能是你手动测试了你对谓词所期望的网址 - 而是你在实际运行期间获得的内容略有不同(比如由于URL编码 - 有空格或/或{ {1}} ?+编码的{1}}。将%放在NSLog之前,看看evaluateWithObject:到底发生了什么?

答案 1 :(得分:1)

然后,我们必须在你的App Delegate上注册这个协议 - (

BOOL)application:didFinishLaunchingWithOptions:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [NSURLProtocol registerClass:[ChromeBrowserURLProtocol class]];
...

源:customizing-uiwebview-requests-with-nsurlprotocol

答案 2 :(得分:1)

据我所知,NSURLProtocol不支持流连接,我相信这是不同的。与rdio流比较(返回206)

enter image description here

说,潘多拉,它返回完成的回复(200)。

Pandora Request

您的WebView委托方法正在捕获所有m.cdn *请求,其余的都可以通过您的自定义协议。

我建议在此处对传出的网络请求进行任何比较/更改:

webView:resource:willSendRequest:redirectResponse:fromDataSource:

因为这似乎可以保证调用您正在使用的所有请求。

希望有所帮助。