Method-Swizzling实战-实现iOS原生网络请求性能采集

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jingcheng345413/article/details/80523071

一、方法交换实现步骤(实例方法和类方法处理逻辑类似)

1.检查原类(要被替换方法的类)的原实例方法是否存在,如果不存在,则不交换;
2.检查新类(最终被使用的方法所在的类)的新实例方法是否存在,如果不存在,则不交换;
3.检索原实例方法所在的真实父类,防止循环调用;
4.如果原类和新类不是一个类,则需要将新类的新实例方法添加到原类;
(1)如果添加失败,说明该方法已经存在,则不需要再做交换;
(2)如果添加成功,需要从原类重新获取新添加的实例方法,否则可能交换失败。
5.将原类的新实例方法交换原类的原实例方法。
6方法交换的时机可以自己控制,确保能够及时交换就可以。
7.关键方法:
class_getInstanceMethod(Class _Nullable cls, SEL _Nonnull name)
class_addMethod(Class _Nullable cls, SEL _Nonnull name, IMP _Nonnull imp, 
                const char * _Nullable types) 
method_exchangeImplementations(Method _Nonnull m1, Method _Nonnull m2) 

二、iOS原生网络请求交换范围

1.NSURLConnection
2.NSURLSession

三、iOS原生网络请求交换步骤,以NSURLConnection为例,NSURLSession类似。

1.新增一个类,声明为NSURLConnection的一个新类别。

2.首先需要交换非代理方式的的请求API。

(1)NSURLConnection类有两个:

+(NSData*)sendSynchronousRequest:(NSURLRequest*)request returningResponse:(NSURLResponse* _Nullable* _Nullable)response error:(NSError**)error;
+(void)sendAsynchronousRequest:(NSURLRequest*)request queue:(NSOperationQueue*)queue completionHandler:(void (^)(NSURLResponse* _Nullable response, NSData* _Nullable data, NSError* _Nullable connectionError)) handler;

(2)新方法如下:

+(NSData*)swizzle_sendSynchronousRequest:(NSURLRequest*)request returningResponse:(NSURLResponse* _Nullable* _Nullable)response error:(NSError **)error
{
    //调用原本的方法
    NSData *resultData = [self swizzle_sendSynchronousRequest:request returningResponse:response error:error];
    return resultData;
}
+(void)swizzle_sendAsynchronousRequest:(NSURLRequest*)request queue:(NSOperationQueue*)queue completionHandler:(void (^)(NSURLResponse* _Nullable swizzle_response, NSData* _Nullable swizzle_data, NSError* _Nullable swizzle_connectionError)) swizzle_handler
{
    //如果回调方法为空,则直接返回,不做截获处理
    if (swizzle_handler == nil)
    {
        return [self swizzle_sendAsynchronousRequest:request queue:queue completionHandler:nil];
    }
    
    //调用原本的方法
    [self swizzle_sendAsynchronousRequest:request queue:queue
                           completionHandler:^(NSURLResponse* _Nullable response, NSData* _Nullable data, NSError* _Nullable connectionError)
     {
         //回调上层
         swizzle_handler(response, data, connectionError);
     }];
}

3.代理方式发送请求的API交换

(1)交换初始化方法,并在初始化方法中获取代理对象,并交换代理对象的网络代理方法。

原方法:
-(NSURLConnection*)initWithRequest:(NSURLRequest*)request delegate:(nullable id)delegate startImmediately:(BOOL)startImmediately;
- (NSURLConnection*)initWithRequest:(NSURLRequest*)request delegate:(nullable id)delegate;

新方法:
-(NSURLConnection*)swizzle_initWithRequest:(NSURLRequest*)request delegate:(nullable id)delegate startImmediately:(BOOL)startImmediately
{
    //设置代理方法交换,交换必要的方法即可
    [self methodsSwizzleForDelegate:delegate];

    //调用原本的方法
    return  [self swizzle_initWithRequest:request delegate:delegate startImmediately:startImmediately];
}
- (NSURLConnection*)swizzle_initWithRequest:(NSURLRequest*)request delegate:(nullable id)delegate
{
    //设置代理方法交换,交换必要的方法即可
    [self methodsSwizzleForDelegate:delegate];
    
    //调用原本的方法
    return  [self swizzle_initWithRequest:request delegate:delegate];;
}

(2)代理方法交换,只列举其中几个,可以扩展
- (void)swizzle_connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    //调用原本的方法
    [self swizzle_connection:connection didReceiveResponse:response];
}
-(void)swizzle_connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    //调用原本的方法
    [self swizzle_connection:connection didReceiveData:data];
}
-(void)swizzle_connectionDidFinishLoading:(NSURLConnection *)connection
{
    //调用原本的方法
    [self id_swizzle_connectionDidFinishLoading:connection];
}
-(void)swizzle_connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    //调用原本的方法
    [self id_swizzle_connection:connection didFailWithError:error];
}

四、请求性能数据采集

请求的整个过程和关键时机都经过我们自己的代码,性能指标数据采集不是很简单?

猜你喜欢

转载自blog.csdn.net/jingcheng345413/article/details/80523071