Authored by 孙凯

add nsurlconnection review by hongmo

... ... @@ -43,6 +43,8 @@
52D204EE1F61360200CB7F1A /* UIActionSheet+AutoTrack.m in Sources */ = {isa = PBXBuildFile; fileRef = 52D204ED1F61360200CB7F1A /* UIActionSheet+AutoTrack.m */; };
B1268A091F623B8800C1E7B9 /* UIWebView+AutoTrack.m in Sources */ = {isa = PBXBuildFile; fileRef = B1268A081F623B8800C1E7B9 /* UIWebView+AutoTrack.m */; };
B13B6C0C1F710BA600C18812 /* UITabBarItem+Yoho.m in Sources */ = {isa = PBXBuildFile; fileRef = B13B6C0B1F710BA600C18812 /* UITabBarItem+Yoho.m */; };
B1475E671F7F37FC0066B514 /* NSURLConnection+AutoTrack.m in Sources */ = {isa = PBXBuildFile; fileRef = B1475E661F7F37FC0066B514 /* NSURLConnection+AutoTrack.m */; };
B1475E6D1F7F38280066B514 /* NSURLSession+AutoTrack.m in Sources */ = {isa = PBXBuildFile; fileRef = B1475E6C1F7F38280066B514 /* NSURLSession+AutoTrack.m */; };
B17F61DB1F6678CD009D1606 /* UserNotifications.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B17F61DA1F6678CD009D1606 /* UserNotifications.framework */; };
B188D2051F692DB600FFBEDF /* SDWebImageDownloaderOperation+AutoTrack.m in Sources */ = {isa = PBXBuildFile; fileRef = B188D2041F692DB600FFBEDF /* SDWebImageDownloaderOperation+AutoTrack.m */; };
B1A393141F7B4E04009700D9 /* UIControl+AutoTrack.m in Sources */ = {isa = PBXBuildFile; fileRef = B1A393131F7B4E04009700D9 /* UIControl+AutoTrack.m */; };
... ... @@ -159,6 +161,10 @@
B1268A081F623B8800C1E7B9 /* UIWebView+AutoTrack.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIWebView+AutoTrack.m"; sourceTree = "<group>"; };
B13B6C0A1F710BA600C18812 /* UITabBarItem+Yoho.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UITabBarItem+Yoho.h"; sourceTree = "<group>"; };
B13B6C0B1F710BA600C18812 /* UITabBarItem+Yoho.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UITabBarItem+Yoho.m"; sourceTree = "<group>"; };
B1475E651F7F37FC0066B514 /* NSURLConnection+AutoTrack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSURLConnection+AutoTrack.h"; sourceTree = "<group>"; };
B1475E661F7F37FC0066B514 /* NSURLConnection+AutoTrack.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSURLConnection+AutoTrack.m"; sourceTree = "<group>"; };
B1475E6B1F7F38280066B514 /* NSURLSession+AutoTrack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSURLSession+AutoTrack.h"; sourceTree = "<group>"; };
B1475E6C1F7F38280066B514 /* NSURLSession+AutoTrack.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSURLSession+AutoTrack.m"; sourceTree = "<group>"; };
B17F61DA1F6678CD009D1606 /* UserNotifications.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UserNotifications.framework; path = System/Library/Frameworks/UserNotifications.framework; sourceTree = SDKROOT; };
B188D2031F692DB600FFBEDF /* SDWebImageDownloaderOperation+AutoTrack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SDWebImageDownloaderOperation+AutoTrack.h"; sourceTree = "<group>"; };
B188D2041F692DB600FFBEDF /* SDWebImageDownloaderOperation+AutoTrack.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "SDWebImageDownloaderOperation+AutoTrack.m"; sourceTree = "<group>"; };
... ... @@ -313,6 +319,10 @@
B1A393131F7B4E04009700D9 /* UIControl+AutoTrack.m */,
B1A393151F7C918C009700D9 /* UIGestureRecognizer+AutoTrack.h */,
B1A393161F7C918C009700D9 /* UIGestureRecognizer+AutoTrack.m */,
B1475E651F7F37FC0066B514 /* NSURLConnection+AutoTrack.h */,
B1475E661F7F37FC0066B514 /* NSURLConnection+AutoTrack.m */,
B1475E6B1F7F38280066B514 /* NSURLSession+AutoTrack.h */,
B1475E6C1F7F38280066B514 /* NSURLSession+AutoTrack.m */,
);
path = YH_AOP;
sourceTree = "<group>";
... ... @@ -678,10 +688,12 @@
52878BFB1F5D44F7000A1597 /* YH_EventCollector.m in Sources */,
52878C0A1F5FD582000A1597 /* UIViewController+AutoTrack.m in Sources */,
B1D774A61F62A37E00BA89C3 /* SDWebImageDownloaderOperation+Performance.m in Sources */,
B1475E671F7F37FC0066B514 /* NSURLConnection+AutoTrack.m in Sources */,
29D3B9761F739D2F00B07F47 /* YH_EventCollector+UIAlertView.m in Sources */,
529A00511F564E8500A83F63 /* ViewController.m in Sources */,
29CDB4B11F6FA5A500AAD350 /* PowerfulBannerView+AutoTrack.m in Sources */,
52878C041F5E8904000A1597 /* YHLog.m in Sources */,
B1475E6D1F7F38280066B514 /* NSURLSession+AutoTrack.m in Sources */,
B1F3F9791F7399380069C68C /* YH_Status.m in Sources */,
B1A393141F7B4E04009700D9 /* UIControl+AutoTrack.m in Sources */,
B1F3F9761F7399380069C68C /* YH_AnalyticEventData.m in Sources */,
... ...
... ... @@ -21,6 +21,7 @@
#import "UITabBar+AutoTrack.h"
#import "UIControl+AutoTrack.h"
#import "UIGestureRecognizer+AutoTrack.h"
#import "NSURLConnection+AutoTrack.h"
#define kYHEventReportIgnoredViewController @"YHEventReportQueue"
... ... @@ -149,6 +150,7 @@ static NSArray *kYHEventReportIgnoredViewControllerArray;
[UITabBar startTrack];
[UIControl startTrack];
[UIGestureRecognizer startTrack];
[NSURLConnection startTrack];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[UIWebView startTrack];
... ...
//
// NSURLConnection+AutoTrack.h
// YHEventReport
//
// Created by 孙凯 on 2017/9/30.
// Copyright © 2017年 YOHO. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface NSURLConnection (AutoTrack)
@property(nonatomic,copy)NSString *yh_viewId;//唯一ID
+(void)startTrack;
@end
... ...
//
// NSURLConnection+AutoTrack.m
// YHEventReport
//
// Created by 孙凯 on 2017/9/30.
// Copyright © 2017年 YOHO. All rights reserved.
//
#import "NSURLConnection+AutoTrack.h"
#import "YHSwizzle.h"
#import <objc/runtime.h>
#import <objc/message.h>
#import "YHEventReport.h"
#import "YHLog.h"
#import "YHSwizzle.h"
typedef void(^ActionHandlerBlock)(NSURLResponse* _Nullable response, NSData* _Nullable data, NSError* _Nullable connectionError);
static const void *yher_actionHandlerBlock = &yher_actionHandlerBlock;
@interface NSURLConnection()
@property(nullable,nonatomic,weak) id my_delegate;
@property (nonatomic, copy) ActionHandlerBlock actionHandlerBlock;
@end
@implementation NSURLConnection (AutoTrack)
#pragma mark - 属性
- (ActionHandlerBlock)actionHandlerBlock{
return objc_getAssociatedObject(self, @selector(actionHandlerBlock));
}
- (void)setActionHandlerBlock:(ActionHandlerBlock)actionHandlerBlock{
objc_setAssociatedObject(self, @selector(actionHandlerBlock), actionHandlerBlock, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- (void)setYh_viewId:(NSString *)yh_viewId{
objc_setAssociatedObject(self,@selector(yh_viewId),yh_viewId,OBJC_ASSOCIATION_RETAIN);
}
- (NSString *)yh_viewId{
return objc_getAssociatedObject(self, @selector(yh_viewId));
}
- (id)my_delegate
{
return objc_getAssociatedObject(self, _cmd);
}
- (void)setMy_delegate:(id)my_delegate
{
objc_setAssociatedObject(self, @selector(my_delegate), my_delegate, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
+(void)startTrack{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
@try {
SEL selectors[] = {
@selector(initWithRequest:delegate:),
@selector(initWithRequest:delegate:startImmediately:),
@selector(start),
};
for (NSUInteger index = 0; index < sizeof(selectors) / sizeof(SEL); ++index) {
SEL originalSelector = selectors[index];
SEL swizzledSelector = NSSelectorFromString([@"yher_" stringByAppendingString:NSStringFromSelector(originalSelector)]);
NSError *error = NULL;
[[self class] yh_swizzleMethod:originalSelector
withMethod:swizzledSelector
error:&error];
if (error) {
YHLog(@"Failed to swizzle: on UIControl. Details: %@", error);
error = NULL;
}
}
SEL class_selectors[] = {
@selector(sendSynchronousRequest:returningResponse:error:),
@selector(sendAsynchronousRequest:queue:completionHandler:),
};
for (NSUInteger index = 0; index < sizeof(class_selectors) / sizeof(SEL); ++index) {
Class selfClass = object_getClass([self class]);
SEL oriSEL = class_selectors[index];
Method oriMethod = class_getClassMethod(selfClass, oriSEL);
SEL cusSEL = NSSelectorFromString([@"yher_" stringByAppendingString:NSStringFromSelector(oriSEL)]);
Method cusMethod = class_getClassMethod(selfClass, cusSEL);
BOOL addSucc = class_addMethod(selfClass, oriSEL, method_getImplementation(cusMethod), method_getTypeEncoding(cusMethod));
if (addSucc) {
class_replaceMethod(selfClass, cusSEL, method_getImplementation(oriMethod), method_getTypeEncoding(oriMethod));
}else {
method_exchangeImplementations(oriMethod, cusMethod);
}
}
} @catch (NSException *exception) {
YHLog(@"%@ error: %@", self, exception);
}
});
}
- (nullable instancetype)yher_initWithRequest:(NSURLRequest *)request delegate:(nullable id)delegate startImmediately:(BOOL)startImmediately
{
[self setMy_delegate:delegate];
return [self yher_initWithRequest:request delegate:self startImmediately:startImmediately];
}
- (nullable instancetype)yher_initWithRequest:(NSURLRequest *)request delegate:(nullable id)delegate
{
[self setMy_delegate:delegate];
return [self yher_initWithRequest:request delegate:self];
}
- (void)yher_start
{
[self yher_start];
}
+ (nullable NSData *)yher_sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse * _Nullable * _Nullable)response error:(NSError **)error
{
NSData *data = [self yher_sendSynchronousRequest:request returningResponse:response error:error];
return data;
}
+ (void)yher_sendAsynchronousRequest:(NSURLRequest*) request
queue:(NSOperationQueue*) queue
completionHandler:(void (^)(NSURLResponse* _Nullable response, NSData* _Nullable data, NSError* _Nullable connectionError)) handler
{
objc_setAssociatedObject(self, yher_actionHandlerBlock, handler, OBJC_ASSOCIATION_COPY_NONATOMIC);
[self yher_sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
ActionHandlerBlock actionHandlerBlock = objc_getAssociatedObject(self, yher_actionHandlerBlock);
if (actionHandlerBlock) {
actionHandlerBlock(response,data,connectionError);
}
}];
}
#pragma mark - NSURLConnectionDelegate
- (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
if (self.my_delegate && [self.my_delegate respondsToSelector:@selector(connection:didReceiveResponse:)]) {
[self.my_delegate connection:connection didReceiveResponse:response];
}
}
- (void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
if (self.my_delegate && [self.my_delegate respondsToSelector:@selector(connection:didReceiveData:)]) {
[self.my_delegate connection:connection didReceiveData:data];
}
}
- (void) connectionDidFinishLoading:(NSURLConnection *)connection {
if (self.my_delegate && [self.my_delegate respondsToSelector:@selector(connectionDidFinishLoading:)]) {
[self.my_delegate connectionDidFinishLoading:connection];
}
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
if (self.my_delegate && [self.my_delegate respondsToSelector:@selector(connection:didFailWithError:)]) {
[self.my_delegate connection:connection didFailWithError:error];
}
}
@end
... ...
//
// NSURLSession+AutoTrack.h
// YHEventReport
//
// Created by 孙凯 on 2017/9/30.
// Copyright © 2017年 YOHO. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface NSURLSession (AutoTrack)
@end
... ...
//
// NSURLSession+AutoTrack.m
// YHEventReport
//
// Created by 孙凯 on 2017/9/30.
// Copyright © 2017年 YOHO. All rights reserved.
//
#import "NSURLSession+AutoTrack.h"
@implementation NSURLSession (AutoTrack)
@end
... ...