zoukankan      html  css  js  c++  java
  • 网络

    NSURLProtocol

     

    /*!

        @class NSURLProtocol

        

        @abstract NSURLProtocol is an abstract class which provides the

        basic structure for performing protocol-specific loading of URL

        data. Concrete subclasses handle the specifics associated with one

        or more protocols or URL schemes.

    */

    抽象类

     

    [NSURLProtocol registerClass:[KCURLProtocol class]];

     

     

    // 这个方法是注册后,NSURLProtocol就会通过这个方法确定参数request是否需要被处理

    // return : YES 需要经过这个NSURLProtocol"协议" 的处理, NO 这个 协议request不需要遵守这个NSURLProtocol"协议"

    // 这个方法的作用 :

    //   -| 1, 筛选Request是否需要遵守这个NSURLRequest ,

    //   -| 2, 处理http: , https等URL

    // 重定向

    // 监听 - sdk -

     

    + (BOOL)canInitWithRequest:(NSURLRequest *)request{

        

        NSLog(@"*** %@",request);

        // md5

        if ([NSURLProtocol propertyForKey:kcProtocolKey inRequest:request]) {

            return NO;//自己的链接不需要hook,或者如果已经重定向过,就不需要在拦截了

        

        }

        

        // 直接hook 图片

        NSArray *array = @[@"png",@"jpg",@"jpeg"];

        if ([array containsObject:[request.URL pathExtension]]) {

            return YES; //返回YES需要重定向,会调用startloading方法

        }

        // 拦截百度的logo

        if ([[request.URL absoluteString] isEqualToString:@"https://m.baidu.com/static/index/plus/plus_logo_web.png"]) {

            return YES;

        }

        

        if ([[request.URL absoluteString] isEqualToString:@"http://www.baidu.com/"]) {

            return YES;

        }

        // 黑名单 -- 服务器 -- 本地

        //

     

        return NO;

    }

     

     

    // 需要在该方法中发起一个请求,对于NSURLConnection来说,就是创建一个NSURLConnection,对于NSURLSession,就是发起一个NSURLSessionTask

    // 另外一点就是这个方法之后,会回调<NSURLProtocolClient>协议中的方法,

     

    - (void)startLoading{

        NSLog(@"%s",__func__);

        NSArray *array = @[@"png",@"jpg",@"jpeg"];

        // 广告

        if ([array containsObject:[self.request.URL pathExtension]]) {

            NSData *data = [self getImageData];

            [self.client URLProtocol:self didLoadData:data];

        }

        

        // 拦截给与自己数据

        if ([[self.request.URL absoluteString] isEqualToString:@"https://m.baidu.com/static/index/plus/plus_logo_web.png"]) {

            NSData *data = [self getImageData];

            [self.client URLProtocol:self didLoadData:data];

        }

        

        if ([[self.request.URL absoluteString] isEqualToString:@"http://www.baidu.com/"]) {

            

     

    //        NSString *url = @"http://127.0.0.1:8080/getMethod/";

                    NSString *url = @"http://127.0.0.1:8080";

        

            NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];

            [NSURLProtocol setProperty:@(YES) forKey:kcProtocolKey inRequest:request];//自己的链接不需要hook

     

            [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {

                

                NSLog(@"Connection - %@---%@",response,data);

            }];

            

        }

    }

     

    //    NSURLProtocol 在AFN和Session拦截会失效,原因是session的协议里面没有NSURLProtocol,需要使用运行时交互方法添加。

     

     

     

    #pragma mark - hook

     

    + (void)hookNSURLSessionConfiguration{

     

        Class cls = NSClassFromString(@"__NSCFURLSessionConfiguration") ?: NSClassFromString(@"NSURLSessionConfiguration");

        

        Method originalMethod = class_getInstanceMethod(cls, @selector(protocolClasses));

        Method stubMethod = class_getInstanceMethod([self class], @selector(protocolClasses));

        if (!originalMethod || !stubMethod) {

            [NSException raise:NSInternalInconsistencyException format:@"没有这个方法 无法交换"];

        }

        method_exchangeImplementations(originalMethod, stubMethod);

    }

     

    - (NSArray *)protocolClasses {

        return @[[KCURLProtocol class]];

        //如果还有其他的监控protocol,也可以在这里加进去

    }

  • 相关阅读:
    eclipse安装Genymotion插件
    [Eclipse插件] 安装和使用JD-Eclipse插件
    [Eclipse插件] Eclipse中如何安装和使用GrepCode插件
    [Android Studio] Android Studio如何删除module(转载)
    前端html基本标签
    python实现简单FTP
    文件的md5计算
    suprocess模块
    几个小例子
    configparser模块
  • 原文地址:https://www.cnblogs.com/coolcold/p/12258798.html
Copyright © 2011-2022 走看看