Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
DiDi
DoraemonKit
提交
49a3af6f
D
DoraemonKit
项目概览
DiDi
/
DoraemonKit
12 个月 前同步成功
通知
166
Star
19623
Fork
3062
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
DoraemonKit
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
49a3af6f
编写于
2月 09, 2021
作者:
W
Wizz.Xu
提交者:
GitHub
2月 09, 2021
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #3 from didi/master
update
上级
d551ce83
e9859859
变更
37
隐藏空白更改
内联
并排
Showing
37 changed file
with
493 addition
and
187 deletion
+493
-187
.github/ISSUE_TEMPLATE/-dokit-------------.md
.github/ISSUE_TEMPLATE/-dokit-------------.md
+27
-0
Doc/iOS-ReleaseNotes.md
Doc/iOS-ReleaseNotes.md
+5
-2
DoraemonKit.podspec
DoraemonKit.podspec
+1
-1
Flutter/CHANGELOG.md
Flutter/CHANGELOG.md
+6
-0
Flutter/README.md
Flutter/README.md
+1
-4
Flutter/lib/dokit.dart
Flutter/lib/dokit.dart
+1
-1
Flutter/lib/engine/dokit_binding.dart
Flutter/lib/engine/dokit_binding.dart
+4
-0
Flutter/lib/engine/dokit_http.dart
Flutter/lib/engine/dokit_http.dart
+31
-16
Flutter/lib/kit/apm/http_kit.dart
Flutter/lib/kit/apm/http_kit.dart
+14
-1
Flutter/lib/kit/apm/log_kit.dart
Flutter/lib/kit/apm/log_kit.dart
+65
-4
Flutter/lib/kit/apm/method_channel_kit.dart
Flutter/lib/kit/apm/method_channel_kit.dart
+15
-4
Flutter/lib/kit/apm/route_kit.dart
Flutter/lib/kit/apm/route_kit.dart
+2
-2
Flutter/lib/kit/common/basic_info.dart
Flutter/lib/kit/common/basic_info.dart
+13
-12
Flutter/lib/kit/visual/view_check.dart
Flutter/lib/kit/visual/view_check.dart
+3
-3
Flutter/lib/ui/dokit_app.dart
Flutter/lib/ui/dokit_app.dart
+122
-3
Flutter/lib/ui/dokit_btn.dart
Flutter/lib/ui/dokit_btn.dart
+2
-2
Flutter/lib/ui/resident_page.dart
Flutter/lib/ui/resident_page.dart
+5
-1
Flutter/pubspec.yaml
Flutter/pubspec.yaml
+1
-1
README.md
README.md
+4
-3
iOS/DoraemonKit/Resource/Assets.xcassets/doraemon_health_bg.imageset/doraemon_health_bg@2x.png
...ets/doraemon_health_bg.imageset/doraemon_health_bg@2x.png
+0
-0
iOS/DoraemonKit/Resource/Assets.xcassets/doraemon_health_bg.imageset/doraemon_health_bg@3x.png
...ets/doraemon_health_bg.imageset/doraemon_health_bg@3x.png
+0
-0
iOS/DoraemonKit/Src/Core/Category/UIImage+Doraemon.m
iOS/DoraemonKit/Src/Core/Category/UIImage+Doraemon.m
+2
-4
iOS/DoraemonKit/Src/Core/Network/Interceptor/DoraemonNSURLProtocol.m
...nKit/Src/Core/Network/Interceptor/DoraemonNSURLProtocol.m
+13
-11
iOS/DoraemonKit/Src/Core/Plugin/Performance/NetFlow/Function/DoraemonNetFlowHttpModel.h
...n/Performance/NetFlow/Function/DoraemonNetFlowHttpModel.h
+1
-1
iOS/DoraemonKit/Src/Core/Plugin/Performance/NetFlow/Function/DoraemonNetFlowHttpModel.m
...n/Performance/NetFlow/Function/DoraemonNetFlowHttpModel.m
+8
-13
iOS/DoraemonKit/Src/Core/Plugin/Performance/NetFlow/Function/DoraemonNetFlowManager.h
...gin/Performance/NetFlow/Function/DoraemonNetFlowManager.h
+4
-0
iOS/DoraemonKit/Src/Core/Plugin/Performance/NetFlow/Function/DoraemonNetFlowManager.m
...gin/Performance/NetFlow/Function/DoraemonNetFlowManager.m
+74
-13
iOS/DoraemonKit/Src/Core/Plugin/Performance/NetFlow/Function/Util/DoraemonUrlUtil.h
...lugin/Performance/NetFlow/Function/Util/DoraemonUrlUtil.h
+3
-3
iOS/DoraemonKit/Src/Core/Plugin/Performance/NetFlow/Function/Util/DoraemonUrlUtil.m
...lugin/Performance/NetFlow/Function/Util/DoraemonUrlUtil.m
+11
-30
iOS/DoraemonKit/Src/Core/Plugin/Performance/WeakNetwork/Function/DoraemonWeakNetworkManager.m
...ormance/WeakNetwork/Function/DoraemonWeakNetworkManager.m
+3
-1
iOS/DoraemonKit/Src/Core/Plugin/Platform/Mock/Function/DoraemonMockManager.m
.../Core/Plugin/Platform/Mock/Function/DoraemonMockManager.m
+2
-1
iOS/DoraemonKitDemo/DoraemonKitDemo/DemoVC/Net/ NSURLProtocol/DoraemonDemoURLProtocol1.m
...Demo/DemoVC/Net/ NSURLProtocol/DoraemonDemoURLProtocol1.m
+6
-4
iOS/DoraemonKitDemo/DoraemonKitDemo/DemoVC/Net/ NSURLProtocol/DoraemonDemoURLProtocol2.m
...Demo/DemoVC/Net/ NSURLProtocol/DoraemonDemoURLProtocol2.m
+6
-4
iOS/DoraemonKitDemo/DoraemonKitDemo/DemoVC/Net/DoraemonDemoNetViewController.m
...oraemonKitDemo/DemoVC/Net/DoraemonDemoNetViewController.m
+6
-5
iOS/DoraemonKitDemo/DoraemonKitDemo/DemoVC/Performance/DoraemonDemoPerformanceViewController.m
...emoVC/Performance/DoraemonDemoPerformanceViewController.m
+4
-3
iOS/DoraemonKitDemo/Podfile
iOS/DoraemonKitDemo/Podfile
+1
-1
iOS/DoraemonKitDemo/Podfile.lock
iOS/DoraemonKitDemo/Podfile.lock
+27
-33
未找到文件。
.github/ISSUE_TEMPLATE/-dokit-------------.md
0 → 100644
浏览文件 @
49a3af6f
---
name
:
"
【DoKit生态场景】-描述出现的问题"
about
:
DoKit生态场景比如Android、iOS、小程序、Flutter,后面跟你需要描述的内容
title
:
"
【DoKit生态场景】-描述出现的问题"
labels
:
'
'
assignees
:
jtsky
---
It is recommended to refer to the following process before submitting issues:https://github.com/didi/DoraemonKit/issues/745
If you still cannot solve your problem, you can submit your issue according to the following template
Please complete the following informations.
> Android、iOS? OS version? Brand?
> Expected behavior and actual behavior.
> Steps to reproduce the problem.
> More informations such as error messages and stack traces are welcomed.
>
建议提issues之前可以参考一下DoKit社区答疑流程:https://github.com/didi/DoraemonKit/issues/745
假如还是无法解决你的问题,你可以按照以下模板来提交你的issue
请补充如下信息。
> Android 还是 iOS?系统版本是多少?手机品牌是什么?(如有)
> 期望的表现和实际的表现。(如有)
> 问题重现的步骤。(如有)
> 其他的错误信息和堆栈信息如果有也可以一并提供出来。(如有)
Doc/iOS-ReleaseNotes.md
浏览文件 @
49a3af6f
# Release Notes
### 3.0.7
1、DoKit iOS github issues bug fixed
### 3.0.4
1、DoKit iOS端文件同步助手正式上线
### 3.0.2
1、支持每一个内置Kit,进行位置重排,添加删除某一个Kit
...
...
@@ -242,4 +245,4 @@
3、性能工具:帧率、CPU、内存、流量、自定义
4、视觉工具:颜色吸管、组件检查、对齐标尺
\ No newline at end of file
4、视觉工具:颜色吸管、组件检查、对齐标尺
DoraemonKit.podspec
浏览文件 @
49a3af6f
...
...
@@ -7,7 +7,7 @@
Pod
::
Spec
.
new
do
|
s
|
s
.
name
=
'DoraemonKit'
s
.
version
=
'3.0.
6
'
s
.
version
=
'3.0.
7
'
s
.
summary
=
'iOS各式各样的工具集合'
s
.
description
=
<<-
DESC
iOS各式各样的工具集合 Desc
...
...
Flutter/CHANGELOG.md
浏览文件 @
49a3af6f
## [0.2.12] - 修改页面层级,现在DoKitApp将以Stack存放用户传入的Widget,防止各种InheritedWidget影响到用户Widget
## [0.2.11] - 修复一些UI异常问题;日志模块增加错误信息过滤,防止被错误日志冲刷掉;
## [0.2.10] - 修复DoKitApp再某些case下获取高度为0的异常.
## [0.2.9] - 修改DoKitApp类型,自定义Overlay容器防止各种InheritedWidget使用异常.
## [0.2.8] - 修复网络请求返回结果乱码问题;增加method—channel耗时统计;日志/方法通道/网络请求增加清空按钮.
## [0.2.7] - 网络请求增加RequestHeaders信息展示,增加非文本类型的返回结果size展示.
## [0.2.6] - 日志功能优化与bug修复.
## [0.2.5] - 修改demo包名为example.
## [0.2.4] - 发布pub包去除demo.
...
...
Flutter/README.md
浏览文件 @
49a3af6f
...
...
@@ -5,9 +5,6 @@
## 支持flutter版本
1.
17.5<=version<=1.22.4,其余版本未做过兼容性测试
## 最新版本
**0.2.6**
## Pub地址
[
DoKit For Flutter
](
https://pub.dev/packages/dokit
)
...
...
@@ -16,7 +13,7 @@
```
dependencies:
dokit: ^0.2.
6
dokit: ^0.2.
12
```
在main函数入口初始化。 DoKit使用runZone的方式进行日志捕获,方法通道的捕获,如果你的app需要使用同样的方式会有冲突。
...
...
Flutter/lib/dokit.dart
浏览文件 @
49a3af6f
...
...
@@ -102,7 +102,7 @@ class DoKit {
}
static
void
dispose
({
@required
BuildContext
context
})
{
Overlay
.
of
(
context
)
.
widget
.
initialEntries
.
forEach
((
element
)
{
doKitOverlayKey
.
currentState
.
widget
.
initialEntries
.
forEach
((
element
)
{
// element.remove();
});
}
...
...
Flutter/lib/engine/dokit_binding.dart
浏览文件 @
49a3af6f
...
...
@@ -63,8 +63,12 @@ class DoKitBinaryMessenger extends BinaryMessenger {
if
(
info
!=
null
&&
result
!=
null
)
{
if
(
info
.
methodCodec
!=
null
)
{
info
.
results
=
info
.
methodCodec
.
decodeEnvelope
(
result
);
info
.
endTimestamp
=
new
DateTime
.
now
().
millisecondsSinceEpoch
;
}
else
if
(
info
.
messageCodec
!=
null
)
{
info
.
results
=
info
.
messageCodec
.
decodeMessage
(
result
);
info
.
endTimestamp
=
new
DateTime
.
now
().
millisecondsSinceEpoch
;
}
else
{
info
.
endTimestamp
=
new
DateTime
.
now
().
millisecondsSinceEpoch
;
}
}
}
catch
(
e
)
{}
...
...
Flutter/lib/engine/dokit_http.dart
浏览文件 @
49a3af6f
...
...
@@ -311,7 +311,7 @@ class DoKitHttpClientRequest implements HttpClientRequest {
Future
<
HttpClientResponse
>
monitor
(
Future
<
HttpClientResponse
>
future
)
async
{
HttpClientResponse
response
=
await
future
;
return
DoKitHttpClientResponse
(
response
,
recordResponse
,
encoding
);
return
DoKitHttpClientResponse
(
response
,
recordResponse
);
}
void
recordResponse
(
int
code
,
String
result
,
String
header
,
int
size
)
{
...
...
@@ -337,9 +337,8 @@ extension HttpClientRequestExt on HttpClientRequest {
class
DoKitHttpClientResponse
implements
HttpClientResponse
{
final
HttpClientResponse
origin
;
final
Function
(
int
,
String
,
String
,
int
)
recordResponse
;
final
Encoding
encoding
;
DoKitHttpClientResponse
(
this
.
origin
,
this
.
recordResponse
,
this
.
encoding
);
DoKitHttpClientResponse
(
this
.
origin
,
this
.
recordResponse
);
@override
Future
<
bool
>
any
(
bool
Function
(
List
<
int
>
element
)
test
)
{
...
...
@@ -483,6 +482,18 @@ class DoKitHttpClientResponse implements HttpClientResponse {
headers
[
'content-type'
].
toString
().
contains
(
'xml'
));
}
Encoding
getEncoding
()
{
var
charset
;
if
(
headers
!=
null
&&
headers
.
contentType
!=
null
&&
headers
.
contentType
.
charset
!=
null
)
{
charset
=
headers
.
contentType
.
charset
;
}
else
{
charset
=
"utf-8"
;
}
return
Encoding
.
getByName
(
charset
);
}
@override
StreamSubscription
<
List
<
int
>>
listen
(
void
Function
(
List
<
int
>
event
)
onData
,
{
Function
onError
,
void
Function
()
onDone
,
bool
cancelOnError
})
{
...
...
@@ -490,17 +501,20 @@ class DoKitHttpClientResponse implements HttpClientResponse {
onData
(
result
);
try
{
if
(
isTextResponse
())
{
if
(
encoding
!=
null
)
{
recordResponse
(
statusCode
,
encoding
.
decode
(
result
),
headers
?.
toString
(),
result
.
l
ength
);
if
(
getEncoding
()
!=
null
)
{
recordResponse
(
statusCode
,
getEncoding
()
.
decode
(
result
),
headers
?.
toString
(),
contentL
ength
);
}
else
{
recordResponse
(
statusCode
,
"返回结果解析失败"
,
headers
?.
toString
(),
0
);
recordResponse
(
statusCode
,
"返回结果解析失败"
,
headers
?.
toString
(),
contentLength
);
}
}
else
{
recordResponse
(
statusCode
,
"返回结果不支持解析"
,
headers
?.
toString
(),
0
);
recordResponse
(
statusCode
,
"返回结果不支持解析"
,
headers
?.
toString
(),
contentLength
);
}
}
catch
(
e
)
{
recordResponse
(
statusCode
,
"返回结果解析失败"
,
headers
?.
toString
(),
0
);
recordResponse
(
statusCode
,
"返回结果解析失败"
,
headers
?.
toString
(),
contentLength
);
}
}
...
...
@@ -595,21 +609,22 @@ class DoKitHttpClientResponse implements HttpClientResponse {
if
(
isTextResponse
())
{
if
(
event
is
Uint8List
)
{
Uint8List
result
=
event
;
if
(
encoding
!=
null
)
{
recordResponse
(
statusCode
,
encoding
.
decode
(
result
.
toList
()),
if
(
getEncoding
()
!=
null
)
{
recordResponse
(
statusCode
,
getEncoding
()
.
decode
(
result
.
toList
()),
headers
?.
toString
(),
event
.
length
);
}
else
{
recordResponse
(
statusCode
,
"返回结果解析失败"
,
headers
?.
toString
(),
0
);
recordResponse
(
statusCode
,
"返回结果解析失败"
,
headers
?.
toString
(),
contentLength
);
}
}
else
if
(
event
is
String
)
{
recordResponse
(
statusCode
,
event
,
headers
?.
toString
(),
event
.
codeUnits
.
length
);
recordResponse
(
statusCode
,
event
,
headers
?.
toString
(),
contentLength
);
}
else
{
recordResponse
(
statusCode
,
'unknown type:
${event.runtimeType}
'
,
headers
?.
toString
(),
0
);
headers
?.
toString
(),
contentLength
);
}
}
else
{
recordResponse
(
statusCode
,
"返回结果不支持解析"
,
headers
?.
toString
(),
0
);
recordResponse
(
statusCode
,
"返回结果不支持解析"
,
headers
?.
toString
(),
contentLength
);
}
});
return
s
;
...
...
Flutter/lib/kit/apm/http_kit.dart
浏览文件 @
49a3af6f
...
...
@@ -344,7 +344,20 @@ class _HttpItemWidgetState extends State<HttpItemWidget> {
height:
1.5
,
color:
Color
(
0xff666666
))),
TextSpan
(
text:
'
\n
Header: '
,
text:
'
\n
RequestHeader: '
,
style:
TextStyle
(
height:
1.5
,
fontSize:
10
,
color:
Color
(
0xff333333
),
fontWeight:
FontWeight
.
bold
)),
TextSpan
(
text:
'
${widget.item.request.header}
'
,
style:
TextStyle
(
fontSize:
10
,
height:
1.5
,
color:
Color
(
0xff666666
))),
TextSpan
(
text:
'
\n
ResponseHeader: '
,
style:
TextStyle
(
height:
1.5
,
fontSize:
10
,
...
...
Flutter/lib/kit/apm/log_kit.dart
浏览文件 @
49a3af6f
...
...
@@ -7,11 +7,16 @@ import 'package:dokit/util/util.dart';
import
'package:flutter/services.dart'
;
import
'package:shared_preferences/shared_preferences.dart'
;
import
'../../dokit.dart'
;
import
'apm.dart'
;
class
LogKit
extends
ApmKit
{
FlutterExceptionHandler
originOnError
;
CommonStorage
_error
=
new
CommonStorage
();
CommonStorage
get
error
=>
_error
;
@override
Widget
createDisplayPage
()
{
return
LogPage
();
...
...
@@ -32,6 +37,14 @@ class LogKit extends ApmKit {
return
'images/dk_log_info.png'
;
}
@override
bool
save
(
IInfo
info
)
{
if
((
info
as
LogBean
).
type
==
LogBean
.
TYPE_ERROR
)
{
_error
.
save
(
info
);
}
return
super
.
save
(
info
);
}
@override
void
start
()
{
resetOnErrorInstance
();
...
...
@@ -86,17 +99,26 @@ class LogManager {
?.
getAll
();
}
List
<
IInfo
>
getErrors
()
{
return
ApmKitManager
.
instance
.
getKit
<
LogKit
>(
ApmKitName
.
KIT_LOG
)
?.
error
?.
getAll
();
}
void
addLog
(
int
type
,
String
msg
)
{
if
(
ApmKitManager
.
instance
.
getKit
(
ApmKitName
.
KIT_LOG
)
!=
null
)
{
LogBean
log
=
new
LogBean
(
type
,
msg
);
LogKit
kit
=
ApmKitManager
.
instance
.
getKit
(
ApmKitName
.
KIT_LOG
);
kit
.
save
(
log
);
listener
?.
call
(
log
);
if
(
type
!=
LogBean
.
TYPE_ERROR
||
LogPageState
.
_showError
)
{
listener
?.
call
(
log
);
}
}
}
void
addException
(
String
exception
)
{
addLog
(
LogBean
.
TYPE_E
XCEPTION
,
exception
);
addLog
(
LogBean
.
TYPE_E
RROR
,
exception
);
}
}
...
...
@@ -106,7 +128,6 @@ class LogBean implements IInfo {
static
const
int
TYPE_INFO
=
3
;
static
const
int
TYPE_WARN
=
4
;
static
const
int
TYPE_ERROR
=
5
;
static
const
int
TYPE_EXCEPTION
=
6
;
final
int
type
;
final
String
msg
;
...
...
@@ -134,6 +155,8 @@ class LogPage extends StatefulWidget {
class
LogPageState
extends
State
<
LogPage
>
{
ScrollController
_offsetController
=
ScrollController
();
//定义ListView的controller
static
bool
_showError
=
false
;
Future
<
void
>
_listener
(
LogBean
logBean
)
async
{
if
(!
mounted
)
return
;
// if there's a current frame,
...
...
@@ -164,12 +187,46 @@ class LogPageState extends State<LogPage> {
@override
Widget
build
(
BuildContext
context
)
{
List
<
IInfo
>
items
=
LogManager
.
instance
.
getLogs
().
reversed
.
toList
();
List
<
IInfo
>
items
=
LogPageState
.
_showError
?
LogManager
.
instance
.
getErrors
().
reversed
.
toList
()
:
LogManager
.
instance
.
getLogs
().
reversed
.
toList
();
return
Column
(
children:
[
Row
(
mainAxisAlignment:
MainAxisAlignment
.
start
,
children:
[
GestureDetector
(
behavior:
HitTestBehavior
.
opaque
,
onTap:
()
{
this
.
setState
(()
{
_showError
=
!
_showError
;
});
},
child:
Container
(
height:
44
,
width:
44
,
padding:
EdgeInsets
.
only
(
left:
16
),
child:
Image
.
asset
(
_showError
?
'images/dk_channel_check_h.png'
:
'images/dk_channel_check_n.png'
,
package:
DoKit
.
PACKAGE_NAME
,
height:
13
,
width:
13
),
),
),
GestureDetector
(
behavior:
HitTestBehavior
.
opaque
,
onTap:
()
{
this
.
setState
(()
{
_showError
=
!
_showError
;
});
},
child:
Text
(
'只显示异常'
,
style:
TextStyle
(
color:
_showError
?
Color
(
0xff337cc4
)
:
Color
(
0xff333333
),
fontSize:
12
))),
Container
(
decoration:
new
BoxDecoration
(
border:
new
Border
.
all
(
color:
Color
(
0xff337cc4
),
width:
1
),
...
...
@@ -186,6 +243,10 @@ class LogPageState extends State<LogPage> {
.
getKit
<
LogKit
>(
ApmKitName
.
KIT_LOG
)
.
getStorage
()
.
clear
();
ApmKitManager
.
instance
.
getKit
<
LogKit
>(
ApmKitName
.
KIT_LOG
)
.
error
.
clear
();
});
},
child:
Text
(
'清除本页数据'
,
...
...
Flutter/lib/kit/apm/method_channel_kit.dart
浏览文件 @
49a3af6f
...
...
@@ -23,7 +23,9 @@ class ChannelInfo implements IInfo {
final
String
method
;
final
dynamic
arguments
;
final
int
timestamp
;
final
int
startTimestamp
;
int
endTimestamp
=
0
;
final
int
type
;
dynamic
results
;
bool
expand
=
false
;
...
...
@@ -31,7 +33,7 @@ class ChannelInfo implements IInfo {
MessageCodec
messageCodec
;
ChannelInfo
(
this
.
channelName
,
this
.
method
,
this
.
arguments
,
this
.
type
)
:
this
.
t
imestamp
=
new
DateTime
.
now
().
millisecondsSinceEpoch
;
:
this
.
startT
imestamp
=
new
DateTime
.
now
().
millisecondsSinceEpoch
;
@override
String
getValue
()
{
...
...
@@ -69,7 +71,7 @@ class MethodChannelKit extends ApmKit {
@override
IStorage
createStorage
()
{
return
CommonStorage
(
maxCount:
12
0
);
return
CommonStorage
(
maxCount:
24
0
);
}
@override
...
...
@@ -82,6 +84,7 @@ class MethodChannelKit extends ApmKit {
if
(!
ChannelPageState
.
showSystemChannel
&&
((
info
as
ChannelInfo
).
type
==
ChannelInfo
.
TYPE_SYSTEM_RECEIVE
||
(
info
as
ChannelInfo
).
type
==
ChannelInfo
.
TYPE_SYSTEM_SEND
))
{
super
.
save
(
info
);
return
false
;
}
bool
result
=
super
.
save
(
info
);
...
...
@@ -331,7 +334,7 @@ class _ChannelItemWidgetState extends State<ChannelItemWidget> {
text:
TextSpan
(
children:
[
TextSpan
(
text:
'[
${TimeUtils.toTimeString(widget.item.
t
imestamp)}
]'
,
'[
${TimeUtils.toTimeString(widget.item.
startT
imestamp)}
]'
,
style:
TextStyle
(
fontSize:
9
,
color:
Color
(
0xff333333
),
...
...
@@ -352,6 +355,14 @@ class _ChannelItemWidgetState extends State<ChannelItemWidget> {
color:
(
widget
.
item
.
type
%
2
!=
0
?
Color
(
0xffd0607e
)
:
Color
(
0xff337cc4
))))),
TextSpan
(
text:
' Cost:
${widget.item.endTimestamp > 0 ? ((widget.item.endTimestamp - widget.item.startTimestamp).toString() + 'ms') : '-'}
'
,
style:
TextStyle
(
fontSize:
9
,
color:
Color
(
0xff666666
),
height:
1.5
,
)),
TextSpan
(
text:
'
\n
ChannelName: '
,
style:
TextStyle
(
...
...
Flutter/lib/kit/apm/route_kit.dart
浏览文件 @
49a3af6f
...
...
@@ -160,7 +160,7 @@ class RouteInfoPageState extends State<RouteInfoPage> {
]))));
}
route
=
route
.
parent
;
if
(
route
.
parent
!=
null
&&
route
.
parent
.
parent
!=
null
)
{
if
(
route
!=
null
&&
route
.
parent
!=
null
)
{
widgets
.
add
(
Container
(
margin:
EdgeInsets
.
only
(
top:
10
,
bottom:
10
),
alignment:
Alignment
.
center
,
...
...
@@ -169,7 +169,7 @@ class RouteInfoPageState extends State<RouteInfoPage> {
));
}
// 过滤掉dokit自带的navigator
}
while
(
route
.
parent
!=
null
&&
route
.
parent
.
parent
!=
null
);
}
while
(
route
!=
null
);
return
widgets
;
}
...
...
Flutter/lib/kit/common/basic_info.dart
浏览文件 @
49a3af6f
...
...
@@ -90,7 +90,7 @@ class InfoItem extends StatelessWidget {
padding:
EdgeInsets
.
only
(
top:
14
,
bottom:
14
),
child:
Row
(
mainAxisAlignment:
MainAxisAlignment
.
spaceBetween
,
crossAxisAlignment:
CrossAxisAlignment
.
center
,
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
<
Widget
>[
Text
(
label
,
...
...
@@ -99,17 +99,18 @@ class InfoItem extends StatelessWidget {
color:
Color
(
0xff333333
),
),
),
Container
(
width:
MediaQuery
.
of
(
context
).
size
.
width
-
130
,
margin:
EdgeInsets
.
only
(
left:
10
),
child:
Text
(
text
??
'-'
,
textAlign:
TextAlign
.
end
,
style:
TextStyle
(
fontSize:
16
,
color:
Color
(
0xff666666
),
),
))
Expanded
(
child:
Container
(
margin:
EdgeInsets
.
only
(
left:
10
),
child:
Text
(
text
??
'-'
,
textAlign:
TextAlign
.
end
,
style:
TextStyle
(
fontSize:
16
,
color:
Color
(
0xff666666
),
),
)),
)
],
));
}
...
...
Flutter/lib/kit/visual/view_check.dart
浏览文件 @
49a3af6f
...
...
@@ -51,9 +51,9 @@ class ViewCheckerKit extends VisualKit {
return
;
}
hasShow
=
true
;
Overlay
.
of
(
context
)
.
insert
(
focusEntry
,
below:
entrance
);
Overlay
.
of
(
context
)
.
insert
(
infoEntry
,
below:
focusEntry
);
Overlay
.
of
(
context
)
.
insert
(
rectEntry
,
below:
infoEntry
);
doKitOverlayKey
.
currentState
.
insert
(
focusEntry
,
below:
entrance
);
doKitOverlayKey
.
currentState
.
insert
(
infoEntry
,
below:
focusEntry
);
doKitOverlayKey
.
currentState
.
insert
(
rectEntry
,
below:
infoEntry
);
}
static
bool
hide
(
BuildContext
context
)
{
...
...
Flutter/lib/ui/dokit_app.dart
浏览文件 @
49a3af6f
import
'package:flutter/cupertino.dart'
;
import
'package:flutter/material.dart'
;
final
GlobalKey
<
OverlayState
>
doKitOverlayKey
=
GlobalKey
<
OverlayState
>();
// 谷歌提供的DevTool会判断入口widget是否在主工程内申明(runApp(new MyApp()),MyApp必须在主工程内定义,估计是根据source file来判断的),
// 如果在package内去申明这个入口widget,则在Flutter Inspector上的左边树会被折叠,影响开发使用。故这里要求在main文件内使用DoKitApp(MyApp())的形式来初始化入口
class
DoKitApp
extends
MaterialApp
{
class
DoKitApp
extends
StatefulWidget
{
// 放置dokit悬浮窗的容器
static
GlobalKey
rootKey
=
new
GlobalKey
();
...
...
@@ -12,8 +15,14 @@ class DoKitApp extends MaterialApp {
Widget
get
origin
=>
_origin
;
Widget
_origin
;
DoKitApp
(
this
.
_origin
)
:
super
(
key:
DoKitApp
.
rootKey
,
home:
_DoKitWrapper
(
_origin
));
DoKitApp
(
Widget
widget
)
:
_origin
=
_DoKitWrapper
(
widget
),
super
(
key:
rootKey
);
@override
State
<
StatefulWidget
>
createState
()
{
return
_DoKitAppState
();
}
}
class
_DoKitWrapper
extends
StatelessWidget
{
...
...
@@ -26,3 +35,113 @@ class _DoKitWrapper extends StatelessWidget {
return
_origin
;
}
}
class
_DoKitAppState
extends
State
<
DoKitApp
>
{
final
List
<
OverlayEntry
>
entries
=
<
OverlayEntry
>[];
final
supportedLocales
=
const
<
Locale
>[
Locale
(
'en'
,
'US'
)];
@override
void
initState
()
{
super
.
initState
();
entries
.
clear
();
entries
.
add
(
new
OverlayEntry
(
builder:
(
context
)
{
return
widget
.
origin
;
}));
}
Iterable
<
LocalizationsDelegate
<
dynamic
>>
get
_localizationsDelegates
sync
*
{
yield
DefaultMaterialLocalizations
.
delegate
;
yield
DefaultCupertinoLocalizations
.
delegate
;
yield
DefaultWidgetsLocalizations
.
delegate
;
}
@override
Widget
build
(
BuildContext
context
)
{
return
Directionality
(
textDirection:
TextDirection
.
ltr
,
child:
Stack
(
children:
<
Widget
>[
widget
.
origin
,
_MediaQueryFromWindow
(
child:
Localizations
(
locale:
supportedLocales
.
first
,
delegates:
_localizationsDelegates
.
toList
(),
child:
Overlay
(
key:
doKitOverlayKey
,
)))
],
),
);
}
}
class
_MediaQueryFromWindow
extends
StatefulWidget
{
const
_MediaQueryFromWindow
({
Key
key
,
this
.
child
})
:
super
(
key:
key
);
final
Widget
child
;
@override
_MediaQueryFromWindowsState
createState
()
=>
_MediaQueryFromWindowsState
();
}
class
_MediaQueryFromWindowsState
extends
State
<
_MediaQueryFromWindow
>
with
WidgetsBindingObserver
{
@override
void
initState
()
{
super
.
initState
();
WidgetsBinding
.
instance
.
addObserver
(
this
);
}
// ACCESSIBILITY
@override
void
didChangeAccessibilityFeatures
()
{
setState
(()
{
// The properties of window have changed. We use them in our build
// function, so we need setState(), but we don't cache anything locally.
});
}
// METRICS
@override
void
didChangeMetrics
()
{
setState
(()
{
// The properties of window have changed. We use them in our build
// function, so we need setState(), but we don't cache anything locally.
});
}
@override
void
didChangeTextScaleFactor
()
{
setState
(()
{
// The textScaleFactor property of window has changed. We reference
// window in our build function, so we need to call setState(), but
// we don't need to cache anything locally.
});
}
// RENDERING
@override
void
didChangePlatformBrightness
()
{
setState
(()
{
// The platformBrightness property of window has changed. We reference
// window in our build function, so we need to call setState(), but
// we don't need to cache anything locally.
});
}
@override
Widget
build
(
BuildContext
context
)
{
return
MediaQuery
(
data:
MediaQueryData
.
fromWindow
(
WidgetsBinding
.
instance
.
window
),
child:
widget
.
child
,
);
}
@override
void
dispose
()
{
WidgetsBinding
.
instance
.
removeObserver
(
this
);
super
.
dispose
();
}
}
Flutter/lib/ui/dokit_btn.dart
浏览文件 @
49a3af6f
...
...
@@ -21,7 +21,7 @@ class DoKitBtn extends StatefulWidget {
overlayEntry
=
new
OverlayEntry
(
builder:
(
context
)
{
return
this
;
});
OverlayState
rootOverlay
=
Overlay
.
of
(
DoKitApp
.
appKey
.
currentContext
)
;
OverlayState
rootOverlay
=
doKitOverlayKey
.
currentState
;
assert
(
rootOverlay
!=
null
);
rootOverlay
.
insert
(
overlayEntry
);
ApmKitManager
.
instance
.
startUp
();
...
...
@@ -100,7 +100,7 @@ class DoKitBtnState extends State<DoKitBtn> {
if
(
showDebugPage
)
{
closeDebugPage
();
}
else
{
Overlay
.
of
(
context
)
.
insert
(
debugPage
,
below:
owner
);
doKitOverlayKey
.
currentState
.
insert
(
debugPage
,
below:
owner
);
showDebugPage
=
true
;
}
}
...
...
Flutter/lib/ui/resident_page.dart
浏览文件 @
49a3af6f
...
...
@@ -59,7 +59,11 @@ class ResidentPageState extends State<ResidentPage> {
final
size
=
MediaQuery
.
of
(
context
).
size
;
final
width
=
size
.
width
;
final
height
=
size
.
height
;
int
topMargin
=
MediaQuery
.
of
(
context
).
orientation
==
Orientation
.
portrait
?
100
:
0
;
int
topMargin
=
MediaQuery
.
of
(
context
).
orientation
==
Orientation
.
portrait
?
100
:
0
;
if
(
height
==
0
)
{
return
Container
();
}
return
Positioned
(
child:
Container
(
width:
width
,
...
...
Flutter/pubspec.yaml
浏览文件 @
49a3af6f
name
:
dokit
description
:
开发工具集
version
:
0.2.
6
version
:
0.2.
12
homepage
:
https://www.dokit.cn/#/index/home
...
...
README.md
浏览文件 @
49a3af6f
...
...
@@ -27,8 +27,8 @@
<img
src=
"https://javer.oss-cn-shanghai.aliyuncs.com/doraemon/github/DoraemonKit_github.png"
width =
"150"
height =
"150"
alt=
"DoraemonKit"
align=
left
/>
<img
src=
"https://img.shields.io/github/license/didi/DoraemonKit.svg"
align=
left
/>
<img
src=
"https://img.shields.io/badge/Android-3.3.5-blue.svg"
align=
left
/>
<img
src=
"https://img.shields.io/badge/iOS-3.0.
4
-yellow.svg"
align=
left
/>
<img
src=
"https://img.shields.io/badge/Flutter-0.2.
5
-blue.svg"
align=
left
/>
<img
src=
"https://img.shields.io/badge/iOS-3.0.
7
-yellow.svg"
align=
left
/>
<img
src=
"https://img.shields.io/badge/Flutter-0.2.
12
-blue.svg"
align=
left
/>
<img
src=
"https://img.shields.io/badge/miniapp-0.0.1-red.svg"
align=
left
/>
<img
src=
"https://img.shields.io/badge/PRs-welcome-brightgreen.svg"
align=
left
/>
</div>
...
...
@@ -47,6 +47,7 @@
## 使用手册
访问
[
DoKit官网
](
https://www.dokit.cn/
)
,点击"
[
使用中心
](
http://xingyun.xiaojukeji.com/docs/dokit/#/intro
)
"。
**温馨提示:当前DoKit的所有功能都只针对Debug环境,Release环境未经过实际验证,所以请大家严格按照官方文档来集成,也不建议大家在Release环境上使用DoKit的任何功能。如果大家一定要在Release环境上使用,请自行进行充分的测试和验证,DoKit官方将不承担任何责任和损失。**
## 更新日志
-
[
iOS-ReleaseNotes
](
Doc/iOS-ReleaseNotes.md
)
...
...
@@ -228,7 +229,7 @@ tips : 如果使用我们滴滴优秀的开源跨端方案 [chameleon](https:/
## 项目成员
**
发起者
**
**
创始人
**
[
yixiangboy(易翔)
](
https://github.com/yixiangboy
)
**负责人**
[
jtsky(金台)
](
https://github.com/jtsky
)
...
...
iOS/DoraemonKit/Resource/Assets.xcassets/doraemon_health_bg.imageset/doraemon_health_bg@2x.png
查看替换文件 @
d551ce83
浏览文件 @
49a3af6f
773.3 KB
|
W:
|
H:
276.7 KB
|
W:
|
H:
2-up
Swipe
Onion skin
iOS/DoraemonKit/Resource/Assets.xcassets/doraemon_health_bg.imageset/doraemon_health_bg@3x.png
查看替换文件 @
d551ce83
浏览文件 @
49a3af6f
276.7 KB
|
W:
|
H:
773.3 KB
|
W:
|
H:
2-up
Swipe
Onion skin
iOS/DoraemonKit/Src/Core/Category/UIImage+Doraemon.m
浏览文件 @
49a3af6f
...
...
@@ -20,12 +20,10 @@
NSString
*
imageName
=
nil
;
CGFloat
scale
=
[
UIScreen
mainScreen
].
scale
;
if
(
ABS
(
scale
-
3
)
<=
0
.
001
){
if
(
ABS
(
scale
-
3
)
<=
0
.
001
)
{
imageName
=
[
NSString
stringWithFormat
:
@"%@@3x"
,
name
];
}
else
if
(
ABS
(
scale
-
2
)
<=
0
.
001
)
{
}
else
{
imageName
=
[
NSString
stringWithFormat
:
@"%@@2x"
,
name
];
}
else
{
imageName
=
name
;
}
UIImage
*
image
=
[
UIImage
imageWithContentsOfFile
:[
imageBundle
pathForResource
:
imageName
ofType
:
@"png"
]];
if
(
!
image
)
{
...
...
iOS/DoraemonKit/Src/Core/Network/Interceptor/DoraemonNSURLProtocol.m
浏览文件 @
49a3af6f
...
...
@@ -98,8 +98,10 @@ static NSString * const kDoraemonProtocolKey = @"doraemon_protocol_key";
});
}
else
if
(
DoraemonWeakNetwork_WeakSpeed
==
[[
DoraemonNetworkInterceptor
shareInstance
].
weakDelegate
weakNetSelecte
]){
DoKitLog
(
@"yd WeakUpFlow Net"
);
[[
DoraemonNetworkInterceptor
shareInstance
].
weakDelegate
handleWeak
:[
DoraemonUrlUtil
getHttpBodyFromRequest
:
self
.
request
]
isDown
:
NO
];
[
self
.
task
resume
];
[[
DoraemonNetFlowManager
shareInstance
]
httpBodyFromRequest
:
self
.
request
bodyCallBack
:
^
(
NSData
*
body
)
{
[[
DoraemonNetworkInterceptor
shareInstance
].
weakDelegate
handleWeak
:
body
isDown
:
NO
];
[
self
.
task
resume
];
}];
}
else
{
[
self
.
task
resume
];
}
...
...
@@ -201,15 +203,15 @@ static NSString * const kDoraemonProtocolKey = @"doraemon_protocol_key";
}
}
-
(
void
)
URLSession
:(
NSURLSession
*
)
session
task
:(
NSURLSessionTask
*
)
task
didReceiveChallenge
:(
NSURLAuthenticationChallenge
*
)
challenge
completionHandler
:(
void
(
^
)(
NSURLSessionAuthChallengeDisposition
disposition
,
NSURLCredential
*
credential
))
completionHandler
{
assert
([
NSThread
currentThread
]
==
self
.
clientThread
);
//判断服务器返回的证书类型, 是否是服务器信任
if
([
challenge
.
protectionSpace
.
authenticationMethod
isEqualToString
:
NSURLAuthenticationMethodServerTrust
])
{
//强制信任
NSURLCredential
*
card
=
[[
NSURLCredential
alloc
]
initWithTrust
:
challenge
.
protectionSpace
.
serverTrust
];
completionHandler
(
NSURLSessionAuthChallengeUseCredential
,
card
);
}
}
//
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler {
//
assert([NSThread currentThread] == self.clientThread);
//
//判断服务器返回的证书类型, 是否是服务器信任
//
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
//
//强制信任
//
NSURLCredential *card = [[NSURLCredential alloc]initWithTrust:challenge.protectionSpace.serverTrust];
//
completionHandler(NSURLSessionAuthChallengeUseCredential, card);
//
}
//
}
// 去掉一些我们不关心的链接, 与UIWebView的兼容还是要好好考略一下
+
(
BOOL
)
ignoreRequest
:(
NSURLRequest
*
)
request
{
...
...
iOS/DoraemonKit/Src/Core/Plugin/Performance/NetFlow/Function/DoraemonNetFlowHttpModel.h
浏览文件 @
49a3af6f
...
...
@@ -28,6 +28,6 @@
@property
(
nonatomic
,
copy
)
NSString
*
topVc
;
//流量触发时候的顶层vc
+
(
DoraemonNetFlowHttpModel
*
)
dealWithResponseData
:(
NSData
*
)
responseData
response
:(
NSURLResponse
*
)
response
request
:(
NSURLRequest
*
)
request
;
+
(
void
)
dealWithResponseData
:(
NSData
*
)
responseData
response
:(
NSURLResponse
*
)
response
request
:(
NSURLRequest
*
)
request
complete
:(
void
(
^
)(
DoraemonNetFlowHttpModel
*
model
))
complete
;
@end
iOS/DoraemonKit/Src/Core/Plugin/Performance/NetFlow/Function/DoraemonNetFlowHttpModel.m
浏览文件 @
49a3af6f
...
...
@@ -6,24 +6,19 @@
//
#import "DoraemonNetFlowHttpModel.h"
#import "DoraemonNetFlowManager.h"
#import "NSURLRequest+Doraemon.h"
#import "DoraemonUrlUtil.h"
@implementation
DoraemonNetFlowHttpModel
+
(
DoraemonNetFlowHttpModel
*
)
dealWithResponseData
:(
NSData
*
)
responseData
response
:(
NSURLResponse
*
)
response
request
:(
NSURLRequest
*
)
request
{
+
(
void
)
dealWithResponseData
:(
NSData
*
)
responseData
response
:(
NSURLResponse
*
)
response
request
:(
NSURLRequest
*
)
request
complete
:(
void
(
^
)(
DoraemonNetFlowHttpModel
*
model
))
complete
{
DoraemonNetFlowHttpModel
*
httpModel
=
[[
DoraemonNetFlowHttpModel
alloc
]
init
];
//request
httpModel
.
request
=
request
;
httpModel
.
requestId
=
request
.
requestId
;
httpModel
.
url
=
[
request
.
URL
absoluteString
];
httpModel
.
method
=
request
.
HTTPMethod
;
NSData
*
httpBody
=
[
DoraemonUrlUtil
getHttpBodyFromRequest
:
request
];
httpModel
.
requestBody
=
[
DoraemonUrlUtil
convertJsonFromData
:
httpBody
];
httpModel
.
uploadFlow
=
[
NSString
stringWithFormat
:
@"%zi"
,[
DoraemonUrlUtil
getRequestLength
:
request
]];
//response
httpModel
.
mineType
=
response
.
MIMEType
;
httpModel
.
response
=
response
;
...
...
@@ -33,12 +28,12 @@
httpModel
.
responseBody
=
[
DoraemonUrlUtil
convertJsonFromData
:
responseData
];
httpModel
.
totalDuration
=
[
NSString
stringWithFormat
:
@"%fs"
,[[
NSDate
date
]
timeIntervalSince1970
]
-
request
.
startTime
.
doubleValue
];
httpModel
.
downFlow
=
[
NSString
stringWithFormat
:
@"%lli"
,[
DoraemonUrlUtil
getResponseLength
:(
NSHTTPURLResponse
*
)
response
data
:
responseData
]];
return
httpModel
;
[[
DoraemonNetFlowManager
shareInstance
]
httpBodyFromRequest
:
request
bodyCallBack
:
^
(
NSData
*
body
)
{
httpModel
.
requestBody
=
[
DoraemonUrlUtil
convertJsonFromData
:
body
];
NSUInteger
length
=
[
DoraemonUrlUtil
getHeadersLengthWithRequest
:
request
]
+
[
body
length
];
httpModel
.
uploadFlow
=
[
NSString
stringWithFormat
:
@"%zi"
,
length
];
complete
(
httpModel
);
}];
}
@end
iOS/DoraemonKit/Src/Core/Plugin/Performance/NetFlow/Function/DoraemonNetFlowManager.h
浏览文件 @
49a3af6f
...
...
@@ -7,6 +7,8 @@
#import <Foundation/Foundation.h>
typedef
void
(
^
HttpBodyCallBack
)(
NSData
*
body
);
@interface
DoraemonNetFlowManager
:
NSObject
+
(
DoraemonNetFlowManager
*
)
shareInstance
;
...
...
@@ -16,4 +18,6 @@
-
(
void
)
canInterceptNetFlow
:(
BOOL
)
enable
;
-
(
void
)
httpBodyFromRequest
:(
NSURLRequest
*
)
request
bodyCallBack
:(
HttpBodyCallBack
)
complete
;
@end
iOS/DoraemonKit/Src/Core/Plugin/Performance/NetFlow/Function/DoraemonNetFlowManager.m
浏览文件 @
49a3af6f
...
...
@@ -13,7 +13,10 @@
#import "UIViewController+Doraemon.h"
#import "DoraemonHealthManager.h"
@interface
DoraemonNetFlowManager
()
<
DoraemonNetworkInterceptorDelegate
>
@interface
DoraemonNetFlowManager
()
<
DoraemonNetworkInterceptorDelegate
,
NSStreamDelegate
>
@property
(
nonatomic
,
copy
)
HttpBodyCallBack
bodyCallBack
;
@property
(
nonatomic
,
strong
)
NSMutableData
*
bodyData
;
@end
...
...
@@ -40,21 +43,79 @@
}
}
-
(
void
)
httpBodyFromRequest
:(
NSURLRequest
*
)
request
bodyCallBack
:(
HttpBodyCallBack
)
complete
{
NSData
*
httpBody
=
nil
;
if
(
request
.
HTTPBody
)
{
httpBody
=
request
.
HTTPBody
;
complete
(
httpBody
);
return
;
}
if
([
request
.
HTTPMethod
isEqualToString
:
@"POST"
])
{
NSInputStream
*
stream
=
request
.
HTTPBodyStream
;
[
stream
setDelegate
:
self
];
self
.
bodyCallBack
=
complete
;
[
stream
scheduleInRunLoop
:[
NSRunLoop
currentRunLoop
]
forMode
:
NSDefaultRunLoopMode
];
[
stream
open
];
}
else
{
complete
(
httpBody
);
}
}
#pragma mark -- NSStreamDelegate
-
(
void
)
stream
:(
NSStream
*
)
aStream
handleEvent
:(
NSStreamEvent
)
eventCode
{
switch
(
eventCode
)
{
case
NSStreamEventHasBytesAvailable
:
{
if
(
!
self
.
bodyData
)
{
self
.
bodyData
=
[
NSMutableData
data
];
}
uint8_t
buf
[
1024
];
NSInteger
len
=
0
;
len
=
[(
NSInputStream
*
)
aStream
read
:
buf
maxLength
:
1024
];
if
(
len
)
{
[
self
.
bodyData
appendBytes
:(
const
void
*
)
buf
length
:
len
];
}
}
break
;
case
NSStreamEventErrorOccurred
:
{
NSError
*
error
=
[
aStream
streamError
];
NSString
*
errorInfo
=
[
NSString
stringWithFormat
:
@"Failed while reading stream; error '%@' (code %ld)"
,
error
.
localizedDescription
,
error
.
code
];
NSLog
(
@"%@"
,
errorInfo
);
}
break
;
case
NSStreamEventEndEncountered
:
{
[
aStream
close
];
[
aStream
removeFromRunLoop
:[
NSRunLoop
currentRunLoop
]
forMode
:
NSDefaultRunLoopMode
];
aStream
=
nil
;
if
(
self
.
bodyCallBack
)
{
self
.
bodyCallBack
([
self
.
bodyData
copy
]);
}
self
.
bodyData
=
nil
;
}
break
;
default:
break
;
}
}
#pragma mark -- DoraemonNetworkInterceptorDelegate
-
(
void
)
doraemonNetworkInterceptorDidReceiveData
:(
NSData
*
)
data
response
:(
NSURLResponse
*
)
response
request
:(
NSURLRequest
*
)
request
error
:(
NSError
*
)
error
startTime
:(
NSTimeInterval
)
startTime
{
DoraemonNetFlowHttpModel
*
httpModel
=
[
DoraemonNetFlowHttpModel
dealWithResponseData
:
data
response
:
response
request
:
request
];
if
(
!
response
)
{
httpModel
.
statusCode
=
error
.
localizedDescription
;
}
httpModel
.
startTime
=
startTime
;
httpModel
.
endTime
=
[[
NSDate
date
]
timeIntervalSince1970
];
httpModel
.
totalDuration
=
[
NSString
stringWithFormat
:
@"%f"
,[[
NSDate
date
]
timeIntervalSince1970
]
-
startTime
];
httpModel
.
topVc
=
NSStringFromClass
([[
UIViewController
topViewControllerForKeyWindow
]
class
]);
[[
DoraemonNetFlowDataSource
shareInstance
]
addHttpModel
:
httpModel
];
[[
DoraemonHealthManager
sharedInstance
]
addHttpModel
:
httpModel
];
[
DoraemonNetFlowHttpModel
dealWithResponseData
:
data
response
:
response
request
:
request
complete
:^
(
DoraemonNetFlowHttpModel
*
httpModel
)
{
if
(
!
response
)
{
httpModel
.
statusCode
=
error
.
localizedDescription
;
}
httpModel
.
startTime
=
startTime
;
httpModel
.
endTime
=
[[
NSDate
date
]
timeIntervalSince1970
];
httpModel
.
totalDuration
=
[
NSString
stringWithFormat
:
@"%f"
,[[
NSDate
date
]
timeIntervalSince1970
]
-
startTime
];
httpModel
.
topVc
=
NSStringFromClass
([[
UIViewController
topViewControllerForKeyWindow
]
class
]);
[[
DoraemonNetFlowDataSource
shareInstance
]
addHttpModel
:
httpModel
];
[[
DoraemonHealthManager
sharedInstance
]
addHttpModel
:
httpModel
];
}];
}
-
(
BOOL
)
shouldIntercept
{
...
...
iOS/DoraemonKit/Src/Core/Plugin/Performance/NetFlow/Function/Util/DoraemonUrlUtil.h
浏览文件 @
49a3af6f
...
...
@@ -13,7 +13,9 @@
+
(
NSDictionary
*
)
convertDicFromData
:(
NSData
*
)
data
;
+
(
NSUInteger
)
getRequestLength
:(
NSURLRequest
*
)
request
;
+
(
NSUInteger
)
getHeadersLengthWithRequest
:(
NSURLRequest
*
)
request
;
+
(
void
)
requestLength
:(
NSURLRequest
*
)
request
callBack
:(
void
(
^
)(
NSUInteger
))
callBack
;
+
(
NSUInteger
)
getHeadersLength
:(
NSDictionary
*
)
headers
;
...
...
@@ -21,6 +23,4 @@
+
(
int64_t
)
getResponseLength
:(
NSHTTPURLResponse
*
)
response
data
:(
NSData
*
)
responseData
;
+
(
NSData
*
)
getHttpBodyFromRequest
:(
NSURLRequest
*
)
request
;
@end
iOS/DoraemonKit/Src/Core/Plugin/Performance/NetFlow/Function/Util/DoraemonUrlUtil.m
浏览文件 @
49a3af6f
...
...
@@ -6,6 +6,7 @@
//
#import "DoraemonUrlUtil.h"
#import "DoraemonNetFlowManager.h"
@implementation
DoraemonUrlUtil
...
...
@@ -39,7 +40,15 @@
return
jsonObj
;
}
+
(
NSUInteger
)
getRequestLength
:(
NSURLRequest
*
)
request
{
+
(
void
)
requestLength
:(
NSURLRequest
*
)
request
callBack
:(
void
(
^
)(
NSUInteger
))
callBack
{
NSUInteger
headersLength
=
[
self
getHeadersLengthWithRequest
:
request
];
[[
DoraemonNetFlowManager
shareInstance
]
httpBodyFromRequest
:
request
bodyCallBack
:
^
(
NSData
*
body
)
{
NSUInteger
bodyLength
=
[
body
length
];
callBack
(
headersLength
+
bodyLength
);
}];
}
+
(
NSUInteger
)
getHeadersLengthWithRequest
:(
NSURLRequest
*
)
request
{
NSDictionary
<
NSString
*
,
NSString
*>
*
headerFields
=
request
.
allHTTPHeaderFields
;
NSDictionary
<
NSString
*
,
NSString
*>
*
cookiesHeader
=
[
self
getCookies
:
request
];
if
(
cookiesHeader
.
count
)
{
...
...
@@ -47,11 +56,7 @@
[
headerFieldsWithCookies
addEntriesFromDictionary
:
cookiesHeader
];
headerFields
=
[
headerFieldsWithCookies
copy
];
}
NSUInteger
headersLength
=
[
self
getHeadersLength
:
headerFields
];
NSData
*
httpBody
=
[[
self
class
]
getHttpBodyFromRequest
:
request
];
NSUInteger
bodyLength
=
[
httpBody
length
];
return
headersLength
+
bodyLength
;
return
[
self
getHeadersLength
:
headerFields
];
}
+
(
NSUInteger
)
getHeadersLength
:(
NSDictionary
*
)
headers
{
...
...
@@ -95,28 +100,4 @@
return
responseLength
;
}
+
(
NSData
*
)
getHttpBodyFromRequest
:(
NSURLRequest
*
)
request
{
NSData
*
httpBody
;
if
(
request
.
HTTPBody
)
{
httpBody
=
request
.
HTTPBody
;
}
else
{
if
([
request
.
HTTPMethod
isEqualToString
:
@"POST"
])
{
if
(
!
request
.
HTTPBody
)
{
uint8_t
d
[
1024
]
=
{
0
};
NSInputStream
*
stream
=
request
.
HTTPBodyStream
;
NSMutableData
*
data
=
[[
NSMutableData
alloc
]
init
];
[
stream
open
];
while
([
stream
hasBytesAvailable
])
{
NSInteger
len
=
[
stream
read
:
d
maxLength
:
1024
];
if
(
len
>
0
&&
stream
.
streamError
==
nil
)
{
[
data
appendBytes
:(
void
*
)
d
length
:
len
];
}
}
httpBody
=
[
data
copy
];
[
stream
close
];
}
}
}
return
httpBody
;
}
@end
iOS/DoraemonKit/Src/Core/Plugin/Performance/WeakNetwork/Function/DoraemonWeakNetworkManager.m
浏览文件 @
49a3af6f
...
...
@@ -115,7 +115,9 @@
#pragma mark -- DoraemonNetworkInterceptorDelegate
-
(
void
)
doraemonNetworkInterceptorDidReceiveData
:(
NSData
*
)
data
response
:(
NSURLResponse
*
)
response
request
:(
NSURLRequest
*
)
request
error
:(
NSError
*
)
error
startTime
:(
NSTimeInterval
)
startTime
{
[[
DoraemonWeakNetworkWindow
shareInstance
]
updateFlowValue
:[
NSString
stringWithFormat
:
@"%zi"
,[
DoraemonUrlUtil
getRequestLength
:
request
]]
downFlow
:[
NSString
stringWithFormat
:
@"%lli"
,[
DoraemonUrlUtil
getResponseLength
:(
NSHTTPURLResponse
*
)
response
data
:
data
]]
fromWeak
:
NO
];
[
DoraemonUrlUtil
requestLength
:
request
callBack
:
^
(
NSUInteger
length
)
{
[[
DoraemonWeakNetworkWindow
shareInstance
]
updateFlowValue
:[
NSString
stringWithFormat
:
@"%zi"
,
length
]
downFlow
:[
NSString
stringWithFormat
:
@"%lli"
,[
DoraemonUrlUtil
getResponseLength
:(
NSHTTPURLResponse
*
)
response
data
:
data
]]
fromWeak
:
NO
];
}];
}
-
(
BOOL
)
shouldIntercept
{
...
...
iOS/DoraemonKit/Src/Core/Plugin/Platform/Mock/Function/DoraemonMockManager.m
浏览文件 @
49a3af6f
...
...
@@ -181,7 +181,8 @@
-
(
DoraemonMockBaseModel
*
)
getSelectedData
:(
NSURLRequest
*
)
request
dataArray
:(
NSArray
*
)
dataArray
{
NSString
*
path
=
request
.
URL
.
path
;
NSString
*
query
=
request
.
URL
.
query
;
NSData
*
httpBody
=
[
DoraemonUrlUtil
getHttpBodyFromRequest
:
request
];
// 这里暂时使用不严谨body match
NSData
*
httpBody
=
request
.
HTTPBody
;
NSDictionary
*
requestBody
=
[
DoraemonUrlUtil
convertDicFromData
:
httpBody
];
DoraemonMockBaseModel
*
selectedApi
;
for
(
DoraemonMockBaseModel
*
api
in
dataArray
)
{
...
...
iOS/DoraemonKitDemo/DoraemonKitDemo/DemoVC/Net/ NSURLProtocol/DoraemonDemoURLProtocol1.m
浏览文件 @
49a3af6f
...
...
@@ -8,6 +8,7 @@
#import "DoraemonDemoURLProtocol1.h"
#import "DoraemonUrlUtil.h"
#import "DoraemonNetFlowManager.h"
static
NSString
*
const
kDoraemonDemoUrlProtocolKey
=
@"doraemon_demo_url_protocol_1_key"
;
...
...
@@ -48,10 +49,11 @@ static NSString * const kDoraemonDemoUrlProtocolKey = @"doraemon_demo_url_protoc
-
(
void
)
stopLoading
{
NSLog
(
@"11111 == stopLoading"
);
NSData
*
httpBody
=
[
DoraemonUrlUtil
getHttpBodyFromRequest
:
self
.
request
];
NSString
*
requestBody
=
[
DoraemonUrlUtil
convertJsonFromData
:
httpBody
];
NSLog
(
@"11111 == requestBody = %@"
,
requestBody
);
[
self
.
connection
cancel
];
[[
DoraemonNetFlowManager
shareInstance
]
httpBodyFromRequest
:
self
.
request
bodyCallBack
:
^
(
NSData
*
httpBody
)
{
NSString
*
requestBody
=
[
DoraemonUrlUtil
convertJsonFromData
:
httpBody
];
NSLog
(
@"11111 == requestBody = %@"
,
requestBody
);
[
self
.
connection
cancel
];
}];
}
...
...
iOS/DoraemonKitDemo/DoraemonKitDemo/DemoVC/Net/ NSURLProtocol/DoraemonDemoURLProtocol2.m
浏览文件 @
49a3af6f
...
...
@@ -8,6 +8,7 @@
#import "DoraemonDemoURLProtocol2.h"
#import "DoraemonUrlUtil.h"
#import "DoraemonNetFlowManager.h"
static
NSString
*
const
kDoraemonDemoUrlProtocol2Key
=
@"doraemon_demo_url_protocol_2_key"
;
...
...
@@ -48,10 +49,11 @@ static NSString * const kDoraemonDemoUrlProtocol2Key = @"doraemon_demo_url_proto
-
(
void
)
stopLoading
{
NSLog
(
@"22222 == stopLoading"
);
NSData
*
httpBody
=
[
DoraemonUrlUtil
getHttpBodyFromRequest
:
self
.
request
];
NSString
*
requestBody
=
[
DoraemonUrlUtil
convertJsonFromData
:
httpBody
];
NSLog
(
@"22222 == requestBody = %@"
,
requestBody
);
[
self
.
connection
cancel
];
[[
DoraemonNetFlowManager
shareInstance
]
httpBodyFromRequest
:
self
.
request
bodyCallBack
:
^
(
NSData
*
httpBody
)
{
NSString
*
requestBody
=
[
DoraemonUrlUtil
convertJsonFromData
:
httpBody
];
NSLog
(
@"22222 == requestBody = %@"
,
requestBody
);
[
self
.
connection
cancel
];
}];
}
...
...
iOS/DoraemonKitDemo/DoraemonKitDemo/DemoVC/Net/DoraemonDemoNetViewController.m
浏览文件 @
49a3af6f
...
...
@@ -222,10 +222,11 @@
session
.
requestSerializer
=
[
AFHTTPRequestSerializer
serializer
];
// 请求
session
.
responseSerializer
=
[
AFHTTPResponseSerializer
serializer
];
// 响应
session
.
responseSerializer
.
acceptableContentTypes
=
[
NSSet
setWithObjects
:
@"application/json"
,
@"text/json"
,
@"text/javascript"
,
@"text/html"
,
nil
];
[
session
GET
:
@"https://www.taobao.com/"
parameters
:
nil
success
:^
(
NSURLSessionDataTask
*
task
,
id
responseObject
)
{
[
session
GET
:
@"https://www.taobao.com/"
parameters
:
nil
headers
:
nil
progress
:
nil
success
:^
(
NSURLSessionDataTask
*
_Nonnull
task
,
id
_Nullable
responseObject
)
{
NSString
*
string
=
[[
NSString
alloc
]
initWithData
:
responseObject
encoding
:
NSUTF8StringEncoding
];
NSLog
(
@"success %@"
,
string
);
}
failure
:^
(
NSURLSessionDataTask
*
task
,
NSError
*
error
)
{
}
failure
:^
(
NSURLSessionDataTask
*
_Nullable
task
,
NSError
*
_Nonnull
error
)
{
NSLog
(
@"failure"
);
}];
...
...
@@ -238,7 +239,7 @@
}
-
(
void
)
netForAFNetworking2
{
AFHTTP
RequestOperationManager
*
manager
=
[
AFHTTPRequestOperat
ionManager
manager
];
AFHTTP
SessionManager
*
manager
=
[
AFHTTPSess
ionManager
manager
];
manager
.
requestSerializer
=
[
AFHTTPRequestSerializer
serializer
];
// 请求
manager
.
responseSerializer
=
[
AFHTTPResponseSerializer
serializer
];
// 响应
manager
.
responseSerializer
.
acceptableContentTypes
=
[
NSSet
setWithObjects
:
@"application/json"
,
@"text/json"
,
@"text/javascript"
,
@"text/html"
,
nil
];
...
...
@@ -249,10 +250,10 @@
// NSLog(@"请求失败");
// }];
[
manager
POST
:
@"https://www.taobao.com/"
parameters
:
nil
success
:^
(
AFHTTPRequestOperation
*
operation
,
id
responseObject
)
{
[
manager
POST
:
@"https://www.taobao.com/"
parameters
:
nil
headers
:
nil
progress
:
nil
success
:^
(
NSURLSessionDataTask
*
_Nonnull
task
,
id
_Nullable
responseObject
)
{
NSString
*
string
=
[[
NSString
alloc
]
initWithData
:
responseObject
encoding
:
NSUTF8StringEncoding
];
NSLog
(
@"success %@"
,
string
);
}
failure
:^
(
AFHTTPRequestOperation
*
operation
,
NSError
*
error
)
{
}
failure
:^
(
NSURLSessionDataTask
*
_Nullable
task
,
NSError
*
_Nonnull
error
)
{
NSLog
(
@"failure"
);
}];
}
...
...
iOS/DoraemonKitDemo/DoraemonKitDemo/DemoVC/Performance/DoraemonDemoPerformanceViewController.m
浏览文件 @
49a3af6f
...
...
@@ -130,14 +130,15 @@
// NSLog(@"请求失败");
// }];
AFHTTP
RequestOperationManager
*
manager
=
[
AFHTTPRequestOperat
ionManager
manager
];
AFHTTP
SessionManager
*
manager
=
[
AFHTTPSess
ionManager
manager
];
manager
.
requestSerializer
=
[
AFHTTPRequestSerializer
serializer
];
// 请求
manager
.
responseSerializer
=
[
AFHTTPResponseSerializer
serializer
];
// 响应
manager
.
responseSerializer
.
acceptableContentTypes
=
[
NSSet
setWithObjects
:
@"application/json"
,
@"text/json"
,
@"text/javascript"
,
@"text/html"
,
nil
];
[
manager
GET
:
@"https://www.taobao.com/"
parameters
:
nil
success
:^
(
AFHTTPRequestOperation
*
operation
,
id
responseObject
)
{
[
manager
GET
:
@"https://www.taobao.com/"
parameters
:
nil
headers
:
nil
progress
:
nil
success
:^
(
NSURLSessionDataTask
*
_Nonnull
task
,
id
_Nullable
responseObject
)
{
NSString
*
string
=
[[
NSString
alloc
]
initWithData
:
responseObject
encoding
:
NSUTF8StringEncoding
];
NSLog
(
@"request success %@"
,
string
);
}
failure
:^
(
AFHTTPRequestOperation
*
operation
,
NSError
*
error
)
{
}
failure
:^
(
NSURLSessionDataTask
*
_Nullable
task
,
NSError
*
_Nonnull
error
)
{
NSLog
(
@"request failure"
);
}];
}
...
...
iOS/DoraemonKitDemo/Podfile
浏览文件 @
49a3af6f
...
...
@@ -20,7 +20,7 @@ target :'DoraemonKitDemo' do
#pod 'DoraemonKit', :subspecs => ['Core','WithLogger','WithGPS','WithLoad','WithWeex', 'WithDatabase', 'WithMLeaksFinder'], :path => '../../'
#pod 'DoraemonKit', :subspecs => ['Core'], :path => '../../'
pod
'DoraemonKit'
,
:subspecs
=>
[
'Core'
,
'WithLogger'
,
'WithGPS'
,
'WithLoad'
,
'WithDatabase'
,
'WithMLeaksFinder'
,
'WithWeex'
],
:path
=>
'../../'
pod
'AFNetworking'
,
'2.6.3'
pod
'AFNetworking'
pod
'SDWebImage'
pod
'SocketRocket'
,
'~> 0.5'
pod
'SDWebImageWebPCoder'
...
...
iOS/DoraemonKitDemo/Podfile.lock
浏览文件 @
49a3af6f
PODS:
- AFNetworking (2.6.3):
- AFNetworking/NSURLConnection (= 2.6.3)
- AFNetworking/NSURLSession (= 2.6.3)
- AFNetworking/Reachability (= 2.6.3)
- AFNetworking/Security (= 2.6.3)
- AFNetworking/Serialization (= 2.6.3)
- AFNetworking/UIKit (= 2.6.3)
- AFNetworking/NSURLConnection (2.6.3):
- AFNetworking (4.0.1):
- AFNetworking/NSURLSession (= 4.0.1)
- AFNetworking/Reachability (= 4.0.1)
- AFNetworking/Security (= 4.0.1)
- AFNetworking/Serialization (= 4.0.1)
- AFNetworking/UIKit (= 4.0.1)
- AFNetworking/NSURLSession (4.0.1):
- AFNetworking/Reachability
- AFNetworking/Security
- AFNetworking/Serialization
- AFNetworking/NSURLSession (2.6.3):
- AFNetworking/Reachability
- AFNetworking/Security
- AFNetworking/Serialization
- AFNetworking/Reachability (2.6.3)
- AFNetworking/Security (2.6.3)
- AFNetworking/Serialization (2.6.3)
- AFNetworking/UIKit (2.6.3):
- AFNetworking/NSURLConnection
- AFNetworking/Reachability (4.0.1)
- AFNetworking/Security (4.0.1)
- AFNetworking/Serialization (4.0.1)
- AFNetworking/UIKit (4.0.1):
- AFNetworking/NSURLSession
- CocoaLumberjack (3.
6.2
):
- CocoaLumberjack/Core (= 3.
6.2
)
- CocoaLumberjack/Core (3.
6.2
)
- CocoaLumberjack (3.
7.0
):
- CocoaLumberjack/Core (= 3.
7.0
)
- CocoaLumberjack/Core (3.
7.0
)
- DoraemonKit/Core (3.0.6):
- FMDB
- GCDWebServer
...
...
@@ -65,12 +59,12 @@ PODS:
- libwebp/mux (1.1.0):
- libwebp/demux
- libwebp/webp (1.1.0)
- SDWebImage (5.
8
.4):
- SDWebImage/Core (= 5.
8
.4)
- SDWebImage/Core (5.
8
.4)
- SDWebImageWebPCoder (0.
6.1
):
- SDWebImage (5.
10
.4):
- SDWebImage/Core (= 5.
10
.4)
- SDWebImage/Core (5.
10
.4)
- SDWebImageWebPCoder (0.
8.2
):
- libwebp (~> 1.0)
- SDWebImage/Core (~> 5.
7
)
- SDWebImage/Core (~> 5.
10
)
- SocketRocket (0.5.1)
- WeexSDK (0.28.0)
- WXDevtool (0.24.0):
...
...
@@ -81,7 +75,7 @@ PODS:
- GCDWebServer
DEPENDENCIES:
- AFNetworking
(= 2.6.3)
- AFNetworking
- DoraemonKit/Core (from `../../`)
- DoraemonKit/WithDatabase (from `../../`)
- DoraemonKit/WithGPS (from `../../`)
...
...
@@ -118,27 +112,27 @@ EXTERNAL SOURCES:
CHECKOUT OPTIONS:
FBRetainCycleDetector:
:commit:
1ff2adee84a6ee94a1ae82526104a188774eb90a
:commit:
32c4afc1fc17553f9b69e4edd82cfa3c73dbb331
:git: https://github.com/facebook/FBRetainCycleDetector.git
YYDebugDatabase:
:commit: 87f4214ab9656b75dd74dfcc042cc3b5067ebab6
:git: https://github.com/y500/YYDebugDatabase.git
SPEC CHECKSUMS:
AFNetworking:
cb8d14a848e831097108418f5d49217339d4eb60
CocoaLumberjack:
bd155f2dd06c0e0b03f876f7a3ee55693122ec94
AFNetworking:
7864c38297c79aaca1500c33288e429c3451fdce
CocoaLumberjack:
e8955b9d337ac307103b0a34fd141c32f27e53c5
DoraemonKit: 919709427c30af94e265532a879ac41797d296d1
FBRetainCycleDetector: 46daef95c2dfa9be34b53087edf6a8f34e4c749c
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
GCDWebServer: 2c156a56c8226e2d5c0c3f208a3621ccffbe3ce4
libwebp: 946cb3063cea9236285f7e9a8505d806d30e07f3
SDWebImage: c
f6922231e95550934da2ada0f20f2becf2ceba9
SDWebImageWebPCoder:
d0dac55073088d24b2ac1b191a71a8f8d0adac21
SDWebImage: c
666b97e1fa9c64b4909816a903322018f0a9c84
SDWebImageWebPCoder:
f56ab499e3ea57dfeb6c3187dce183b10e160db0
SocketRocket: d57c7159b83c3c6655745cd15302aa24b6bae531
WeexSDK: 78861d2f8b78f67e30580c15a54f5b420456db39
WXDevtool: 95b70c73c06fc3299d65bd53ba4b3e0b0087f3cb
YYDebugDatabase: e684a7f79fca2e3673a23347cefb822f911f3124
PODFILE CHECKSUM:
6c5cced982a83d1a6dbfb6e8501724985d70d130
PODFILE CHECKSUM:
a955cdaf3e59b0dc21224f229ea928cf97cc0173
COCOAPODS: 1.
10.1
COCOAPODS: 1.
8.4
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录