Skip to content

Commit 92e38c2

Browse files
authoredFeb 9, 2023
fix(iOS): concurrent inputStream callback falied (#1105)
1 parent 14b2461 commit 92e38c2

File tree

1 file changed

+77
-38
lines changed

1 file changed

+77
-38
lines changed
 

‎iOS/DoraemonKit/Src/Core/Plugin/Performance/NetFlow/Function/DoraemonNetFlowManager.m

+77-38
Original file line numberDiff line numberDiff line change
@@ -12,53 +12,39 @@
1212
#import "DoraemonNetworkInterceptor.h"
1313
#import "UIViewController+Doraemon.h"
1414
#import "DoraemonHealthManager.h"
15+
#import <objc/runtime.h>
1516

16-
@interface DoraemonNetFlowManager() <DoraemonNetworkInterceptorDelegate, NSStreamDelegate>
17-
18-
@property (nonatomic, copy) HttpBodyCallBack bodyCallBack;
19-
@property (nonatomic, strong) NSMutableData *bodyData;
17+
@interface NSInputStream (DoraemonHttpBodyCallBack)
2018

19+
@property (nonatomic, strong) id<NSStreamDelegate> dkStrongDelegate;
2120
@end
2221

23-
@implementation DoraemonNetFlowManager
22+
@implementation NSInputStream (DoraemonHttpBodyCallBack)
2423

25-
+ (DoraemonNetFlowManager *)shareInstance{
26-
static dispatch_once_t once;
27-
static DoraemonNetFlowManager *instance;
28-
dispatch_once(&once, ^{
29-
instance = [[DoraemonNetFlowManager alloc] init];
30-
});
31-
return instance;
24+
- (void)setDkStrongDelegate:(id<NSStreamDelegate>)dkStrongDelegate {
25+
objc_setAssociatedObject(self, @selector(dkStrongDelegate), dkStrongDelegate, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
3226
}
3327

34-
- (void)canInterceptNetFlow:(BOOL)enable{
35-
_canIntercept = enable;
36-
if (enable) {
37-
[[DoraemonNetworkInterceptor shareInstance] addDelegate:self];
38-
_startInterceptDate = [NSDate date];
39-
}else{
40-
[DoraemonNetworkInterceptor.shareInstance removeDelegate:self];
41-
_startInterceptDate = nil;
42-
[[DoraemonNetFlowDataSource shareInstance] clear];
43-
}
28+
- (id<NSStreamDelegate>)dkStrongDelegate {
29+
return objc_getAssociatedObject(self, _cmd);
4430
}
31+
@end
4532

46-
- (void)httpBodyFromRequest:(NSURLRequest *)request bodyCallBack:(HttpBodyCallBack)complete {
47-
NSData *httpBody = nil;
48-
if (request.HTTPBody) {
49-
httpBody = request.HTTPBody;
50-
complete(httpBody);
51-
return;
52-
}
53-
if ([request.HTTPMethod isEqualToString:@"POST"]) {
54-
NSInputStream *stream = request.HTTPBodyStream;
55-
[stream setDelegate:self];
56-
self.bodyCallBack = complete;
57-
[stream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
58-
[stream open];
59-
} else {
60-
complete(httpBody);
33+
@interface DoraemonInputStreamDelegate : NSObject<NSStreamDelegate>
34+
35+
@property (nonatomic, strong) NSMutableData *bodyData;
36+
@property (nonatomic, copy) HttpBodyCallBack bodyCallBack;
37+
@end
38+
39+
@implementation DoraemonInputStreamDelegate
40+
- (instancetype)initWithCallback:(HttpBodyCallBack)callback inputStream:(NSInputStream *)inputStream{
41+
self = [super init];
42+
if(self){
43+
_bodyCallBack = callback;
44+
inputStream.dkStrongDelegate = self;//keep alive
45+
inputStream.delegate = self;
6146
}
47+
return self;
6248
}
6349

6450
#pragma mark -- NSStreamDelegate
@@ -89,7 +75,6 @@ - (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode {
8975
{
9076
[aStream close];
9177
[aStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
92-
aStream = nil;
9378
if (self.bodyCallBack) {
9479
self.bodyCallBack([self.bodyData copy]);
9580
}
@@ -101,6 +86,60 @@ - (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode {
10186
}
10287
}
10388

89+
90+
@end
91+
92+
93+
94+
95+
@interface DoraemonNetFlowManager() <DoraemonNetworkInterceptorDelegate>
96+
97+
98+
@property (nonatomic, strong) NSMapTable *bodyCallBackMap;
99+
100+
@end
101+
102+
@implementation DoraemonNetFlowManager
103+
104+
+ (DoraemonNetFlowManager *)shareInstance{
105+
static dispatch_once_t once;
106+
static DoraemonNetFlowManager *instance;
107+
dispatch_once(&once, ^{
108+
instance = [[DoraemonNetFlowManager alloc] init];
109+
instance.bodyCallBackMap = [NSMapTable mapTableWithKeyOptions:NSPointerFunctionsWeakMemory valueOptions:NSPointerFunctionsStrongMemory];
110+
});
111+
return instance;
112+
}
113+
114+
- (void)canInterceptNetFlow:(BOOL)enable{
115+
_canIntercept = enable;
116+
if (enable) {
117+
[[DoraemonNetworkInterceptor shareInstance] addDelegate:self];
118+
_startInterceptDate = [NSDate date];
119+
}else{
120+
[DoraemonNetworkInterceptor.shareInstance removeDelegate:self];
121+
_startInterceptDate = nil;
122+
[[DoraemonNetFlowDataSource shareInstance] clear];
123+
}
124+
}
125+
126+
- (void)httpBodyFromRequest:(NSURLRequest *)request bodyCallBack:(HttpBodyCallBack)complete {
127+
NSData *httpBody = nil;
128+
if (request.HTTPBody) {
129+
httpBody = request.HTTPBody;
130+
complete(httpBody);
131+
return;
132+
}
133+
if ([request.HTTPMethod isEqualToString:@"POST"]) {
134+
NSInputStream *stream = request.HTTPBodyStream;
135+
DoraemonInputStreamDelegate *delegate = [[DoraemonInputStreamDelegate alloc] initWithCallback:complete inputStream:stream];
136+
[stream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
137+
[stream open];
138+
} else {
139+
complete(httpBody);
140+
}
141+
}
142+
104143
#pragma mark -- DoraemonNetworkInterceptorDelegate
105144
- (void)doraemonNetworkInterceptorDidReceiveData:(NSData *)data response:(NSURLResponse *)response request:(NSURLRequest *)request error:(NSError *)error startTime:(NSTimeInterval)startTime {
106145
[DoraemonNetFlowHttpModel dealWithResponseData:data response:response request:request complete:^(DoraemonNetFlowHttpModel *httpModel) {

0 commit comments

Comments
 (0)