Skip to content

Commit

Permalink
Merge pull request #28 from didi/dev-instruction-opt
Browse files Browse the repository at this point in the history
iOS端指令优化及代码重构。
  • Loading branch information
ronghaopger authored Jul 14, 2021
2 parents e8126f1 + 145569b commit b169adc
Show file tree
Hide file tree
Showing 71 changed files with 1,425 additions and 669 deletions.
1 change: 1 addition & 0 deletions DiDiPrism.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ Pod::Spec.new do |spec|

spec.subspec 'Core' do |ss|
ss.source_files = ['iOS/DiDiPrism/Src/Core/**/*{.h,.m}', 'iOS/DiDiPrism/Src/Category/**/*{.h,.m}', 'iOS/DiDiPrism/Src/Util/**/*{.h,.m}', 'iOS/DiDiPrism/Src/Protocol/**/*{.h,.m}']
ss.dependency 'RSSwizzle'
end

spec.subspec 'WithBehaviorRecord' do |ss|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,8 @@ - (instancetype)init {
return self;
}

- (BOOL)canDetect {
return YES;
}

#pragma mark - public method
- (void)setupWithConfigModel:(PrismBehaviorDetectRuleConfigModel*)configModel {
if ([self canDetect] == NO) {
return;
}
if (!configModel) {
return;
}
Expand All @@ -57,7 +50,7 @@ - (void)addInstruction:(NSString*)instruction withParams:(NSDictionary*)params {
if (!instruction.length) {
return;
}
if (!self.ruleConfigModel || [self canDetect] == NO) {
if (!self.ruleConfigModel) {
return;
}
NSMutableDictionary *newParams = [NSMutableDictionary dictionaryWithDictionary:params];
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@
NS_ASSUME_NONNULL_BEGIN

@interface PrismRecordNSURLProtocol : NSURLProtocol

/*
定制用于提取网络请求信息的逻辑。
*/
@property (nonatomic, strong, class) NSString*(^urlFlagPickBlock)(NSURLRequest*);
@property (nonatomic, strong, class) NSString*(^traceIdPickBlock)(NSURLRequest*);
@end

NS_ASSUME_NONNULL_END
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@
//

#import "PrismRecordNSURLProtocol.h"
#import <objc/runtime.h>
#import "PrismBehaviorRecordManager.h"
// Category
#import "NSDictionary+PrismExtends.h"

@interface PrismRecordNSURLProtocol() <NSURLSessionDelegate>
@property (nonatomic, strong) NSURLSession *session;
Expand All @@ -22,15 +25,12 @@ + (BOOL)canInitWithTask:(NSURLSessionTask *)task {
}

+ (BOOL)canInitWithRequest:(NSURLRequest *)request {
if ([[PrismBehaviorRecordManager sharedManager] canUpload] == NO) {
return NO;
}
if (![request.URL.scheme isEqualToString:@"http"]
&& ![request.URL.scheme isEqualToString:@"https"]) {
return NO;
}
NSString *urlFlag = [PrismBehaviorRecordManager sharedManager].urlFlagPickBlock ? [PrismBehaviorRecordManager sharedManager].urlFlagPickBlock(request) : nil;
NSString *traceId = [PrismBehaviorRecordManager sharedManager].traceIdPickBlock ? [PrismBehaviorRecordManager sharedManager].traceIdPickBlock(request) : nil;
NSString *urlFlag = self.urlFlagPickBlock ? self.urlFlagPickBlock(request) : nil;
NSString *traceId = self.traceIdPickBlock ? self.traceIdPickBlock(request) : nil;
[[PrismBehaviorRecordManager sharedManager] addRequestInfoWithUrl:urlFlag traceId:traceId];

return NO;
Expand All @@ -39,7 +39,37 @@ + (BOOL)canInitWithRequest:(NSURLRequest *)request {
#pragma mark - delegate

#pragma mark - setters
+ (void)setUrlFlagPickBlock:(NSString * _Nonnull (^)(NSURLRequest * _Nonnull))urlFlagPickBlock {
objc_setAssociatedObject(self, @selector(urlFlagPickBlock), urlFlagPickBlock, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

+ (void)setTraceIdPickBlock:(NSString * _Nonnull (^)(NSURLRequest * _Nonnull))traceIdPickBlock {
objc_setAssociatedObject(self, @selector(traceIdPickBlock), traceIdPickBlock, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

#pragma mark - getters
+ (NSString * _Nonnull (^)(NSURLRequest * _Nonnull))urlFlagPickBlock {
id result = objc_getAssociatedObject(self, _cmd);
if (!result) {
result = ^(NSURLRequest* request) {
return [NSString stringWithFormat:@"%@%@", request.URL.host, request.URL.path];
};
objc_setAssociatedObject(self, @selector(urlFlagPickBlock), result, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
return result;
}

+ (NSString * _Nonnull (^)(NSURLRequest * _Nonnull))traceIdPickBlock {
id result = objc_getAssociatedObject(self, _cmd);
if (!result) {
result = ^(NSURLRequest* request) {
NSDictionary *header = request.allHTTPHeaderFields;
NSString *traceIdKey = @"traceid";
return [header prism_stringForKey:traceIdKey];
};
objc_setAssociatedObject(self, @selector(traceIdPickBlock), result, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
return result;
}

@end
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#import "PrismBehaviorRecordManager+PrismDispatchListenerProtocol.h"
#import "PrismInstructionParamUtil.h"
#import "PrismInstructionDefines.h"
// Category
#import "NSDictionary+PrismExtends.h"
#import "UIView+PrismExtends.h"
Expand All @@ -17,23 +18,31 @@
#import "PrismControlInstructionGenerator.h"
#import "PrismEdgePanInstructionGenerator.h"
#import "PrismTapGestureInstructionGenerator.h"
#import "PrismLongPressGestureInstructionGenerator.h"
#import "PrismCellInstructionGenerator.h"
#import "PrismViewControllerInstructionGenerator.h"

@implementation PrismBehaviorRecordManager (PrismDispatchListenerProtocol)
#pragma mark -delegate
#pragma mark PrismDispatchListenerProtocol
- (void)dispatchEvent:(PrismDispatchEvent)event withSender:(NSObject *)sender params:(NSDictionary *)params {
if (![self canUpload]) {
return;
}
if (event == PrismDispatchEventUIControlSendAction_Start) {
UIControl *control = (UIControl*)sender;
NSObject *target = [params objectForKey:@"target"];
NSString *action = [params objectForKey:@"action"];
NSString *targetAndSelector = [NSString stringWithFormat:@"%@_&_%@", NSStringFromClass([target class]), action];
if ([targetAndSelector isEqualToString:control.autoDotTargetAndSelector]) {
NSString *instruction = [PrismControlInstructionGenerator getInstructionOfControl:control];
NSDictionary<NSString*,NSString*> *prismAutoDotTargetAndSelector = [control.prismAutoDotTargetAndSelector copy];
if ([[prismAutoDotTargetAndSelector allValues] containsObject:targetAndSelector]) {
NSMutableString *controlEvents = [NSMutableString string];
for (NSString *key in [prismAutoDotTargetAndSelector allKeys]) {
if ([prismAutoDotTargetAndSelector[key] isEqualToString:targetAndSelector]) {
if (controlEvents.length) {
[controlEvents appendString:@"_&_"];
}
[controlEvents appendString:key];
}
}
NSString *instruction = [PrismControlInstructionGenerator getInstructionOfControl:control withTargetAndSelector:targetAndSelector withControlEvents:[controlEvents copy]];
if (instruction.length) {
NSDictionary *eventParams = [PrismInstructionParamUtil getEventParamsWithElement:control];
[self addInstruction:instruction withEventParams:eventParams];
Expand All @@ -48,9 +57,9 @@ - (void)dispatchEvent:(PrismDispatchEvent)event withSender:(NSObject *)sender pa
if (edgePanGestureRecognizer.state == UIGestureRecognizerStateBegan) {
UIViewController *viewController = [edgePanGestureRecognizer.view prism_viewController];
UINavigationController *navigationController = [viewController isKindOfClass:[UINavigationController class]] ? (UINavigationController*)viewController : viewController.navigationController;
[edgePanGestureRecognizer setAutoDotNavigationController:navigationController];
[edgePanGestureRecognizer setPrismAutoDotNavigationController:navigationController];
NSInteger viewControllerCount = navigationController.viewControllers.count;
[edgePanGestureRecognizer setAutoDotViewControllerCount:[NSNumber numberWithInteger:viewControllerCount]];
[edgePanGestureRecognizer setPrismAutoDotViewControllerCount:[NSNumber numberWithInteger:viewControllerCount]];
}
// 输入后退手势时,如果手指始终未离开屏幕,state会变为UIGestureRecognizerStateCancelled
if (edgePanGestureRecognizer.state != UIGestureRecognizerStateEnded &&
Expand All @@ -63,9 +72,9 @@ - (void)dispatchEvent:(PrismDispatchEvent)event withSender:(NSObject *)sender pa
return;
}
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
UINavigationController *navigationController = [edgePanGestureRecognizer autoDotNavigationController];
UINavigationController *navigationController = [edgePanGestureRecognizer prismAutoDotNavigationController];
NSInteger viewControllerCount = navigationController.viewControllers.count;
if (navigationController && (viewControllerCount <= [edgePanGestureRecognizer autoDotViewControllerCount].integerValue)) {
if (navigationController && (viewControllerCount <= [edgePanGestureRecognizer prismAutoDotViewControllerCount].integerValue)) {
[self addInstruction:instruction];
}
});
Expand All @@ -78,6 +87,14 @@ - (void)dispatchEvent:(PrismDispatchEvent)event withSender:(NSObject *)sender pa
[self addInstruction:instruction withEventParams:eventParams];
}
}
else if (event == PrismDispatchEventUILongPressGestureRecognizerAction) {
UILongPressGestureRecognizer *longPressGesture = (UILongPressGestureRecognizer*)sender;
NSString *instruction = [PrismLongPressGestureInstructionGenerator getInstructionOfLongPressGesture:longPressGesture];
if (instruction.length) {
NSDictionary *eventParams = [PrismInstructionParamUtil getEventParamsWithElement:longPressGesture.view];
[self addInstruction:instruction withEventParams:eventParams];
}
}
else if (event == PrismDispatchEventUIViewTouchesEnded_End) {
UIView *view = (UIView*)sender;
if ([view isKindOfClass:[UITableViewCell class]] || [view isKindOfClass:[UICollectionViewCell class]]) {
Expand All @@ -94,17 +111,25 @@ - (void)dispatchEvent:(PrismDispatchEvent)event withSender:(NSObject *)sender pa
[self addInstruction:instruction];
}
else if (event == PrismDispatchEventWKWebViewInitWithFrame) {
if (![self canH5Upload]) {
return;
}
WKWebView *webView = (WKWebView*)sender;
WKWebViewConfiguration *configuration = [params objectForKey:@"configuration"];
NSString *recordScript = @"!function(){\"use strict\";var e=new(function(){function e(){}return e.prototype.record=function(e){for(var t=this.getContent(e),r=[];e&&\"body\"!==e.nodeName.toLowerCase();){var n=e.nodeName.toLowerCase();if(e.id)n+=\"#\"+e.id;else{for(var i=e,o=1;i.previousElementSibling;)i=i.previousElementSibling,o+=1;o>1&&(n+=\":nth-child(\"+o+\")\")}r.unshift(n),e=e.parentElement}return r.unshift(\"body\"),{instruct:r.join(\">\"),content:t}},e.prototype.getContent=function(e){return e.innerText?this.getText(e):e.getAttribute(\"src\")?e.getAttribute(\"src\"):e.querySelectorAll(\"img\")&&e.querySelectorAll(\"img\").length>0?this.getImgSrc(e):\"\"},e.prototype.getText=function(e){if(!(e.childNodes&&e.childNodes.length>0))return e.innerText||e.nodeValue;for(var t=0;t<e.childNodes.length;t++)if(e.childNodes[t].childNodes){var r=this.getText(e.childNodes[t]);if(r)return r}},e.prototype.getImgSrc=function(e){var t=e.querySelectorAll(\"img\");return t&&t[0]&&t[0].src},e}());document.addEventListener(\"click\",(function(t){if(t.target)try{window.webkit.messageHandlers.prism_record_instruct&&window.webkit.messageHandlers.prism_record_instruct.postMessage(e.record(t.target))}catch(e){}}))}();";

[webView autoDot_addCustomScript:recordScript withConfiguration:configuration];
[webView prism_autoDot_addCustomScript:recordScript withConfiguration:configuration];
NSString *scriptName = @"prism_record_instruct";
[webView.configuration.userContentController removeScriptMessageHandlerForName:scriptName];
[webView.configuration.userContentController addScriptMessageHandler:self name:scriptName];
}
else if (event == PrismDispatchEventUIApplicationLaunchByURL) {
NSString *openUrl = [params objectForKey:@"openUrl"];
NSString *instruction = [NSString stringWithFormat:@"%@%@%@", kUIApplicationOpenURL, kBeginOfViewRepresentativeContentFlag, openUrl ?: @""];
[self addInstruction:instruction];
}
else if (event == PrismDispatchEventUIApplicationDidBecomeActive) {
[self addInstruction:kUIApplicationBecomeActive];
}
else if (event == PrismDispatchEventUIApplicationWillResignActive) {
[self addInstruction:kUIApplicationResignActive];
}
}
@end
Original file line number Diff line number Diff line change
Expand Up @@ -13,31 +13,12 @@ NS_ASSUME_NONNULL_BEGIN
@interface PrismBehaviorRecordManager : NSObject <WKScriptMessageHandler>
+ (instancetype)sharedManager;

/*
定制用于提取网络请求信息的逻辑。
*/
@property (nonatomic, strong) NSString*(^urlFlagPickBlock)(NSURLRequest*);
@property (nonatomic, strong) NSString*(^traceIdPickBlock)(NSURLRequest*);

/*
初始化
*/
- (void)install;
- (void)uninstall;

/*
是否可以Hook。
*/
- (BOOL)canHook;
/*
是否可以上报指令。
*/
- (BOOL)canUpload;
/*
是否可以上报H5页面指令。
*/
- (BOOL)canH5Upload;

- (void)addInstruction:(NSString*)instruction;
- (void)addInstruction:(NSString*)instruction withEventParams:(NSDictionary*)eventParams;
- (void)addRequestInfoWithUrl:(NSString*)url traceId:(NSString*)traceId;
Expand Down
Loading

0 comments on commit b169adc

Please sign in to comment.