add http review by daiqiang
Showing
13 changed files
with
462 additions
and
76 deletions
@@ -26,6 +26,7 @@ | @@ -26,6 +26,7 @@ | ||
26 | #import "YH_CrashDataManager.h" | 26 | #import "YH_CrashDataManager.h" |
27 | #import "YH_EventDataFactory.h" | 27 | #import "YH_EventDataFactory.h" |
28 | #import "YH_CrashReporter.h" | 28 | #import "YH_CrashReporter.h" |
29 | +#import "NSURLSession+AutoTrack.h" | ||
29 | 30 | ||
30 | #define kYHEventReportIgnoredViewController @"YHEventReportQueue" | 31 | #define kYHEventReportIgnoredViewController @"YHEventReportQueue" |
31 | 32 | ||
@@ -157,13 +158,21 @@ static NSArray *kYHEventReportIgnoredViewControllerArray; | @@ -157,13 +158,21 @@ static NSArray *kYHEventReportIgnoredViewControllerArray; | ||
157 | */ | 158 | */ |
158 | -(void)startPerformanceTrack{ | 159 | -(void)startPerformanceTrack{ |
159 | self.performanceTrackEnabled = YES; | 160 | self.performanceTrackEnabled = YES; |
161 | + | ||
160 | if ([YHEventReport sharedInstance].isControllerPerformanceTrackEnable) { | 162 | if ([YHEventReport sharedInstance].isControllerPerformanceTrackEnable) { |
161 | [UIViewController startTrack]; | 163 | [UIViewController startTrack]; |
162 | [UITabBar startTrack]; | 164 | [UITabBar startTrack]; |
163 | } | 165 | } |
164 | - // [UIControl startTrack]; | ||
165 | - // [UITapGestureRecognizer startTrack]; | ||
166 | - // [NSURLConnection startTrack]; | 166 | + |
167 | + if ([YHEventReport sharedInstance].isButtonPerformanceTrackEnable) { | ||
168 | + [UIControl startTrack]; | ||
169 | + [UITapGestureRecognizer startTrack]; | ||
170 | + } | ||
171 | + | ||
172 | + if ([YHEventReport sharedInstance].isHttpPerformanceTrackEnable) { | ||
173 | + [NSURLConnection startTrack]; | ||
174 | + //[NSURLSession startTrack]; | ||
175 | + } | ||
167 | 176 | ||
168 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ | 177 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ |
169 | 178 |
@@ -12,50 +12,16 @@ | @@ -12,50 +12,16 @@ | ||
12 | #import <objc/message.h> | 12 | #import <objc/message.h> |
13 | #import "YHEventReport.h" | 13 | #import "YHEventReport.h" |
14 | #import "YHLog.h" | 14 | #import "YHLog.h" |
15 | -#import "YHSwizzle.h" | ||
16 | - | ||
17 | -typedef void(^ActionHandlerBlock)(NSURLResponse* _Nullable response, NSData* _Nullable data, NSError* _Nullable connectionError); | ||
18 | - | ||
19 | -static const void *yher_actionHandlerBlock = &yher_actionHandlerBlock; | 15 | +#import "YH_EventCollector.h" |
20 | 16 | ||
21 | @interface NSURLConnection() | 17 | @interface NSURLConnection() |
22 | 18 | ||
23 | -@property(nullable,nonatomic,weak) id my_delegate; | ||
24 | - | ||
25 | -@property (nonatomic, copy) ActionHandlerBlock actionHandlerBlock; | ||
26 | - | ||
27 | @end | 19 | @end |
28 | 20 | ||
29 | @implementation NSURLConnection (AutoTrack) | 21 | @implementation NSURLConnection (AutoTrack) |
30 | 22 | ||
31 | #pragma mark - 属性 | 23 | #pragma mark - 属性 |
32 | 24 | ||
33 | -- (ActionHandlerBlock)actionHandlerBlock{ | ||
34 | - return objc_getAssociatedObject(self, @selector(actionHandlerBlock)); | ||
35 | -} | ||
36 | - | ||
37 | -- (void)setActionHandlerBlock:(ActionHandlerBlock)actionHandlerBlock{ | ||
38 | - objc_setAssociatedObject(self, @selector(actionHandlerBlock), actionHandlerBlock, OBJC_ASSOCIATION_COPY_NONATOMIC); | ||
39 | -} | ||
40 | - | ||
41 | -- (void)setYh_viewId:(NSString *)yh_viewId{ | ||
42 | - objc_setAssociatedObject(self,@selector(yh_viewId),yh_viewId,OBJC_ASSOCIATION_RETAIN); | ||
43 | -} | ||
44 | - | ||
45 | -- (NSString *)yh_viewId{ | ||
46 | - return objc_getAssociatedObject(self, @selector(yh_viewId)); | ||
47 | -} | ||
48 | - | ||
49 | -- (id)my_delegate | ||
50 | -{ | ||
51 | - return objc_getAssociatedObject(self, _cmd); | ||
52 | -} | ||
53 | - | ||
54 | -- (void)setMy_delegate:(id)my_delegate | ||
55 | -{ | ||
56 | - objc_setAssociatedObject(self, @selector(my_delegate), my_delegate, OBJC_ASSOCIATION_RETAIN_NONATOMIC); | ||
57 | -} | ||
58 | - | ||
59 | +(void)startTrack{ | 25 | +(void)startTrack{ |
60 | static dispatch_once_t onceToken; | 26 | static dispatch_once_t onceToken; |
61 | dispatch_once(&onceToken, ^{ | 27 | dispatch_once(&onceToken, ^{ |
@@ -110,14 +76,12 @@ static const void *yher_actionHandlerBlock = &yher_actionHandlerBlock; | @@ -110,14 +76,12 @@ static const void *yher_actionHandlerBlock = &yher_actionHandlerBlock; | ||
110 | 76 | ||
111 | - (nullable instancetype)yher_initWithRequest:(NSURLRequest *)request delegate:(nullable id)delegate startImmediately:(BOOL)startImmediately | 77 | - (nullable instancetype)yher_initWithRequest:(NSURLRequest *)request delegate:(nullable id)delegate startImmediately:(BOOL)startImmediately |
112 | { | 78 | { |
113 | - [self setMy_delegate:delegate]; | ||
114 | - return [self yher_initWithRequest:request delegate:self startImmediately:startImmediately]; | 79 | + return [self yher_initWithRequest:request delegate:delegate startImmediately:startImmediately]; |
115 | } | 80 | } |
116 | 81 | ||
117 | - (nullable instancetype)yher_initWithRequest:(NSURLRequest *)request delegate:(nullable id)delegate | 82 | - (nullable instancetype)yher_initWithRequest:(NSURLRequest *)request delegate:(nullable id)delegate |
118 | { | 83 | { |
119 | - [self setMy_delegate:delegate]; | ||
120 | - return [self yher_initWithRequest:request delegate:self]; | 84 | + return [self yher_initWithRequest:request delegate:delegate]; |
121 | } | 85 | } |
122 | 86 | ||
123 | - (void)yher_start | 87 | - (void)yher_start |
@@ -127,7 +91,17 @@ static const void *yher_actionHandlerBlock = &yher_actionHandlerBlock; | @@ -127,7 +91,17 @@ static const void *yher_actionHandlerBlock = &yher_actionHandlerBlock; | ||
127 | 91 | ||
128 | + (nullable NSData *)yher_sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse * _Nullable * _Nullable)response error:(NSError **)error | 92 | + (nullable NSData *)yher_sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse * _Nullable * _Nullable)response error:(NSError **)error |
129 | { | 93 | { |
94 | + if ([YHEventReport sharedInstance].isPerformanceTrackEnabled && [YHEventReport sharedInstance].httpPerformanceTrackEnable) { | ||
95 | + [[YH_EventCollector sharedInstance] timeEventStartWithCollectionURL:[request.URL absoluteString]]; | ||
96 | + } | ||
130 | NSData *data = [self yher_sendSynchronousRequest:request returningResponse:response error:error]; | 97 | NSData *data = [self yher_sendSynchronousRequest:request returningResponse:response error:error]; |
98 | + if ([YHEventReport sharedInstance].isPerformanceTrackEnabled && [YHEventReport sharedInstance].httpPerformanceTrackEnable) { | ||
99 | + if (error) { | ||
100 | + [[YH_EventCollector sharedInstance] timeEventEndWithCollectionURL:[request.URL absoluteString] status:YHEventLoadStatusFailed]; | ||
101 | + }else{ | ||
102 | + [[YH_EventCollector sharedInstance] timeEventEndWithCollectionURL:[request.URL absoluteString] status:YHEventLoadStatusSuc]; | ||
103 | + } | ||
104 | + } | ||
131 | return data; | 105 | return data; |
132 | } | 106 | } |
133 | 107 | ||
@@ -135,40 +109,23 @@ static const void *yher_actionHandlerBlock = &yher_actionHandlerBlock; | @@ -135,40 +109,23 @@ static const void *yher_actionHandlerBlock = &yher_actionHandlerBlock; | ||
135 | queue:(NSOperationQueue*) queue | 109 | queue:(NSOperationQueue*) queue |
136 | completionHandler:(void (^)(NSURLResponse* _Nullable response, NSData* _Nullable data, NSError* _Nullable connectionError)) handler | 110 | completionHandler:(void (^)(NSURLResponse* _Nullable response, NSData* _Nullable data, NSError* _Nullable connectionError)) handler |
137 | { | 111 | { |
138 | - objc_setAssociatedObject(self, yher_actionHandlerBlock, handler, OBJC_ASSOCIATION_COPY_NONATOMIC); | ||
139 | - [self yher_sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) { | ||
140 | - ActionHandlerBlock actionHandlerBlock = objc_getAssociatedObject(self, yher_actionHandlerBlock); | ||
141 | - if (actionHandlerBlock) { | ||
142 | - actionHandlerBlock(response,data,connectionError); | ||
143 | - } | ||
144 | - }]; | ||
145 | -} | ||
146 | 112 | ||
147 | - | ||
148 | -#pragma mark - NSURLConnectionDelegate | ||
149 | -- (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { | ||
150 | - if (self.my_delegate && [self.my_delegate respondsToSelector:@selector(connection:didReceiveResponse:)]) { | ||
151 | - [self.my_delegate connection:connection didReceiveResponse:response]; | 113 | + if ([YHEventReport sharedInstance].isPerformanceTrackEnabled && [YHEventReport sharedInstance].httpPerformanceTrackEnable) { |
114 | + [[YH_EventCollector sharedInstance] timeEventStartWithCollectionURL:[request.URL absoluteString]]; | ||
152 | } | 115 | } |
153 | -} | 116 | + [self yher_sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) { |
154 | 117 | ||
155 | -- (void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { | ||
156 | - if (self.my_delegate && [self.my_delegate respondsToSelector:@selector(connection:didReceiveData:)]) { | ||
157 | - [self.my_delegate connection:connection didReceiveData:data]; | 118 | + if (handler) { |
119 | + handler(response,data,connectionError); | ||
158 | } | 120 | } |
159 | -} | ||
160 | - | ||
161 | -- (void) connectionDidFinishLoading:(NSURLConnection *)connection { | ||
162 | - if (self.my_delegate && [self.my_delegate respondsToSelector:@selector(connectionDidFinishLoading:)]) { | ||
163 | - [self.my_delegate connectionDidFinishLoading:connection]; | 121 | + if ([YHEventReport sharedInstance].isPerformanceTrackEnabled && [YHEventReport sharedInstance].httpPerformanceTrackEnable) { |
122 | + if (connectionError) { | ||
123 | + [[YH_EventCollector sharedInstance] timeEventEndWithCollectionURL:[request.URL absoluteString] status:YHEventLoadStatusFailed]; | ||
124 | + }else{ | ||
125 | + [[YH_EventCollector sharedInstance] timeEventEndWithCollectionURL:[request.URL absoluteString] status:YHEventLoadStatusSuc]; | ||
164 | } | 126 | } |
165 | -} | ||
166 | - | ||
167 | -- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { | ||
168 | - if (self.my_delegate && [self.my_delegate respondsToSelector:@selector(connection:didFailWithError:)]) { | ||
169 | - [self.my_delegate connection:connection didFailWithError:error]; | ||
170 | } | 127 | } |
171 | - | 128 | + }]; |
172 | } | 129 | } |
173 | 130 | ||
174 | @end | 131 | @end |
@@ -10,4 +10,14 @@ | @@ -10,4 +10,14 @@ | ||
10 | 10 | ||
11 | @interface NSURLSession (AutoTrack) | 11 | @interface NSURLSession (AutoTrack) |
12 | 12 | ||
13 | ++(void)startTrack; | ||
14 | + | ||
15 | +@end | ||
16 | + | ||
17 | +@interface NSURLSessionTask (AutoTrack) | ||
18 | + | ||
19 | +@property(nonatomic,copy)NSString *yh_viewId;//唯一ID | ||
20 | + | ||
21 | ++(void)startTrack; | ||
22 | + | ||
13 | @end | 23 | @end |
@@ -7,7 +7,243 @@ | @@ -7,7 +7,243 @@ | ||
7 | // | 7 | // |
8 | 8 | ||
9 | #import "NSURLSession+AutoTrack.h" | 9 | #import "NSURLSession+AutoTrack.h" |
10 | +#import "YHSwizzle.h" | ||
11 | +#import <objc/runtime.h> | ||
12 | +#import <objc/message.h> | ||
13 | +#import "YHEventReport.h" | ||
14 | +#import "YHLog.h" | ||
15 | +#import "YH_EventCollector.h" | ||
16 | + | ||
17 | + | ||
18 | +@interface NSURLSession() | ||
19 | + | ||
20 | +@end | ||
21 | + | ||
10 | 22 | ||
11 | @implementation NSURLSession (AutoTrack) | 23 | @implementation NSURLSession (AutoTrack) |
12 | 24 | ||
25 | +#pragma mark - 属性 | ||
26 | + | ||
27 | ++(void)startTrack{ | ||
28 | + static dispatch_once_t onceToken; | ||
29 | + dispatch_once(&onceToken, ^{ | ||
30 | + @try { | ||
31 | + | ||
32 | + [NSURLSessionTask startTrack]; | ||
33 | + | ||
34 | + SEL class_selectors[] = { | ||
35 | + @selector(dataTaskWithRequest:completionHandler:), | ||
36 | + @selector(dataTaskWithURL:completionHandler:), | ||
37 | + @selector(uploadTaskWithRequest:fromData:completionHandler:), | ||
38 | + @selector(uploadTaskWithRequest:fromFile:completionHandler:), | ||
39 | + @selector(downloadTaskWithRequest:completionHandler:), | ||
40 | + @selector(downloadTaskWithURL:completionHandler:), | ||
41 | + @selector(downloadTaskWithResumeData:completionHandler:), | ||
42 | + }; | ||
43 | + | ||
44 | + for (NSUInteger index = 0; index < sizeof(class_selectors) / sizeof(SEL); ++index) { | ||
45 | + Class selfClass = object_getClass([self class]); | ||
46 | + SEL oriSEL = class_selectors[index]; | ||
47 | + Method oriMethod = class_getClassMethod(selfClass, oriSEL); | ||
48 | + SEL cusSEL = NSSelectorFromString([@"yher_" stringByAppendingString:NSStringFromSelector(oriSEL)]); | ||
49 | + Method cusMethod = class_getClassMethod(selfClass, cusSEL); | ||
50 | + | ||
51 | + BOOL addSucc = class_addMethod(selfClass, oriSEL, method_getImplementation(cusMethod), method_getTypeEncoding(cusMethod)); | ||
52 | + if (addSucc) { | ||
53 | + class_replaceMethod(selfClass, cusSEL, method_getImplementation(oriMethod), method_getTypeEncoding(oriMethod)); | ||
54 | + }else { | ||
55 | + method_exchangeImplementations(oriMethod, cusMethod); | ||
56 | + } | ||
57 | + | ||
58 | + } | ||
59 | + } @catch (NSException *exception) { | ||
60 | + YHLog(@"%@ error: %@", self, exception); | ||
61 | + } | ||
62 | + }); | ||
63 | +} | ||
64 | + | ||
65 | + | ||
66 | +- (NSURLSessionDataTask *)yher_dataTaskWithRequest:(NSURLRequest *)request completionHandler:(void (^)(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler | ||
67 | +{ | ||
68 | + __block NSURLSessionDataTask *task = [self yher_dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { | ||
69 | + if (completionHandler) { | ||
70 | + completionHandler(data,response,error); | ||
71 | + } | ||
72 | + if ([YHEventReport sharedInstance].isPerformanceTrackEnabled && [YHEventReport sharedInstance].httpPerformanceTrackEnable) { | ||
73 | + if (error) { | ||
74 | + [[YH_EventCollector sharedInstance] timeEventEndWithSessionTask:task status:YHEventLoadStatusFailed]; | ||
75 | + }else{ | ||
76 | + [[YH_EventCollector sharedInstance] timeEventEndWithSessionTask:task status:YHEventLoadStatusSuc]; | ||
77 | + } | ||
78 | + } | ||
79 | + }]; | ||
80 | + | ||
81 | + return task; | ||
82 | +} | ||
83 | + | ||
84 | +- (NSURLSessionDataTask *)yher_dataTaskWithURL:(NSURL *)url completionHandler:(void (^)(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler | ||
85 | +{ | ||
86 | + __block NSURLSessionDataTask *task = [self yher_dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { | ||
87 | + | ||
88 | + if (completionHandler) { | ||
89 | + completionHandler(data,response,error); | ||
90 | + } | ||
91 | + if ([YHEventReport sharedInstance].isPerformanceTrackEnabled && [YHEventReport sharedInstance].httpPerformanceTrackEnable) { | ||
92 | + if (error) { | ||
93 | + [[YH_EventCollector sharedInstance] timeEventEndWithSessionTask:task status:YHEventLoadStatusFailed]; | ||
94 | + }else{ | ||
95 | + [[YH_EventCollector sharedInstance] timeEventEndWithSessionTask:task status:YHEventLoadStatusSuc]; | ||
96 | + } | ||
97 | + } | ||
98 | + }]; | ||
99 | + return task; | ||
100 | +} | ||
101 | + | ||
102 | +- (NSURLSessionUploadTask *)yher_uploadTaskWithRequest:(NSURLRequest *)request fromFile:(NSURL *)fileURL completionHandler:(void (^)(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler | ||
103 | +{ | ||
104 | + | ||
105 | + __block NSURLSessionUploadTask *task = [self yher_uploadTaskWithRequest:request fromFile:fileURL completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { | ||
106 | + | ||
107 | + if (completionHandler) { | ||
108 | + completionHandler(data,response,error); | ||
109 | + } | ||
110 | + if ([YHEventReport sharedInstance].isPerformanceTrackEnabled && [YHEventReport sharedInstance].httpPerformanceTrackEnable) { | ||
111 | + if (error) { | ||
112 | + [[YH_EventCollector sharedInstance] timeEventEndWithSessionTask:task status:YHEventLoadStatusFailed]; | ||
113 | + }else{ | ||
114 | + [[YH_EventCollector sharedInstance] timeEventEndWithSessionTask:task status:YHEventLoadStatusSuc]; | ||
115 | + } | ||
116 | + } | ||
117 | + }]; | ||
118 | + return task; | ||
119 | +} | ||
120 | + | ||
121 | +- (NSURLSessionUploadTask *)yher_uploadTaskWithRequest:(NSURLRequest *)request fromData:(nullable NSData *)bodyData completionHandler:(void (^)(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler | ||
122 | +{ | ||
123 | + | ||
124 | + __block NSURLSessionUploadTask *task = [self yher_uploadTaskWithRequest:request fromData:bodyData completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { | ||
125 | + | ||
126 | + if (completionHandler) { | ||
127 | + completionHandler(data,response,error); | ||
128 | + } | ||
129 | + if ([YHEventReport sharedInstance].isPerformanceTrackEnabled && [YHEventReport sharedInstance].httpPerformanceTrackEnable) { | ||
130 | + if (error) { | ||
131 | + [[YH_EventCollector sharedInstance] timeEventEndWithSessionTask:task status:YHEventLoadStatusFailed]; | ||
132 | + }else{ | ||
133 | + [[YH_EventCollector sharedInstance] timeEventEndWithSessionTask:task status:YHEventLoadStatusSuc]; | ||
134 | + } | ||
135 | + } | ||
136 | + }]; | ||
137 | + return task; | ||
138 | +} | ||
139 | + | ||
140 | +- (NSURLSessionDownloadTask *)yher_downloadTaskWithRequest:(NSURLRequest *)request completionHandler:(void (^)(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler | ||
141 | +{ | ||
142 | + | ||
143 | + __block NSURLSessionDownloadTask *task = [self yher_downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) { | ||
144 | + | ||
145 | + if (completionHandler) { | ||
146 | + completionHandler(location,response,error); | ||
147 | + } | ||
148 | + if ([YHEventReport sharedInstance].isPerformanceTrackEnabled && [YHEventReport sharedInstance].httpPerformanceTrackEnable) { | ||
149 | + if (error) { | ||
150 | + [[YH_EventCollector sharedInstance] timeEventEndWithSessionTask:task status:YHEventLoadStatusFailed]; | ||
151 | + }else{ | ||
152 | + [[YH_EventCollector sharedInstance] timeEventEndWithSessionTask:task status:YHEventLoadStatusSuc]; | ||
153 | + } | ||
154 | + } | ||
155 | + }]; | ||
156 | + return task; | ||
157 | +} | ||
158 | + | ||
159 | +- (NSURLSessionDownloadTask *)yher_downloadTaskWithURL:(NSURL *)url completionHandler:(void (^)(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler | ||
160 | +{ | ||
161 | + | ||
162 | + __block NSURLSessionDownloadTask *task = [self yher_downloadTaskWithURL:url completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) { | ||
163 | + | ||
164 | + if (completionHandler) { | ||
165 | + completionHandler(location,response,error); | ||
166 | + } | ||
167 | + if ([YHEventReport sharedInstance].isPerformanceTrackEnabled && [YHEventReport sharedInstance].httpPerformanceTrackEnable) { | ||
168 | + if (error) { | ||
169 | + [[YH_EventCollector sharedInstance] timeEventEndWithSessionTask:task status:YHEventLoadStatusFailed]; | ||
170 | + }else{ | ||
171 | + [[YH_EventCollector sharedInstance] timeEventEndWithSessionTask:task status:YHEventLoadStatusSuc]; | ||
172 | + } | ||
173 | + } | ||
174 | + }]; | ||
175 | + return task; | ||
176 | +} | ||
177 | + | ||
178 | +- (NSURLSessionDownloadTask *)yher_downloadTaskWithResumeData:(NSData *)resumeData completionHandler:(void (^)(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler | ||
179 | +{ | ||
180 | + | ||
181 | + __block NSURLSessionDownloadTask *task = [self yher_downloadTaskWithResumeData:resumeData completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) { | ||
182 | + | ||
183 | + if (completionHandler) { | ||
184 | + completionHandler(location,response,error); | ||
185 | + } | ||
186 | + if ([YHEventReport sharedInstance].isPerformanceTrackEnabled && [YHEventReport sharedInstance].httpPerformanceTrackEnable) { | ||
187 | + if (error) { | ||
188 | + [[YH_EventCollector sharedInstance] timeEventEndWithSessionTask:task status:YHEventLoadStatusFailed]; | ||
189 | + }else{ | ||
190 | + [[YH_EventCollector sharedInstance] timeEventEndWithSessionTask:task status:YHEventLoadStatusSuc]; | ||
191 | + } | ||
192 | + } | ||
193 | + }]; | ||
194 | + return task; | ||
195 | +} | ||
196 | + | ||
197 | +@end | ||
198 | + | ||
199 | +@implementation NSURLSessionTask (AutoTrack) | ||
200 | + | ||
201 | +- (void)setYh_viewId:(NSString *)yh_viewId{ | ||
202 | + objc_setAssociatedObject(self,@selector(yh_viewId),yh_viewId,OBJC_ASSOCIATION_RETAIN); | ||
203 | +} | ||
204 | + | ||
205 | +- (NSString *)yh_viewId{ | ||
206 | + return objc_getAssociatedObject(self, @selector(yh_viewId)); | ||
207 | +} | ||
208 | + | ||
209 | ++(void)startTrack{ | ||
210 | + static dispatch_once_t onceToken; | ||
211 | + dispatch_once(&onceToken, ^{ | ||
212 | + @try { | ||
213 | + | ||
214 | + SEL class_selectors[] = { | ||
215 | + @selector(resume), | ||
216 | + }; | ||
217 | + | ||
218 | + for (NSUInteger index = 0; index < sizeof(class_selectors) / sizeof(SEL); ++index) { | ||
219 | + Class selfClass = object_getClass([self class]); | ||
220 | + SEL oriSEL = class_selectors[index]; | ||
221 | + Method oriMethod = class_getClassMethod(selfClass, oriSEL); | ||
222 | + SEL cusSEL = NSSelectorFromString([@"yher_" stringByAppendingString:NSStringFromSelector(oriSEL)]); | ||
223 | + Method cusMethod = class_getClassMethod(selfClass, cusSEL); | ||
224 | + | ||
225 | + BOOL addSucc = class_addMethod(selfClass, oriSEL, method_getImplementation(cusMethod), method_getTypeEncoding(cusMethod)); | ||
226 | + if (addSucc) { | ||
227 | + class_replaceMethod(selfClass, cusSEL, method_getImplementation(oriMethod), method_getTypeEncoding(oriMethod)); | ||
228 | + }else { | ||
229 | + method_exchangeImplementations(oriMethod, cusMethod); | ||
230 | + } | ||
231 | + | ||
232 | + } | ||
233 | + } @catch (NSException *exception) { | ||
234 | + YHLog(@"%@ error: %@", self, exception); | ||
235 | + } | ||
236 | + }); | ||
237 | +} | ||
238 | + | ||
239 | + | ||
240 | +- (void)yher_resume | ||
241 | +{ | ||
242 | + if ([YHEventReport sharedInstance].isPerformanceTrackEnabled && [YHEventReport sharedInstance].httpPerformanceTrackEnable) { | ||
243 | + [[YH_EventCollector sharedInstance] timeEventStartWithSession:self]; | ||
244 | + } | ||
245 | + [self yher_resume]; | ||
246 | +} | ||
247 | + | ||
13 | @end | 248 | @end |
249 | + |
@@ -117,10 +117,11 @@ | @@ -117,10 +117,11 @@ | ||
117 | NSString *selectorAction = NSStringFromSelector(action); | 117 | NSString *selectorAction = NSStringFromSelector(action); |
118 | 118 | ||
119 | if ([YHEventReport sharedInstance].isPerformanceTrackEnabled && [YHEventReport sharedInstance].buttonPerformanceTrackEnable && [self isKindOfClass:[UIButton class]]) { | 119 | if ([YHEventReport sharedInstance].isPerformanceTrackEnabled && [YHEventReport sharedInstance].buttonPerformanceTrackEnable && [self isKindOfClass:[UIButton class]]) { |
120 | - if ([selectorAction rangeOfString:@":"].location !=NSNotFound) { | ||
121 | - [UIControl yher_exchangeSelector:action target:target toSelector:@selector(yher_UIControl_didTouch_cmdWithEvent:)]; | ||
122 | - }else{ | 120 | + |
121 | + if ([[selectorAction componentsSeparatedByString:@":"]count]==1) { | ||
123 | [UIControl yher_exchangeSelector:action target:target toSelector:@selector(yher_UIControl_didTouch_cmd)]; | 122 | [UIControl yher_exchangeSelector:action target:target toSelector:@selector(yher_UIControl_didTouch_cmd)]; |
123 | + }else if ([[selectorAction componentsSeparatedByString:@":"]count]==2){ | ||
124 | + [UIControl yher_exchangeSelector:action target:target toSelector:@selector(yher_UIControl_didTouch_cmdWithEvent:)]; | ||
124 | } | 125 | } |
125 | } | 126 | } |
126 | 127 |
@@ -56,17 +56,25 @@ | @@ -56,17 +56,25 @@ | ||
56 | #pragma mark - hook API | 56 | #pragma mark - hook API |
57 | - (instancetype)yher_initWithTarget:(nullable id)target action:(nullable SEL)action | 57 | - (instancetype)yher_initWithTarget:(nullable id)target action:(nullable SEL)action |
58 | { | 58 | { |
59 | + NSString *selectorAction = NSStringFromSelector(action); | ||
60 | + | ||
59 | if ([YHEventReport sharedInstance].isPerformanceTrackEnabled && [YHEventReport sharedInstance].buttonPerformanceTrackEnable && ([target isKindOfClass:[UIViewController class]] || [target isKindOfClass:[UIImageView class]] || [target isKindOfClass:[UILabel class]])) { | 61 | if ([YHEventReport sharedInstance].isPerformanceTrackEnabled && [YHEventReport sharedInstance].buttonPerformanceTrackEnable && ([target isKindOfClass:[UIViewController class]] || [target isKindOfClass:[UIImageView class]] || [target isKindOfClass:[UILabel class]])) { |
62 | + if ([[selectorAction componentsSeparatedByString:@":"]count]==1) { | ||
60 | [UITapGestureRecognizer yher_exchangeSelector:action target:target toSelector:@selector(yher_gestureRecognizerDidTouch_cmd:)]; | 63 | [UITapGestureRecognizer yher_exchangeSelector:action target:target toSelector:@selector(yher_gestureRecognizerDidTouch_cmd:)]; |
61 | } | 64 | } |
65 | + } | ||
62 | return [self yher_initWithTarget:target action:action]; | 66 | return [self yher_initWithTarget:target action:action]; |
63 | } | 67 | } |
64 | 68 | ||
65 | - (void)yher_addTarget:(id)target action:(SEL)action | 69 | - (void)yher_addTarget:(id)target action:(SEL)action |
66 | { | 70 | { |
71 | + NSString *selectorAction = NSStringFromSelector(action); | ||
72 | + | ||
67 | if ([YHEventReport sharedInstance].isPerformanceTrackEnabled && [YHEventReport sharedInstance].buttonPerformanceTrackEnable && ([target isKindOfClass:[UIViewController class]] || [target isKindOfClass:[UIImageView class]] || [target isKindOfClass:[UILabel class]])) { | 73 | if ([YHEventReport sharedInstance].isPerformanceTrackEnabled && [YHEventReport sharedInstance].buttonPerformanceTrackEnable && ([target isKindOfClass:[UIViewController class]] || [target isKindOfClass:[UIImageView class]] || [target isKindOfClass:[UILabel class]])) { |
74 | + if ([[selectorAction componentsSeparatedByString:@":"]count]==1) { | ||
68 | [UITapGestureRecognizer yher_exchangeSelector:action target:target toSelector:@selector(yher_gestureRecognizerDidTouch_cmd:)]; | 75 | [UITapGestureRecognizer yher_exchangeSelector:action target:target toSelector:@selector(yher_gestureRecognizerDidTouch_cmd:)]; |
69 | } | 76 | } |
77 | + } | ||
70 | 78 | ||
71 | [self yher_addTarget:target action:action]; | 79 | [self yher_addTarget:target action:action]; |
72 | } | 80 | } |
@@ -257,6 +257,59 @@ | @@ -257,6 +257,59 @@ | ||
257 | return performanceAryDic; | 257 | return performanceAryDic; |
258 | } | 258 | } |
259 | 259 | ||
260 | +-(NSString *)getPointName:(YHEventReportPointName)pointName{ | ||
261 | + NSString *str = @""; | ||
262 | + switch (pointName) { | ||
263 | + case YHPN_VIEWCONTROLLER: | ||
264 | + str = @"PAGE"; | ||
265 | + break; | ||
266 | + case YHPN_WEBVIEW: | ||
267 | + str = @"WEBVIEW"; | ||
268 | + break; | ||
269 | + case YHPN_IMAGEVIEW: | ||
270 | + str = @"IMAGE"; | ||
271 | + break; | ||
272 | + case YHPN_BUTTON: | ||
273 | + str = @"BUTTON"; | ||
274 | + break; | ||
275 | + case YHPN_GESTURERECOGNIZER: | ||
276 | + str = @"GESTURERECOGNIZER"; | ||
277 | + break; | ||
278 | + case YHPN_HTTP: | ||
279 | + str = @"HTTP"; | ||
280 | + break; | ||
281 | + default: | ||
282 | + break; | ||
283 | + } | ||
284 | + | ||
285 | + return str; | ||
286 | +} | ||
287 | + | ||
288 | +-(NSString *)getDataType:(YHEventReportTrackDataType)type{ | ||
289 | + NSString *str = @""; | ||
290 | + | ||
291 | + switch (type) { | ||
292 | + case YHEventReportTrackDataTypeStart: | ||
293 | + str = @"start"; | ||
294 | + break; | ||
295 | + case YHEventReportTrackDataTypeDestory: | ||
296 | + str = @"destory"; | ||
297 | + break; | ||
298 | + case YHEventReportTrackDataTypeStop: | ||
299 | + str = @"stop"; | ||
300 | + break; | ||
301 | + case YHEventReportTrackDataTypeHeartbeat: | ||
302 | + str = @"hb"; | ||
303 | + break; | ||
304 | + case YHEventReportTrackDataTypeNONE: | ||
305 | + str = @"realTime"; | ||
306 | + break; | ||
307 | + default: | ||
308 | + break; | ||
309 | + } | ||
310 | + | ||
311 | + return str; | ||
312 | +} | ||
260 | 313 | ||
261 | - (void)refreshPushStatus | 314 | - (void)refreshPushStatus |
262 | { | 315 | { |
@@ -30,6 +30,20 @@ | @@ -30,6 +30,20 @@ | ||
30 | - (void)timeEventStartWithUIGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer; | 30 | - (void)timeEventStartWithUIGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer; |
31 | - (void)timeEventEndWithUIGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer; | 31 | - (void)timeEventEndWithUIGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer; |
32 | 32 | ||
33 | +- (void)timeEventStartWithCollectionURL:(NSString *)collectionURL; | ||
34 | +- (void)timeEventEndWithCollectionURL:(NSString *)collectionURL status:(YHEventLoadStatus)status; | ||
35 | + | ||
36 | +- (void)timeEventStartWithSession:(NSURLSessionTask*)sessionTask; | ||
37 | +- (void)timeEventEndWithSessionTask:(NSURLSessionTask *)sessionTask status:(YHEventLoadStatus)status; | ||
38 | + | ||
39 | ++ (void)trackAppClickWithView:(id)targetView UITableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath; | ||
40 | + | ||
41 | ++ (void)trackAppClickWithView:(id)targetView UICollectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath; | ||
42 | + | ||
43 | ++ (void)trackAppClickWithView:(id)targetView UITabbar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item; | ||
44 | + | ||
45 | ++ (void)trackAppClickWithView:(id)targetView UIAlertView:(UIAlertView *)alertView didSelectIndex:(NSInteger )buttonIndex; | ||
46 | + | ||
33 | + (NSString *)viewPathOfPurposeView:(UIView *)purposeView; | 47 | + (NSString *)viewPathOfPurposeView:(UIView *)purposeView; |
34 | 48 | ||
35 | @end | 49 | @end |
@@ -19,6 +19,8 @@ | @@ -19,6 +19,8 @@ | ||
19 | #import "UITabBarItem+Yoho.h" | 19 | #import "UITabBarItem+Yoho.h" |
20 | #import "UIControl+AutoTrack.h" | 20 | #import "UIControl+AutoTrack.h" |
21 | #import "UITapGestureRecognizer+AutoTrack.h" | 21 | #import "UITapGestureRecognizer+AutoTrack.h" |
22 | +#import "NSURLSession+AutoTrack.h" | ||
23 | +#import "NSURLConnection+AutoTrack.h" | ||
22 | 24 | ||
23 | #define kYHEventReportQueue @"YHEventReportQueue" | 25 | #define kYHEventReportQueue @"YHEventReportQueue" |
24 | #define kYHEventReporrH5StartKey @"YHEventReporrH5StartKey" | 26 | #define kYHEventReporrH5StartKey @"YHEventReporrH5StartKey" |
@@ -394,6 +396,89 @@ | @@ -394,6 +396,89 @@ | ||
394 | } | 396 | } |
395 | 397 | ||
396 | 398 | ||
399 | +#pragma mark - http performance time | ||
400 | +- (void)timeEventStartWithCollectionURL:(NSString *)collectionURL | ||
401 | +{ | ||
402 | + NSNumber *startTime = @([[NSDate date] timeIntervalSince1970]); | ||
403 | + NSString *viewId = [NSString stringWithFormat:@"%@",collectionURL]; | ||
404 | + NSLog(@"startTime = %f",[[NSDate date] timeIntervalSince1970]); | ||
405 | + | ||
406 | + if (startTime==0||IsStrEmpty(viewId)) { | ||
407 | + return; | ||
408 | + } | ||
409 | + | ||
410 | + if (!collectionURL) { | ||
411 | + return; | ||
412 | + } | ||
413 | + | ||
414 | + dispatch_async(self.serialQueue, ^{ | ||
415 | + self.timedEvents[viewId] = startTime; | ||
416 | + }); | ||
417 | +} | ||
418 | + | ||
419 | +- (void)timeEventEndWithCollectionURL:(NSString *)collectionURL status:(YHEventLoadStatus)status | ||
420 | +{ | ||
421 | + NSTimeInterval elapsedTime = [self eventElapsedTime:collectionURL]; | ||
422 | + | ||
423 | + if (elapsedTime==0) { | ||
424 | + return; | ||
425 | + } | ||
426 | + if (!IsStrEmpty(collectionURL)) { | ||
427 | + dispatch_async(self.serialQueue, ^{ | ||
428 | + [self.timedEvents removeObjectForKey:collectionURL]; | ||
429 | + }); | ||
430 | + } | ||
431 | + | ||
432 | + NSDictionary *param = [YH_EventDataFactory factoryTimeEventDataWithHttp:collectionURL ElapsedTime:elapsedTime]; | ||
433 | + | ||
434 | + NSLog(@"%@",param); | ||
435 | + if (param) { | ||
436 | + [[YH_EventCacheManager sharedInstance] pushPerformanceData:param pointName:YHPN_HTTP]; | ||
437 | + } | ||
438 | +} | ||
439 | + | ||
440 | + | ||
441 | +- (void)timeEventStartWithSession:(NSURLSessionTask*)sessionTask | ||
442 | +{ | ||
443 | + NSNumber *startTime = @([[NSDate date] timeIntervalSince1970]); | ||
444 | + NSString *viewId = [NSString stringWithFormat:@"%@%@",NSStringFromClass([sessionTask class]),startTime]; | ||
445 | + NSLog(@"startTime = %f",[[NSDate date] timeIntervalSince1970]); | ||
446 | + | ||
447 | + if (startTime==0||IsStrEmpty(viewId)) { | ||
448 | + return; | ||
449 | + } | ||
450 | + | ||
451 | + if (!sessionTask) { | ||
452 | + return; | ||
453 | + } | ||
454 | + | ||
455 | + sessionTask.yh_viewId=viewId; | ||
456 | + dispatch_async(self.serialQueue, ^{ | ||
457 | + self.timedEvents[viewId] = startTime; | ||
458 | + }); | ||
459 | +} | ||
460 | + | ||
461 | +- (void)timeEventEndWithSessionTask:(NSURLSessionTask *)sessionTask status:(YHEventLoadStatus)status | ||
462 | +{ | ||
463 | + NSTimeInterval elapsedTime = [self eventElapsedTime:sessionTask.yh_viewId]; | ||
464 | + | ||
465 | + if (elapsedTime==0) { | ||
466 | + return; | ||
467 | + } | ||
468 | + if (!IsStrEmpty(sessionTask.yh_viewId)) { | ||
469 | + dispatch_async(self.serialQueue, ^{ | ||
470 | + [self.timedEvents removeObjectForKey:sessionTask.yh_viewId]; | ||
471 | + }); | ||
472 | + } | ||
473 | + | ||
474 | + NSDictionary *param = [YH_EventDataFactory factoryTimeEventDataWithHttp:sessionTask ElapsedTime:elapsedTime]; | ||
475 | + | ||
476 | + NSLog(@"%@",param); | ||
477 | + if (param) { | ||
478 | + [[YH_EventCacheManager sharedInstance] pushPerformanceData:param pointName:YHPN_HTTP]; | ||
479 | + } | ||
480 | +} | ||
481 | + | ||
397 | @end | 482 | @end |
398 | 483 | ||
399 | 484 |
@@ -93,6 +93,7 @@ typedef NS_ENUM(NSInteger, YHEventReportPointName) { | @@ -93,6 +93,7 @@ typedef NS_ENUM(NSInteger, YHEventReportPointName) { | ||
93 | YHPN_WEBVIEW,//UIWebView 加载时间 // @"WEBVIEW" | 93 | YHPN_WEBVIEW,//UIWebView 加载时间 // @"WEBVIEW" |
94 | YHPN_IMAGEVIEW,//Image (SDWebImage) 加载时间 // @"IMAGE" | 94 | YHPN_IMAGEVIEW,//Image (SDWebImage) 加载时间 // @"IMAGE" |
95 | YHPN_BUTTON,//Button 响应时间 // @"BUTTON" | 95 | YHPN_BUTTON,//Button 响应时间 // @"BUTTON" |
96 | + | ||
96 | YHPN_TIMEOUT, //网络事件 -网络超时 | 97 | YHPN_TIMEOUT, //网络事件 -网络超时 |
97 | YHPN_CODE_ERR , //网络事件- 有错误码返回的错误 | 98 | YHPN_CODE_ERR , //网络事件- 有错误码返回的错误 |
98 | YHPN_H5_FEATURE_META_FAILED, //feature.yoho.cn的H5页面meta校验失败 | 99 | YHPN_H5_FEATURE_META_FAILED, //feature.yoho.cn的H5页面meta校验失败 |
@@ -118,7 +119,10 @@ typedef NS_ENUM(NSInteger, YHEventReportPointName) { | @@ -118,7 +119,10 @@ typedef NS_ENUM(NSInteger, YHEventReportPointName) { | ||
118 | YHPN_BUSINESS_ORDER_ACCOUNT,//结算订单相关业务错误 | 119 | YHPN_BUSINESS_ORDER_ACCOUNT,//结算订单相关业务错误 |
119 | YHPN_BUSINESS_ORDER_CONFIRM,//确认订单相关业务错误 | 120 | YHPN_BUSINESS_ORDER_CONFIRM,//确认订单相关业务错误 |
120 | YHPN_BUSINESS_ORDER_PAY,//支付相关业务错误 | 121 | YHPN_BUSINESS_ORDER_PAY,//支付相关业务错误 |
121 | - YHPN_GESTURERECOGNIZER //UITapGestureRecognizer响应时间// @"GESTURERECOGNIZER" | 122 | + |
123 | + YHPN_GESTURERECOGNIZER, //UITapGestureRecognizer响应时间// @"GESTURERECOGNIZER" | ||
124 | + YHPN_HTTP //HTTP响应时间// @"HTTP" | ||
125 | + | ||
122 | }; | 126 | }; |
123 | 127 | ||
124 | typedef NS_ENUM(NSInteger, YHEventReportType) { | 128 | typedef NS_ENUM(NSInteger, YHEventReportType) { |
@@ -79,6 +79,15 @@ | @@ -79,6 +79,15 @@ | ||
79 | return dict; | 79 | return dict; |
80 | } | 80 | } |
81 | 81 | ||
82 | + | ||
83 | ++(NSDictionary *)factoryTimeEventDataWithHttp:(NSString*)url ElapsedTime:(NSTimeInterval)elapsedTime { | ||
84 | + | ||
85 | + NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:[url er_encodedString],kYHEventReportTimeURL,[NSString stringWithFormat:@"%.0f",elapsedTime*1000],kYHEventReportTimeElapsed,@"",kYHEventReportTimeTitle,nil]; | ||
86 | + | ||
87 | + return dict; | ||
88 | +} | ||
89 | + | ||
90 | + | ||
82 | + (NSDictionary *)factoryEventAppInfo:(YH_PerformanceAppInfo*)appInfo | 91 | + (NSDictionary *)factoryEventAppInfo:(YH_PerformanceAppInfo*)appInfo |
83 | { | 92 | { |
84 | if (IsNilOrNull(appInfo)) { | 93 | if (IsNilOrNull(appInfo)) { |
-
Please register or login to post a comment