├── README.md ├── TBRMonitor.podspec ├── TBRMonitorExample.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── hwh.xcuserdatad │ │ └── UserInterfaceState.xcuserstate ├── xcshareddata │ └── xcschemes │ │ └── TBRMonitorFramework.xcscheme └── xcuserdata │ └── hwh.xcuserdatad │ └── xcschemes │ ├── TBRMonitorDocument.xcscheme │ ├── TBRMonitorExample.xcscheme │ └── xcschememanagement.plist ├── TBRMonitorExample ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── Info.plist ├── ViewController.h ├── ViewController.m └── main.m ├── TBRMonitorExampleTests ├── Info.plist └── TBRMonitorExampleTests.m └── TBRMonitorFramework ├── GenerateDocument.sh ├── Info.plist ├── TBRCatogory ├── TBR_NSObject+Property.h ├── TBR_NSObject+Property.m ├── TBR_NSString+md5.h └── TBR_NSString+md5.m ├── TBRElectricity ├── TBRElectricity.h └── TBRElectricity.m ├── TBREnvConfig.h ├── TBREnvConfig.m ├── TBRMemory ├── TBRDeviceUsage.h └── TBRDeviceUsage.m ├── TBRMonitor.h ├── TBRMonitor.m ├── TBRMonitorFramework.h └── TBRURL ├── TBRURLCollectionManager.h ├── TBRURLCollectionManager.m ├── TBRURLGuard.h ├── TBRURLGuard.m ├── TBRURLProtocol.h └── TBRURLProtocol.m /README.md: -------------------------------------------------------------------------------- 1 | # TBRMonitor 2 | 3 | iOS App 性能监控(内存、电量、网络预警) 4 | 5 | --- 6 | 7 | ## Usage 8 | **Objective-c** 9 | ``` 10 | @interface AppDelegate () 11 | 12 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 13 | [TBRMonitor startMonotorWithDelegate:self]; 14 | return YES; 15 | } 16 | ``` 17 | 18 | 然后实现 TBRMonitorDelegate 监听数据 19 | 20 | ``` 21 | -(void)applicationRecieveBadUrl:(NSDictionary *)dic { 22 | NSLog(@"bad url : %@",dic); 23 | } 24 | - (void)applicationMemoryUsed:(float)usedSpace free:(float)freeSpace cpu:cpuUsage { 25 | NSLog(@"used: %f free: %f cpu:%f",usedSpace, freeSpace,cpuUsage); 26 | } 27 | -(void)applicationElectricityChanged:(float)level { 28 | NSLog(@"current electricity: %f",level); 29 | 30 | } 31 | ``` 32 | --- 33 | ## 主要功能 34 | 35 | **Request** 36 | 37 | 通过集成 NSURLProtocol 协议,覆盖协议中的方法,以实现拦截App中的网络请求 38 | 39 | 已实现功能: 40 | * 监测 失败URL ,并通知 " < TBRMonitorDelegate>" 41 | * 统计失败、成功 Request 个数 42 | * 本地URL 日志文件,路径为 43 | * Debug -> /Documents/Record.txt 44 | * Release -> /Documents/.Record.txt 45 | 46 | * 通过在main bundle创建 Host.plist ,root类型为 NSArray ,监听指定 `host 47 | 48 | 缺失功能: 49 | * 到达率 50 | * 网络延迟分析 51 | * ip地址解析 52 | 53 | 54 | 55 | **Memory** 56 | 57 | 已实现功能: 58 | * 一帧每秒,快照memory使用情况,并 ```-(void)applicationMemoryUsed:(float)usedSpace free:(float)freeSpace; 59 | ``` used 和 free 空间,已 ```kb``` 为单位 60 | 61 | **电量使用情况** 62 | 63 | * 手机电量使用状况。刷新时机为“每当电量有变化时才会通知”。代理方法为``-(void)applicationElectricityChanged:(float)level; 64 | `` 65 | 66 | 67 | **CPU使用** 68 | 69 | * 明天加上。。。 70 | 71 | 72 | **UI 绘制** 73 | * Window 绘制监控数据 74 | 75 | 76 | --- 77 | 78 | 79 | ## Install 80 | 81 | #### manual (不推荐) 82 | * 拖动 TBRMonitorFramework 文件夹到 工程所在文件夹,然后可以引入源文件,也可以使用工程生成framework使用 83 | * import 84 | 85 | #### Cocoapods 86 | * 安装cocoapods 87 | * 在Podfile文件添加 TBRMonitor 88 | ``` 89 | pod 'TBRMonitor', :git => 'https://github.com/huang1988519/TBRMonitor.git' 90 | 91 | ``` 92 | 因为是在测试阶段,不对外公开,暂时不会支持pod ```search TBRMonitor``` 93 | 94 | * ``` pod update --no-repo-update ``` 95 | * ``` import ``` 96 | 97 | 等待完成。等待loading结束,集成成功。 98 | #### carthage 99 | * 创建 Cartfile 100 | * 编辑 Cartfile -> 插入 ```github "huang1988519/TBRMonitor"``` 101 | * ```carthage update``` 102 | * embedded Carthage/Build/iOS/TBRMonitorFramework.framework 到你的target 103 | 104 | 105 | ## 生成Api文档: 106 | ``` 107 | > chmod +x GenerateDocument.sh 108 | > /GenerateDocument.sh 109 | ... 110 | input company name 111 | input company id 112 | input project name 113 | input "is generate xcode docs" yes/other 114 | generate... 115 | sucess! 116 | ``` 117 | 118 | > 如果使用过程中有问题,请发邮件 huang1988519@126.com 119 | -------------------------------------------------------------------------------- /TBRMonitor.podspec: -------------------------------------------------------------------------------- 1 | 2 | Pod::Spec.new do |s| 3 | s.name = "TBRMonitor" 4 | s.version = "0.0.1" 5 | s.summary = "The monitor of iOS app performance." 6 | s.description = <<-DESC 7 | ios应用性能监控,暂时只支持>监听电量,网络异常,cpu,ram 8 | DESC 9 | 10 | s.homepage = "http://huang1988519.github.io/TBRMonitor" 11 | s.license = "MIT" 12 | s.author = { "huangwh" => "huang1988519@126.com" } 13 | 14 | s.platform = :ios, "7.0" 15 | s.ios.deployment_target = "7.0" 16 | 17 | s.source = { :git => "https://github.com/huang1988519/TBRMonitor.git", :tag => s.version } 18 | #s.source_files = 'TBRMonitor/TBRMonitor.{h,m}', 'TBRMonitorFramework/', 'TBRMonitorFramework/TBRCatogory/', 'TBRMonitorFramework/TBRElectricity', 'TBRMonitorFramework/TBRMemory', 'TBRMonitorFramework/TBRURL/' 19 | s.source_files = 'TBRMonitorFramework/**/*' 20 | s.exclude_files = "Classes/Exclude" 21 | s.public_header_files = "TBRMonitor/TBRMonitor.h" 22 | end 23 | -------------------------------------------------------------------------------- /TBRMonitorExample.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXAggregateTarget section */ 10 | D9D36DF11CC62CD000E7AF10 /* TBRMonitorDocument */ = { 11 | isa = PBXAggregateTarget; 12 | buildConfigurationList = D9D36DF41CC62CD000E7AF10 /* Build configuration list for PBXAggregateTarget "TBRMonitorDocument" */; 13 | buildPhases = ( 14 | D9D36DF61CC62CE800E7AF10 /* ShellScript */, 15 | ); 16 | dependencies = ( 17 | ); 18 | name = TBRMonitorDocument; 19 | productName = TBRMonitorDocument; 20 | }; 21 | /* End PBXAggregateTarget section */ 22 | 23 | /* Begin PBXBuildFile section */ 24 | D9D56EB81CC098EC003CE68D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = D9D56EB71CC098EC003CE68D /* main.m */; }; 25 | D9D56EBB1CC098EC003CE68D /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = D9D56EBA1CC098EC003CE68D /* AppDelegate.m */; }; 26 | D9D56EBE1CC098EC003CE68D /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D9D56EBD1CC098EC003CE68D /* ViewController.m */; }; 27 | D9D56EC11CC098EC003CE68D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D9D56EBF1CC098EC003CE68D /* Main.storyboard */; }; 28 | D9D56EC31CC098EC003CE68D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D9D56EC21CC098EC003CE68D /* Assets.xcassets */; }; 29 | D9D56EC61CC098EC003CE68D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D9D56EC41CC098EC003CE68D /* LaunchScreen.storyboard */; }; 30 | D9D56ED11CC098EC003CE68D /* TBRMonitorExampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D9D56ED01CC098EC003CE68D /* TBRMonitorExampleTests.m */; }; 31 | D9D56EF21CC0991A003CE68D /* TBR_NSObject+Property.m in Sources */ = {isa = PBXBuildFile; fileRef = D9D56EDE1CC0991A003CE68D /* TBR_NSObject+Property.m */; }; 32 | D9D56EF31CC0991A003CE68D /* TBR_NSString+md5.m in Sources */ = {isa = PBXBuildFile; fileRef = D9D56EE01CC0991A003CE68D /* TBR_NSString+md5.m */; }; 33 | D9D56EF41CC0991A003CE68D /* TBRElectricity.m in Sources */ = {isa = PBXBuildFile; fileRef = D9D56EE31CC0991A003CE68D /* TBRElectricity.m */; }; 34 | D9D56EF51CC0991A003CE68D /* TBREnvConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = D9D56EE51CC0991A003CE68D /* TBREnvConfig.m */; }; 35 | D9D56EF61CC0991A003CE68D /* TBRDeviceUsage.m in Sources */ = {isa = PBXBuildFile; fileRef = D9D56EE81CC0991A003CE68D /* TBRDeviceUsage.m */; }; 36 | D9D56EF71CC0991A003CE68D /* TBRMonitor.m in Sources */ = {isa = PBXBuildFile; fileRef = D9D56EEA1CC0991A003CE68D /* TBRMonitor.m */; }; 37 | D9D56EF81CC0991A003CE68D /* TBRURLCollectionManager.m in Sources */ = {isa = PBXBuildFile; fileRef = D9D56EED1CC0991A003CE68D /* TBRURLCollectionManager.m */; }; 38 | D9D56EF91CC0991A003CE68D /* TBRURLGuard.m in Sources */ = {isa = PBXBuildFile; fileRef = D9D56EEF1CC0991A003CE68D /* TBRURLGuard.m */; }; 39 | D9D56EFA1CC0991A003CE68D /* TBRURLProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = D9D56EF11CC0991A003CE68D /* TBRURLProtocol.m */; }; 40 | D9D56F081CC09AF6003CE68D /* TBRMonitor.h in Headers */ = {isa = PBXBuildFile; fileRef = D9D56EE91CC0991A003CE68D /* TBRMonitor.h */; settings = {ATTRIBUTES = (Public, ); }; }; 41 | D9D56F091CC09B0C003CE68D /* TBR_NSObject+Property.m in Sources */ = {isa = PBXBuildFile; fileRef = D9D56EDE1CC0991A003CE68D /* TBR_NSObject+Property.m */; }; 42 | D9D56F0A1CC09B0C003CE68D /* TBR_NSString+md5.m in Sources */ = {isa = PBXBuildFile; fileRef = D9D56EE01CC0991A003CE68D /* TBR_NSString+md5.m */; }; 43 | D9D56F0B1CC09B0C003CE68D /* TBRElectricity.m in Sources */ = {isa = PBXBuildFile; fileRef = D9D56EE31CC0991A003CE68D /* TBRElectricity.m */; }; 44 | D9D56F0C1CC09B0C003CE68D /* TBREnvConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = D9D56EE51CC0991A003CE68D /* TBREnvConfig.m */; }; 45 | D9D56F0D1CC09B0D003CE68D /* TBRDeviceUsage.m in Sources */ = {isa = PBXBuildFile; fileRef = D9D56EE81CC0991A003CE68D /* TBRDeviceUsage.m */; }; 46 | D9D56F0E1CC09B0D003CE68D /* TBRMonitor.m in Sources */ = {isa = PBXBuildFile; fileRef = D9D56EEA1CC0991A003CE68D /* TBRMonitor.m */; }; 47 | D9D56F0F1CC09B0D003CE68D /* TBRURLCollectionManager.m in Sources */ = {isa = PBXBuildFile; fileRef = D9D56EED1CC0991A003CE68D /* TBRURLCollectionManager.m */; }; 48 | D9D56F101CC09B0D003CE68D /* TBRURLGuard.m in Sources */ = {isa = PBXBuildFile; fileRef = D9D56EEF1CC0991A003CE68D /* TBRURLGuard.m */; }; 49 | D9D56F111CC09B0D003CE68D /* TBRURLProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = D9D56EF11CC0991A003CE68D /* TBRURLProtocol.m */; }; 50 | D9D56F3B1CC0A2AA003CE68D /* TBRMonitorFramework.h in Headers */ = {isa = PBXBuildFile; fileRef = D9D56F021CC09AC7003CE68D /* TBRMonitorFramework.h */; settings = {ATTRIBUTES = (Public, ); }; }; 51 | /* End PBXBuildFile section */ 52 | 53 | /* Begin PBXContainerItemProxy section */ 54 | D9D56ECD1CC098EC003CE68D /* PBXContainerItemProxy */ = { 55 | isa = PBXContainerItemProxy; 56 | containerPortal = D9D56EAB1CC098EC003CE68D /* Project object */; 57 | proxyType = 1; 58 | remoteGlobalIDString = D9D56EB21CC098EC003CE68D; 59 | remoteInfo = TBRMonitorExample; 60 | }; 61 | /* End PBXContainerItemProxy section */ 62 | 63 | /* Begin PBXFileReference section */ 64 | D9D56EB31CC098EC003CE68D /* TBRMonitorExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TBRMonitorExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 65 | D9D56EB71CC098EC003CE68D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 66 | D9D56EB91CC098EC003CE68D /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 67 | D9D56EBA1CC098EC003CE68D /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 68 | D9D56EBC1CC098EC003CE68D /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 69 | D9D56EBD1CC098EC003CE68D /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 70 | D9D56EC01CC098EC003CE68D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 71 | D9D56EC21CC098EC003CE68D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 72 | D9D56EC51CC098EC003CE68D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 73 | D9D56EC71CC098EC003CE68D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 74 | D9D56ECC1CC098EC003CE68D /* TBRMonitorExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TBRMonitorExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 75 | D9D56ED01CC098EC003CE68D /* TBRMonitorExampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TBRMonitorExampleTests.m; sourceTree = ""; }; 76 | D9D56ED21CC098EC003CE68D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 77 | D9D56EDD1CC0991A003CE68D /* TBR_NSObject+Property.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "TBR_NSObject+Property.h"; sourceTree = ""; }; 78 | D9D56EDE1CC0991A003CE68D /* TBR_NSObject+Property.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "TBR_NSObject+Property.m"; sourceTree = ""; }; 79 | D9D56EDF1CC0991A003CE68D /* TBR_NSString+md5.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "TBR_NSString+md5.h"; sourceTree = ""; }; 80 | D9D56EE01CC0991A003CE68D /* TBR_NSString+md5.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "TBR_NSString+md5.m"; sourceTree = ""; }; 81 | D9D56EE21CC0991A003CE68D /* TBRElectricity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TBRElectricity.h; sourceTree = ""; }; 82 | D9D56EE31CC0991A003CE68D /* TBRElectricity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TBRElectricity.m; sourceTree = ""; }; 83 | D9D56EE41CC0991A003CE68D /* TBREnvConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TBREnvConfig.h; sourceTree = ""; }; 84 | D9D56EE51CC0991A003CE68D /* TBREnvConfig.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TBREnvConfig.m; sourceTree = ""; }; 85 | D9D56EE71CC0991A003CE68D /* TBRDeviceUsage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TBRDeviceUsage.h; sourceTree = ""; }; 86 | D9D56EE81CC0991A003CE68D /* TBRDeviceUsage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TBRDeviceUsage.m; sourceTree = ""; }; 87 | D9D56EE91CC0991A003CE68D /* TBRMonitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TBRMonitor.h; sourceTree = ""; }; 88 | D9D56EEA1CC0991A003CE68D /* TBRMonitor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TBRMonitor.m; sourceTree = ""; }; 89 | D9D56EEC1CC0991A003CE68D /* TBRURLCollectionManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TBRURLCollectionManager.h; sourceTree = ""; }; 90 | D9D56EED1CC0991A003CE68D /* TBRURLCollectionManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TBRURLCollectionManager.m; sourceTree = ""; }; 91 | D9D56EEE1CC0991A003CE68D /* TBRURLGuard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TBRURLGuard.h; sourceTree = ""; }; 92 | D9D56EEF1CC0991A003CE68D /* TBRURLGuard.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TBRURLGuard.m; sourceTree = ""; }; 93 | D9D56EF01CC0991A003CE68D /* TBRURLProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TBRURLProtocol.h; sourceTree = ""; }; 94 | D9D56EF11CC0991A003CE68D /* TBRURLProtocol.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TBRURLProtocol.m; sourceTree = ""; }; 95 | D9D56F001CC09AC7003CE68D /* TBRMonitorFramework.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = TBRMonitorFramework.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 96 | D9D56F021CC09AC7003CE68D /* TBRMonitorFramework.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TBRMonitorFramework.h; sourceTree = ""; }; 97 | D9D56F041CC09AC7003CE68D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 98 | /* End PBXFileReference section */ 99 | 100 | /* Begin PBXFrameworksBuildPhase section */ 101 | D9D56EB01CC098EC003CE68D /* Frameworks */ = { 102 | isa = PBXFrameworksBuildPhase; 103 | buildActionMask = 2147483647; 104 | files = ( 105 | ); 106 | runOnlyForDeploymentPostprocessing = 0; 107 | }; 108 | D9D56EC91CC098EC003CE68D /* Frameworks */ = { 109 | isa = PBXFrameworksBuildPhase; 110 | buildActionMask = 2147483647; 111 | files = ( 112 | ); 113 | runOnlyForDeploymentPostprocessing = 0; 114 | }; 115 | D9D56EFC1CC09AC7003CE68D /* Frameworks */ = { 116 | isa = PBXFrameworksBuildPhase; 117 | buildActionMask = 2147483647; 118 | files = ( 119 | ); 120 | runOnlyForDeploymentPostprocessing = 0; 121 | }; 122 | /* End PBXFrameworksBuildPhase section */ 123 | 124 | /* Begin PBXGroup section */ 125 | D9D56EAA1CC098EC003CE68D = { 126 | isa = PBXGroup; 127 | children = ( 128 | D9D56EDB1CC0991A003CE68D /* TBRMonitorFramework */, 129 | D9D56EB51CC098EC003CE68D /* TBRMonitorExample */, 130 | D9D56ECF1CC098EC003CE68D /* TBRMonitorExampleTests */, 131 | D9D56F011CC09AC7003CE68D /* TBRMonitorFramework */, 132 | D9D56EB41CC098EC003CE68D /* Products */, 133 | ); 134 | sourceTree = ""; 135 | }; 136 | D9D56EB41CC098EC003CE68D /* Products */ = { 137 | isa = PBXGroup; 138 | children = ( 139 | D9D56EB31CC098EC003CE68D /* TBRMonitorExample.app */, 140 | D9D56ECC1CC098EC003CE68D /* TBRMonitorExampleTests.xctest */, 141 | D9D56F001CC09AC7003CE68D /* TBRMonitorFramework.framework */, 142 | ); 143 | name = Products; 144 | sourceTree = ""; 145 | }; 146 | D9D56EB51CC098EC003CE68D /* TBRMonitorExample */ = { 147 | isa = PBXGroup; 148 | children = ( 149 | D9D56EB91CC098EC003CE68D /* AppDelegate.h */, 150 | D9D56EBA1CC098EC003CE68D /* AppDelegate.m */, 151 | D9D56EBC1CC098EC003CE68D /* ViewController.h */, 152 | D9D56EBD1CC098EC003CE68D /* ViewController.m */, 153 | D9D56EBF1CC098EC003CE68D /* Main.storyboard */, 154 | D9D56EC21CC098EC003CE68D /* Assets.xcassets */, 155 | D9D56EC41CC098EC003CE68D /* LaunchScreen.storyboard */, 156 | D9D56EC71CC098EC003CE68D /* Info.plist */, 157 | D9D56EB61CC098EC003CE68D /* Supporting Files */, 158 | ); 159 | path = TBRMonitorExample; 160 | sourceTree = ""; 161 | }; 162 | D9D56EB61CC098EC003CE68D /* Supporting Files */ = { 163 | isa = PBXGroup; 164 | children = ( 165 | D9D56EB71CC098EC003CE68D /* main.m */, 166 | ); 167 | name = "Supporting Files"; 168 | sourceTree = ""; 169 | }; 170 | D9D56ECF1CC098EC003CE68D /* TBRMonitorExampleTests */ = { 171 | isa = PBXGroup; 172 | children = ( 173 | D9D56ED01CC098EC003CE68D /* TBRMonitorExampleTests.m */, 174 | D9D56ED21CC098EC003CE68D /* Info.plist */, 175 | ); 176 | path = TBRMonitorExampleTests; 177 | sourceTree = ""; 178 | }; 179 | D9D56EDB1CC0991A003CE68D /* TBRMonitorFramework */ = { 180 | isa = PBXGroup; 181 | children = ( 182 | D9D56EDC1CC0991A003CE68D /* TBRCatogory */, 183 | D9D56EE11CC0991A003CE68D /* TBRElectricity */, 184 | D9D56EE41CC0991A003CE68D /* TBREnvConfig.h */, 185 | D9D56EE51CC0991A003CE68D /* TBREnvConfig.m */, 186 | D9D56EE61CC0991A003CE68D /* TBRMemory */, 187 | D9D56EE91CC0991A003CE68D /* TBRMonitor.h */, 188 | D9D56EEA1CC0991A003CE68D /* TBRMonitor.m */, 189 | D9D56EEB1CC0991A003CE68D /* TBRURL */, 190 | ); 191 | path = TBRMonitorFramework; 192 | sourceTree = ""; 193 | }; 194 | D9D56EDC1CC0991A003CE68D /* TBRCatogory */ = { 195 | isa = PBXGroup; 196 | children = ( 197 | D9D56EDD1CC0991A003CE68D /* TBR_NSObject+Property.h */, 198 | D9D56EDE1CC0991A003CE68D /* TBR_NSObject+Property.m */, 199 | D9D56EDF1CC0991A003CE68D /* TBR_NSString+md5.h */, 200 | D9D56EE01CC0991A003CE68D /* TBR_NSString+md5.m */, 201 | ); 202 | path = TBRCatogory; 203 | sourceTree = ""; 204 | }; 205 | D9D56EE11CC0991A003CE68D /* TBRElectricity */ = { 206 | isa = PBXGroup; 207 | children = ( 208 | D9D56EE21CC0991A003CE68D /* TBRElectricity.h */, 209 | D9D56EE31CC0991A003CE68D /* TBRElectricity.m */, 210 | ); 211 | path = TBRElectricity; 212 | sourceTree = ""; 213 | }; 214 | D9D56EE61CC0991A003CE68D /* TBRMemory */ = { 215 | isa = PBXGroup; 216 | children = ( 217 | D9D56EE71CC0991A003CE68D /* TBRDeviceUsage.h */, 218 | D9D56EE81CC0991A003CE68D /* TBRDeviceUsage.m */, 219 | ); 220 | path = TBRMemory; 221 | sourceTree = ""; 222 | }; 223 | D9D56EEB1CC0991A003CE68D /* TBRURL */ = { 224 | isa = PBXGroup; 225 | children = ( 226 | D9D56EEC1CC0991A003CE68D /* TBRURLCollectionManager.h */, 227 | D9D56EED1CC0991A003CE68D /* TBRURLCollectionManager.m */, 228 | D9D56EEE1CC0991A003CE68D /* TBRURLGuard.h */, 229 | D9D56EEF1CC0991A003CE68D /* TBRURLGuard.m */, 230 | D9D56EF01CC0991A003CE68D /* TBRURLProtocol.h */, 231 | D9D56EF11CC0991A003CE68D /* TBRURLProtocol.m */, 232 | ); 233 | path = TBRURL; 234 | sourceTree = ""; 235 | }; 236 | D9D56F011CC09AC7003CE68D /* TBRMonitorFramework */ = { 237 | isa = PBXGroup; 238 | children = ( 239 | D9D56F021CC09AC7003CE68D /* TBRMonitorFramework.h */, 240 | D9D56F041CC09AC7003CE68D /* Info.plist */, 241 | ); 242 | path = TBRMonitorFramework; 243 | sourceTree = ""; 244 | }; 245 | /* End PBXGroup section */ 246 | 247 | /* Begin PBXHeadersBuildPhase section */ 248 | D9D56EFD1CC09AC7003CE68D /* Headers */ = { 249 | isa = PBXHeadersBuildPhase; 250 | buildActionMask = 2147483647; 251 | files = ( 252 | D9D56F081CC09AF6003CE68D /* TBRMonitor.h in Headers */, 253 | D9D56F3B1CC0A2AA003CE68D /* TBRMonitorFramework.h in Headers */, 254 | ); 255 | runOnlyForDeploymentPostprocessing = 0; 256 | }; 257 | /* End PBXHeadersBuildPhase section */ 258 | 259 | /* Begin PBXNativeTarget section */ 260 | D9D56EB21CC098EC003CE68D /* TBRMonitorExample */ = { 261 | isa = PBXNativeTarget; 262 | buildConfigurationList = D9D56ED51CC098EC003CE68D /* Build configuration list for PBXNativeTarget "TBRMonitorExample" */; 263 | buildPhases = ( 264 | D9D56EAF1CC098EC003CE68D /* Sources */, 265 | D9D56EB01CC098EC003CE68D /* Frameworks */, 266 | D9D56EB11CC098EC003CE68D /* Resources */, 267 | ); 268 | buildRules = ( 269 | ); 270 | dependencies = ( 271 | ); 272 | name = TBRMonitorExample; 273 | productName = TBRMonitorExample; 274 | productReference = D9D56EB31CC098EC003CE68D /* TBRMonitorExample.app */; 275 | productType = "com.apple.product-type.application"; 276 | }; 277 | D9D56ECB1CC098EC003CE68D /* TBRMonitorExampleTests */ = { 278 | isa = PBXNativeTarget; 279 | buildConfigurationList = D9D56ED81CC098EC003CE68D /* Build configuration list for PBXNativeTarget "TBRMonitorExampleTests" */; 280 | buildPhases = ( 281 | D9D56EC81CC098EC003CE68D /* Sources */, 282 | D9D56EC91CC098EC003CE68D /* Frameworks */, 283 | D9D56ECA1CC098EC003CE68D /* Resources */, 284 | ); 285 | buildRules = ( 286 | ); 287 | dependencies = ( 288 | D9D56ECE1CC098EC003CE68D /* PBXTargetDependency */, 289 | ); 290 | name = TBRMonitorExampleTests; 291 | productName = TBRMonitorExampleTests; 292 | productReference = D9D56ECC1CC098EC003CE68D /* TBRMonitorExampleTests.xctest */; 293 | productType = "com.apple.product-type.bundle.unit-test"; 294 | }; 295 | D9D56EFF1CC09AC7003CE68D /* TBRMonitorFramework */ = { 296 | isa = PBXNativeTarget; 297 | buildConfigurationList = D9D56F051CC09AC7003CE68D /* Build configuration list for PBXNativeTarget "TBRMonitorFramework" */; 298 | buildPhases = ( 299 | D9D56EFB1CC09AC7003CE68D /* Sources */, 300 | D9D56EFC1CC09AC7003CE68D /* Frameworks */, 301 | D9D56EFD1CC09AC7003CE68D /* Headers */, 302 | D9D56EFE1CC09AC7003CE68D /* Resources */, 303 | ); 304 | buildRules = ( 305 | ); 306 | dependencies = ( 307 | ); 308 | name = TBRMonitorFramework; 309 | productName = TBRMonitorFramework; 310 | productReference = D9D56F001CC09AC7003CE68D /* TBRMonitorFramework.framework */; 311 | productType = "com.apple.product-type.framework"; 312 | }; 313 | /* End PBXNativeTarget section */ 314 | 315 | /* Begin PBXProject section */ 316 | D9D56EAB1CC098EC003CE68D /* Project object */ = { 317 | isa = PBXProject; 318 | attributes = { 319 | LastUpgradeCheck = 0730; 320 | ORGANIZATIONNAME = "Alibaba-inc Literature"; 321 | TargetAttributes = { 322 | D9D36DF11CC62CD000E7AF10 = { 323 | CreatedOnToolsVersion = 7.3; 324 | }; 325 | D9D56EB21CC098EC003CE68D = { 326 | CreatedOnToolsVersion = 7.3; 327 | }; 328 | D9D56ECB1CC098EC003CE68D = { 329 | CreatedOnToolsVersion = 7.3; 330 | TestTargetID = D9D56EB21CC098EC003CE68D; 331 | }; 332 | D9D56EFF1CC09AC7003CE68D = { 333 | CreatedOnToolsVersion = 7.3; 334 | }; 335 | }; 336 | }; 337 | buildConfigurationList = D9D56EAE1CC098EC003CE68D /* Build configuration list for PBXProject "TBRMonitorExample" */; 338 | compatibilityVersion = "Xcode 3.2"; 339 | developmentRegion = English; 340 | hasScannedForEncodings = 0; 341 | knownRegions = ( 342 | en, 343 | Base, 344 | ); 345 | mainGroup = D9D56EAA1CC098EC003CE68D; 346 | productRefGroup = D9D56EB41CC098EC003CE68D /* Products */; 347 | projectDirPath = ""; 348 | projectRoot = ""; 349 | targets = ( 350 | D9D56EB21CC098EC003CE68D /* TBRMonitorExample */, 351 | D9D56ECB1CC098EC003CE68D /* TBRMonitorExampleTests */, 352 | D9D56EFF1CC09AC7003CE68D /* TBRMonitorFramework */, 353 | D9D36DF11CC62CD000E7AF10 /* TBRMonitorDocument */, 354 | ); 355 | }; 356 | /* End PBXProject section */ 357 | 358 | /* Begin PBXResourcesBuildPhase section */ 359 | D9D56EB11CC098EC003CE68D /* Resources */ = { 360 | isa = PBXResourcesBuildPhase; 361 | buildActionMask = 2147483647; 362 | files = ( 363 | D9D56EC61CC098EC003CE68D /* LaunchScreen.storyboard in Resources */, 364 | D9D56EC31CC098EC003CE68D /* Assets.xcassets in Resources */, 365 | D9D56EC11CC098EC003CE68D /* Main.storyboard in Resources */, 366 | ); 367 | runOnlyForDeploymentPostprocessing = 0; 368 | }; 369 | D9D56ECA1CC098EC003CE68D /* Resources */ = { 370 | isa = PBXResourcesBuildPhase; 371 | buildActionMask = 2147483647; 372 | files = ( 373 | ); 374 | runOnlyForDeploymentPostprocessing = 0; 375 | }; 376 | D9D56EFE1CC09AC7003CE68D /* Resources */ = { 377 | isa = PBXResourcesBuildPhase; 378 | buildActionMask = 2147483647; 379 | files = ( 380 | ); 381 | runOnlyForDeploymentPostprocessing = 0; 382 | }; 383 | /* End PBXResourcesBuildPhase section */ 384 | 385 | /* Begin PBXShellScriptBuildPhase section */ 386 | D9D36DF61CC62CE800E7AF10 /* ShellScript */ = { 387 | isa = PBXShellScriptBuildPhase; 388 | buildActionMask = 2147483647; 389 | files = ( 390 | ); 391 | inputPaths = ( 392 | ); 393 | outputPaths = ( 394 | ); 395 | runOnlyForDeploymentPostprocessing = 0; 396 | shellPath = /bin/sh; 397 | shellScript = "#appledoc Xcode script\n# Start constants\ncompany=\"Alibaba\";\ncompanyID=\"com.alibaba-inc\";\ncompanyURL=\"http://\";\ntarget=\"iphoneos\";\n#target=\"macosx\";\noutputPath=\"./Help\";\n# End constants\n/usr/local/bin/appledoc \\\n--project-name \"${PROJECT_NAME}\" \\\n--project-company \"${company}\" \\\n--company-id \"${companyID}\" \\\n--docset-atom-filename \"${company}.atom\" \\\n--docset-feed-url \"${companyURL}/${company}/%DOCSETATOMFILENAME\" \\\n--docset-package-url \"${companyURL}/${company}/%DOCSETPACKAGEFILENAME\" \\\n--docset-fallback-url \"${companyURL}/${company}\" \\\n--output \"${outputPath}\" \\\n--publish-docset \\\n--docset-platform-family \"${target}\" \\\n--logformat xcode \\\n--keep-intermediate-files \\\n--no-repeat-first-par \\\n--no-warn-invalid-crossref \\\n--exit-threshold 2 \\\n\"${PROJECT_DIR}\""; 398 | }; 399 | /* End PBXShellScriptBuildPhase section */ 400 | 401 | /* Begin PBXSourcesBuildPhase section */ 402 | D9D56EAF1CC098EC003CE68D /* Sources */ = { 403 | isa = PBXSourcesBuildPhase; 404 | buildActionMask = 2147483647; 405 | files = ( 406 | D9D56EF61CC0991A003CE68D /* TBRDeviceUsage.m in Sources */, 407 | D9D56EBE1CC098EC003CE68D /* ViewController.m in Sources */, 408 | D9D56EF71CC0991A003CE68D /* TBRMonitor.m in Sources */, 409 | D9D56EF21CC0991A003CE68D /* TBR_NSObject+Property.m in Sources */, 410 | D9D56EF91CC0991A003CE68D /* TBRURLGuard.m in Sources */, 411 | D9D56EF51CC0991A003CE68D /* TBREnvConfig.m in Sources */, 412 | D9D56EBB1CC098EC003CE68D /* AppDelegate.m in Sources */, 413 | D9D56EF81CC0991A003CE68D /* TBRURLCollectionManager.m in Sources */, 414 | D9D56EFA1CC0991A003CE68D /* TBRURLProtocol.m in Sources */, 415 | D9D56EF31CC0991A003CE68D /* TBR_NSString+md5.m in Sources */, 416 | D9D56EF41CC0991A003CE68D /* TBRElectricity.m in Sources */, 417 | D9D56EB81CC098EC003CE68D /* main.m in Sources */, 418 | ); 419 | runOnlyForDeploymentPostprocessing = 0; 420 | }; 421 | D9D56EC81CC098EC003CE68D /* Sources */ = { 422 | isa = PBXSourcesBuildPhase; 423 | buildActionMask = 2147483647; 424 | files = ( 425 | D9D56ED11CC098EC003CE68D /* TBRMonitorExampleTests.m in Sources */, 426 | ); 427 | runOnlyForDeploymentPostprocessing = 0; 428 | }; 429 | D9D56EFB1CC09AC7003CE68D /* Sources */ = { 430 | isa = PBXSourcesBuildPhase; 431 | buildActionMask = 2147483647; 432 | files = ( 433 | D9D56F091CC09B0C003CE68D /* TBR_NSObject+Property.m in Sources */, 434 | D9D56F0A1CC09B0C003CE68D /* TBR_NSString+md5.m in Sources */, 435 | D9D56F0B1CC09B0C003CE68D /* TBRElectricity.m in Sources */, 436 | D9D56F0C1CC09B0C003CE68D /* TBREnvConfig.m in Sources */, 437 | D9D56F0D1CC09B0D003CE68D /* TBRDeviceUsage.m in Sources */, 438 | D9D56F0E1CC09B0D003CE68D /* TBRMonitor.m in Sources */, 439 | D9D56F0F1CC09B0D003CE68D /* TBRURLCollectionManager.m in Sources */, 440 | D9D56F101CC09B0D003CE68D /* TBRURLGuard.m in Sources */, 441 | D9D56F111CC09B0D003CE68D /* TBRURLProtocol.m in Sources */, 442 | ); 443 | runOnlyForDeploymentPostprocessing = 0; 444 | }; 445 | /* End PBXSourcesBuildPhase section */ 446 | 447 | /* Begin PBXTargetDependency section */ 448 | D9D56ECE1CC098EC003CE68D /* PBXTargetDependency */ = { 449 | isa = PBXTargetDependency; 450 | target = D9D56EB21CC098EC003CE68D /* TBRMonitorExample */; 451 | targetProxy = D9D56ECD1CC098EC003CE68D /* PBXContainerItemProxy */; 452 | }; 453 | /* End PBXTargetDependency section */ 454 | 455 | /* Begin PBXVariantGroup section */ 456 | D9D56EBF1CC098EC003CE68D /* Main.storyboard */ = { 457 | isa = PBXVariantGroup; 458 | children = ( 459 | D9D56EC01CC098EC003CE68D /* Base */, 460 | ); 461 | name = Main.storyboard; 462 | sourceTree = ""; 463 | }; 464 | D9D56EC41CC098EC003CE68D /* LaunchScreen.storyboard */ = { 465 | isa = PBXVariantGroup; 466 | children = ( 467 | D9D56EC51CC098EC003CE68D /* Base */, 468 | ); 469 | name = LaunchScreen.storyboard; 470 | sourceTree = ""; 471 | }; 472 | /* End PBXVariantGroup section */ 473 | 474 | /* Begin XCBuildConfiguration section */ 475 | D9D36DF21CC62CD000E7AF10 /* Debug */ = { 476 | isa = XCBuildConfiguration; 477 | buildSettings = { 478 | PRODUCT_NAME = "$(TARGET_NAME)"; 479 | }; 480 | name = Debug; 481 | }; 482 | D9D36DF31CC62CD000E7AF10 /* Release */ = { 483 | isa = XCBuildConfiguration; 484 | buildSettings = { 485 | PRODUCT_NAME = "$(TARGET_NAME)"; 486 | }; 487 | name = Release; 488 | }; 489 | D9D56ED31CC098EC003CE68D /* Debug */ = { 490 | isa = XCBuildConfiguration; 491 | buildSettings = { 492 | ALWAYS_SEARCH_USER_PATHS = NO; 493 | CLANG_ANALYZER_NONNULL = YES; 494 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 495 | CLANG_CXX_LIBRARY = "libc++"; 496 | CLANG_ENABLE_MODULES = YES; 497 | CLANG_ENABLE_OBJC_ARC = YES; 498 | CLANG_WARN_BOOL_CONVERSION = YES; 499 | CLANG_WARN_CONSTANT_CONVERSION = YES; 500 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 501 | CLANG_WARN_EMPTY_BODY = YES; 502 | CLANG_WARN_ENUM_CONVERSION = YES; 503 | CLANG_WARN_INT_CONVERSION = YES; 504 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 505 | CLANG_WARN_UNREACHABLE_CODE = YES; 506 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 507 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 508 | COPY_PHASE_STRIP = NO; 509 | DEBUG_INFORMATION_FORMAT = dwarf; 510 | ENABLE_STRICT_OBJC_MSGSEND = YES; 511 | ENABLE_TESTABILITY = YES; 512 | GCC_C_LANGUAGE_STANDARD = gnu99; 513 | GCC_DYNAMIC_NO_PIC = NO; 514 | GCC_NO_COMMON_BLOCKS = YES; 515 | GCC_OPTIMIZATION_LEVEL = 0; 516 | GCC_PREPROCESSOR_DEFINITIONS = ( 517 | "DEBUG=1", 518 | "$(inherited)", 519 | ); 520 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 521 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 522 | GCC_WARN_UNDECLARED_SELECTOR = YES; 523 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 524 | GCC_WARN_UNUSED_FUNCTION = YES; 525 | GCC_WARN_UNUSED_VARIABLE = YES; 526 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 527 | MTL_ENABLE_DEBUG_INFO = YES; 528 | ONLY_ACTIVE_ARCH = YES; 529 | SDKROOT = iphoneos; 530 | TARGETED_DEVICE_FAMILY = "1,2"; 531 | }; 532 | name = Debug; 533 | }; 534 | D9D56ED41CC098EC003CE68D /* Release */ = { 535 | isa = XCBuildConfiguration; 536 | buildSettings = { 537 | ALWAYS_SEARCH_USER_PATHS = NO; 538 | CLANG_ANALYZER_NONNULL = YES; 539 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 540 | CLANG_CXX_LIBRARY = "libc++"; 541 | CLANG_ENABLE_MODULES = YES; 542 | CLANG_ENABLE_OBJC_ARC = YES; 543 | CLANG_WARN_BOOL_CONVERSION = YES; 544 | CLANG_WARN_CONSTANT_CONVERSION = YES; 545 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 546 | CLANG_WARN_EMPTY_BODY = YES; 547 | CLANG_WARN_ENUM_CONVERSION = YES; 548 | CLANG_WARN_INT_CONVERSION = YES; 549 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 550 | CLANG_WARN_UNREACHABLE_CODE = YES; 551 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 552 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 553 | COPY_PHASE_STRIP = NO; 554 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 555 | ENABLE_NS_ASSERTIONS = NO; 556 | ENABLE_STRICT_OBJC_MSGSEND = YES; 557 | GCC_C_LANGUAGE_STANDARD = gnu99; 558 | GCC_NO_COMMON_BLOCKS = YES; 559 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 560 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 561 | GCC_WARN_UNDECLARED_SELECTOR = YES; 562 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 563 | GCC_WARN_UNUSED_FUNCTION = YES; 564 | GCC_WARN_UNUSED_VARIABLE = YES; 565 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 566 | MTL_ENABLE_DEBUG_INFO = NO; 567 | SDKROOT = iphoneos; 568 | TARGETED_DEVICE_FAMILY = "1,2"; 569 | VALIDATE_PRODUCT = YES; 570 | }; 571 | name = Release; 572 | }; 573 | D9D56ED61CC098EC003CE68D /* Debug */ = { 574 | isa = XCBuildConfiguration; 575 | buildSettings = { 576 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 577 | INFOPLIST_FILE = TBRMonitorExample/Info.plist; 578 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 579 | PRODUCT_BUNDLE_IDENTIFIER = "Alibaba-inc.TBRMonitorExample"; 580 | PRODUCT_NAME = "$(TARGET_NAME)"; 581 | }; 582 | name = Debug; 583 | }; 584 | D9D56ED71CC098EC003CE68D /* Release */ = { 585 | isa = XCBuildConfiguration; 586 | buildSettings = { 587 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 588 | INFOPLIST_FILE = TBRMonitorExample/Info.plist; 589 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 590 | PRODUCT_BUNDLE_IDENTIFIER = "Alibaba-inc.TBRMonitorExample"; 591 | PRODUCT_NAME = "$(TARGET_NAME)"; 592 | }; 593 | name = Release; 594 | }; 595 | D9D56ED91CC098EC003CE68D /* Debug */ = { 596 | isa = XCBuildConfiguration; 597 | buildSettings = { 598 | BUNDLE_LOADER = "$(TEST_HOST)"; 599 | INFOPLIST_FILE = TBRMonitorExampleTests/Info.plist; 600 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 601 | PRODUCT_BUNDLE_IDENTIFIER = "Alibaba-inc.TBRMonitorExampleTests"; 602 | PRODUCT_NAME = "$(TARGET_NAME)"; 603 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/TBRMonitorExample.app/TBRMonitorExample"; 604 | }; 605 | name = Debug; 606 | }; 607 | D9D56EDA1CC098EC003CE68D /* Release */ = { 608 | isa = XCBuildConfiguration; 609 | buildSettings = { 610 | BUNDLE_LOADER = "$(TEST_HOST)"; 611 | INFOPLIST_FILE = TBRMonitorExampleTests/Info.plist; 612 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 613 | PRODUCT_BUNDLE_IDENTIFIER = "Alibaba-inc.TBRMonitorExampleTests"; 614 | PRODUCT_NAME = "$(TARGET_NAME)"; 615 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/TBRMonitorExample.app/TBRMonitorExample"; 616 | }; 617 | name = Release; 618 | }; 619 | D9D56F061CC09AC7003CE68D /* Debug */ = { 620 | isa = XCBuildConfiguration; 621 | buildSettings = { 622 | CURRENT_PROJECT_VERSION = 1; 623 | DEFINES_MODULE = YES; 624 | DYLIB_COMPATIBILITY_VERSION = 1; 625 | DYLIB_CURRENT_VERSION = 1; 626 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 627 | INFOPLIST_FILE = TBRMonitorFramework/Info.plist; 628 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 629 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 630 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 631 | OTHER_LDFLAGS = "-all_load"; 632 | PRODUCT_BUNDLE_IDENTIFIER = "Alibaba-inc.TBRMonitorFramework"; 633 | PRODUCT_NAME = TBRMonitorFramework; 634 | SKIP_INSTALL = YES; 635 | VERSIONING_SYSTEM = "apple-generic"; 636 | VERSION_INFO_PREFIX = ""; 637 | }; 638 | name = Debug; 639 | }; 640 | D9D56F071CC09AC7003CE68D /* Release */ = { 641 | isa = XCBuildConfiguration; 642 | buildSettings = { 643 | CURRENT_PROJECT_VERSION = 1; 644 | DEFINES_MODULE = YES; 645 | DYLIB_COMPATIBILITY_VERSION = 1; 646 | DYLIB_CURRENT_VERSION = 1; 647 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 648 | INFOPLIST_FILE = TBRMonitorFramework/Info.plist; 649 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 650 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 651 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 652 | OTHER_LDFLAGS = "-all_load"; 653 | PRODUCT_BUNDLE_IDENTIFIER = "Alibaba-inc.TBRMonitorFramework"; 654 | PRODUCT_NAME = TBRMonitorFramework; 655 | SKIP_INSTALL = YES; 656 | VERSIONING_SYSTEM = "apple-generic"; 657 | VERSION_INFO_PREFIX = ""; 658 | }; 659 | name = Release; 660 | }; 661 | /* End XCBuildConfiguration section */ 662 | 663 | /* Begin XCConfigurationList section */ 664 | D9D36DF41CC62CD000E7AF10 /* Build configuration list for PBXAggregateTarget "TBRMonitorDocument" */ = { 665 | isa = XCConfigurationList; 666 | buildConfigurations = ( 667 | D9D36DF21CC62CD000E7AF10 /* Debug */, 668 | D9D36DF31CC62CD000E7AF10 /* Release */, 669 | ); 670 | defaultConfigurationIsVisible = 0; 671 | }; 672 | D9D56EAE1CC098EC003CE68D /* Build configuration list for PBXProject "TBRMonitorExample" */ = { 673 | isa = XCConfigurationList; 674 | buildConfigurations = ( 675 | D9D56ED31CC098EC003CE68D /* Debug */, 676 | D9D56ED41CC098EC003CE68D /* Release */, 677 | ); 678 | defaultConfigurationIsVisible = 0; 679 | defaultConfigurationName = Release; 680 | }; 681 | D9D56ED51CC098EC003CE68D /* Build configuration list for PBXNativeTarget "TBRMonitorExample" */ = { 682 | isa = XCConfigurationList; 683 | buildConfigurations = ( 684 | D9D56ED61CC098EC003CE68D /* Debug */, 685 | D9D56ED71CC098EC003CE68D /* Release */, 686 | ); 687 | defaultConfigurationIsVisible = 0; 688 | defaultConfigurationName = Release; 689 | }; 690 | D9D56ED81CC098EC003CE68D /* Build configuration list for PBXNativeTarget "TBRMonitorExampleTests" */ = { 691 | isa = XCConfigurationList; 692 | buildConfigurations = ( 693 | D9D56ED91CC098EC003CE68D /* Debug */, 694 | D9D56EDA1CC098EC003CE68D /* Release */, 695 | ); 696 | defaultConfigurationIsVisible = 0; 697 | defaultConfigurationName = Release; 698 | }; 699 | D9D56F051CC09AC7003CE68D /* Build configuration list for PBXNativeTarget "TBRMonitorFramework" */ = { 700 | isa = XCConfigurationList; 701 | buildConfigurations = ( 702 | D9D56F061CC09AC7003CE68D /* Debug */, 703 | D9D56F071CC09AC7003CE68D /* Release */, 704 | ); 705 | defaultConfigurationIsVisible = 0; 706 | defaultConfigurationName = Release; 707 | }; 708 | /* End XCConfigurationList section */ 709 | }; 710 | rootObject = D9D56EAB1CC098EC003CE68D /* Project object */; 711 | } 712 | -------------------------------------------------------------------------------- /TBRMonitorExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /TBRMonitorExample.xcodeproj/project.xcworkspace/xcuserdata/hwh.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huang1988519/TBRMonitor/2e473a609e390a18516cf336a6c4ac6eb9b69b5c/TBRMonitorExample.xcodeproj/project.xcworkspace/xcuserdata/hwh.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /TBRMonitorExample.xcodeproj/xcshareddata/xcschemes/TBRMonitorFramework.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 70 | 71 | 72 | 73 | 75 | 76 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /TBRMonitorExample.xcodeproj/xcuserdata/hwh.xcuserdatad/xcschemes/TBRMonitorDocument.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 70 | 71 | 72 | 73 | 75 | 76 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /TBRMonitorExample.xcodeproj/xcuserdata/hwh.xcuserdatad/xcschemes/TBRMonitorExample.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 64 | 66 | 72 | 73 | 74 | 75 | 76 | 77 | 83 | 85 | 91 | 92 | 93 | 94 | 96 | 97 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /TBRMonitorExample.xcodeproj/xcuserdata/hwh.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | TBRMonitorDocument.xcscheme 8 | 9 | orderHint 10 | 2 11 | 12 | TBRMonitorExample.xcscheme 13 | 14 | orderHint 15 | 0 16 | 17 | TBRMonitorFramework.xcscheme_^#shared#^_ 18 | 19 | orderHint 20 | 1 21 | 22 | 23 | SuppressBuildableAutocreation 24 | 25 | D9D36DF11CC62CD000E7AF10 26 | 27 | primary 28 | 29 | 30 | D9D56EB21CC098EC003CE68D 31 | 32 | primary 33 | 34 | 35 | D9D56ECB1CC098EC003CE68D 36 | 37 | primary 38 | 39 | 40 | D9D56EFF1CC09AC7003CE68D 41 | 42 | primary 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /TBRMonitorExample/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // TBRMonitorExample 4 | // 5 | // Created by huanwh on 16/4/15. 6 | // Copyright © 2016年 Alibaba-inc Literature. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /TBRMonitorExample/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // TBRMonitorExample 4 | // 5 | // Created by huanwh on 16/4/15. 6 | // Copyright © 2016年 Alibaba-inc Literature. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import "TBRMonitor.h" 11 | 12 | @interface AppDelegate () 13 | 14 | @end 15 | 16 | @implementation AppDelegate 17 | 18 | #pragma mark - TBRMonitorDeletate 19 | -(void)applicationRecieveBadUrl:(NSDictionary *)dic { 20 | NSLog(@"异常URL : %@", dic); 21 | } 22 | -(void)applicationElectricityChanged:(float)level { 23 | NSLog(@"当前电量 %f",level); 24 | } 25 | -(void)applicationMemoryUsed:(float)usedSpace free:(float)freeSpace cpu:(float)cpuUsage{ 26 | NSLog(@"used: %f free: %f cpu: %f",usedSpace, freeSpace,cpuUsage); 27 | } 28 | #pragma mark - 29 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 30 | [TBRMonitor startMonotorWithDelegate:self]; 31 | return YES; 32 | } 33 | 34 | - (void)applicationWillResignActive:(UIApplication *)application { 35 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 36 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 37 | } 38 | 39 | - (void)applicationDidEnterBackground:(UIApplication *)application { 40 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 41 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 42 | } 43 | 44 | - (void)applicationWillEnterForeground:(UIApplication *)application { 45 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 46 | } 47 | 48 | - (void)applicationDidBecomeActive:(UIApplication *)application { 49 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 50 | } 51 | 52 | - (void)applicationWillTerminate:(UIApplication *)application { 53 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 54 | } 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /TBRMonitorExample/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "ipad", 35 | "size" : "29x29", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "29x29", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "40x40", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "40x40", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "76x76", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "76x76", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /TBRMonitorExample/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /TBRMonitorExample/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /TBRMonitorExample/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | NSAppTransportSecurity 26 | 27 | NSAllowsArbitraryLoads 28 | 29 | 30 | UILaunchStoryboardName 31 | LaunchScreen 32 | UIMainStoryboardFile 33 | Main 34 | UIRequiredDeviceCapabilities 35 | 36 | armv7 37 | 38 | UISupportedInterfaceOrientations 39 | 40 | UIInterfaceOrientationPortrait 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | UISupportedInterfaceOrientations~ipad 45 | 46 | UIInterfaceOrientationPortrait 47 | UIInterfaceOrientationPortraitUpsideDown 48 | UIInterfaceOrientationLandscapeLeft 49 | UIInterfaceOrientationLandscapeRight 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /TBRMonitorExample/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // TBRMonitorExample 4 | // 5 | // Created by huanwh on 16/4/15. 6 | // Copyright © 2016年 Alibaba-inc Literature. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /TBRMonitorExample/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // TBRMonitorExample 4 | // 5 | // Created by huanwh on 16/4/15. 6 | // Copyright © 2016年 Alibaba-inc Literature. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | 11 | @interface ViewController () 12 | 13 | @end 14 | 15 | @implementation ViewController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | NSArray * urlStrings = @[@"https://www.google.com", 20 | @"http://www.baidu.com", 21 | @"https://taobao.com", 22 | @"http://www.safsaf24---23423.com"]; 23 | 24 | for (NSString * urlString in urlStrings) { 25 | NSURL * url = [NSURL URLWithString:urlString]; 26 | [self startWithRequest:url]; 27 | } 28 | 29 | } 30 | 31 | -(void)startWithRequest:(NSURL *)url { 32 | if (!url) { 33 | return; 34 | } 35 | 36 | NSURLRequest * request = [NSURLRequest requestWithURL:url]; 37 | NSURLSession * session = [NSURLSession sharedSession]; 38 | 39 | NSURLSessionTask * task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { 40 | if ([response isMemberOfClass:[NSHTTPURLResponse class]]) { 41 | NSHTTPURLResponse * httpResponse = (NSHTTPURLResponse *)response; 42 | NSLog(@"收到 : %ld",httpResponse.statusCode); 43 | } 44 | if (error) { 45 | NSLog(@"network Errpr: %@",[error localizedDescription]); 46 | } 47 | }]; 48 | [task resume]; 49 | } 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /TBRMonitorExample/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // TBRMonitorExample 4 | // 5 | // Created by huanwh on 16/4/15. 6 | // Copyright © 2016年 Alibaba-inc Literature. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /TBRMonitorExampleTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /TBRMonitorExampleTests/TBRMonitorExampleTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // TBRMonitorExampleTests.m 3 | // TBRMonitorExampleTests 4 | // 5 | // Created by huanwh on 16/4/15. 6 | // Copyright © 2016年 Alibaba-inc Literature. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface TBRMonitorExampleTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation TBRMonitorExampleTests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | // Put setup code here. This method is called before the invocation of each test method in the class. 20 | } 21 | 22 | - (void)tearDown { 23 | // Put teardown code here. This method is called after the invocation of each test method in the class. 24 | [super tearDown]; 25 | } 26 | 27 | - (void)testExample { 28 | // This is an example of a functional test case. 29 | // Use XCTAssert and related functions to verify your tests produce the correct results. 30 | } 31 | 32 | - (void)testPerformanceExample { 33 | // This is an example of a performance test case. 34 | [self measureBlock:^{ 35 | // Put the code you want to measure the time of here. 36 | }]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /TBRMonitorFramework/GenerateDocument.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | if [[ -n 'which brew' ]]; then 3 | if [[ -n 'which appledoc' ]]; then 4 | 5 | echo -n '输入公司名称'; 6 | read company_name; 7 | 8 | echo -n '输入公司标识'; 9 | read company_id; 10 | 11 | echo -n '输入工程名字'; 12 | read project_name; 13 | 14 | echo -n '是否需要生成苹果文档'; 15 | read isCreateDoc; 16 | 17 | if [ ${isCreateDoc} == 'yes' ] ;then 18 | echo '生成xcode 文档'; 19 | appledoc --output ./Doc --project-name ${project_name} --project-company ${project-company} --company-id ${company_id} . ; 20 | cat ./Doc/docset-installed.txt 21 | else 22 | echo '生成html文档'; 23 | appledoc --no-create-docset --output ./Doc --project-name ${project_name} --project-company ${project-company} --company-id ${company_id} . ; 24 | fi 25 | echo "当前路径为 :" 26 | pwd; 27 | 28 | else 29 | brew install appledoc; 30 | fi 31 | else 32 | echo '请先安装 brew' 33 | exit 34 | fi 35 | -------------------------------------------------------------------------------- /TBRMonitorFramework/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /TBRMonitorFramework/TBRCatogory/TBR_NSObject+Property.h: -------------------------------------------------------------------------------- 1 | // 2 | // TBR_NSObject+Property.h 3 | // Usage 4 | // 5 | // Created by huanwh on 16/4/13. 6 | // Copyright © 2016年 huanwh. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSObject (Property) 12 | - (NSArray *)properties; 13 | - (id)objectForProperty:(NSString *)propertyName; 14 | 15 | -(NSString *)jsonString; 16 | -(NSDictionary *)dictionay; 17 | @end 18 | -------------------------------------------------------------------------------- /TBRMonitorFramework/TBRCatogory/TBR_NSObject+Property.m: -------------------------------------------------------------------------------- 1 | // 2 | // TBR_NSObject+Property.m 3 | // Usage 4 | // 5 | // Created by huanwh on 16/4/13. 6 | // Copyright © 2016年 huanwh. All rights reserved. 7 | // 8 | 9 | #import "TBR_NSObject+Property.h" 10 | #import 11 | 12 | @implementation NSObject (Property) 13 | - (NSArray *)properties { 14 | // 获取当前类的所有属性 15 | unsigned int count;// 记录属性个数 16 | objc_property_t *properties = class_copyPropertyList(self.class, &count); 17 | // 遍历 18 | NSMutableArray *mArray = [NSMutableArray array]; 19 | for (int i = 0; i < count; i++) { 20 | 21 | // An opaque type that represents an Objective-C declared property. 22 | // objc_property_t 属性类型 23 | objc_property_t property = properties[i]; 24 | // 获取属性的名称 C语言字符串 25 | const char *cName = property_getName(property); 26 | // 转换为Objective C 字符串 27 | NSString *name = [NSString stringWithCString:cName encoding:NSUTF8StringEncoding]; 28 | [mArray addObject:name]; 29 | } 30 | 31 | return mArray.copy; 32 | } 33 | -(id)objectForProperty:(NSString *)propertyName { 34 | NSString * _property = [@"_" stringByAppendingString:propertyName]; 35 | const char * name = _property.UTF8String ; 36 | 37 | Ivar var = class_getInstanceVariable([self class], name); 38 | id object = object_getIvar(self, var); 39 | 40 | return [object copy]; 41 | } 42 | 43 | -(NSString *)jsonString { 44 | NSArray * properties = [NSArray arrayWithArray:[self properties]]; 45 | NSMutableDictionary * resultDic = @{}.mutableCopy; 46 | 47 | for (NSString * key in properties) { 48 | resultDic[key] = [self objectForProperty:key]; 49 | } 50 | 51 | NSError * error = nil; 52 | NSData * jsonData = [NSJSONSerialization dataWithJSONObject:resultDic options:NSJSONWritingPrettyPrinted error:&error]; 53 | if (error) { 54 | NSLog(@"[TBR LOG]node-> jsonString\n 解析json 出错: %@",error); 55 | return nil; 56 | } 57 | 58 | NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; 59 | 60 | return jsonString; 61 | } 62 | -(NSDictionary *)dictionay { 63 | NSArray * properties = [NSArray arrayWithArray:[self properties]]; 64 | NSMutableDictionary * resultDic = @{}.mutableCopy; 65 | 66 | for (NSString * key in properties) { 67 | resultDic[key] = [self objectForProperty:key]; 68 | } 69 | return resultDic.copy; 70 | } 71 | @end 72 | -------------------------------------------------------------------------------- /TBRMonitorFramework/TBRCatogory/TBR_NSString+md5.h: -------------------------------------------------------------------------------- 1 | // 2 | // TBR_NSString+md5.h 3 | // Usage 4 | // 5 | // Created by huanwh on 16/4/12. 6 | // Copyright © 2016年 huanwh. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSString (md5) 12 | - (NSString *)md5; 13 | @end 14 | -------------------------------------------------------------------------------- /TBRMonitorFramework/TBRCatogory/TBR_NSString+md5.m: -------------------------------------------------------------------------------- 1 | // 2 | // TBR_NSString+md5.m 3 | // Usage 4 | // 5 | // Created by huanwh on 16/4/12. 6 | // Copyright © 2016年 huanwh. All rights reserved. 7 | // 8 | 9 | #import "TBR_NSString+md5.h" 10 | #import 11 | 12 | @implementation NSString (md5) 13 | - (NSString *)md5 14 | { 15 | const char * pointer = [self UTF8String]; 16 | unsigned char md5Buffer[CC_MD5_DIGEST_LENGTH]; 17 | 18 | CC_MD5(pointer, (CC_LONG)strlen(pointer), md5Buffer); 19 | 20 | NSMutableString *string = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2]; 21 | for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) 22 | [string appendFormat:@"%02x",md5Buffer[i]]; 23 | 24 | return string; 25 | } 26 | @end 27 | -------------------------------------------------------------------------------- /TBRMonitorFramework/TBRElectricity/TBRElectricity.h: -------------------------------------------------------------------------------- 1 | // 2 | // TBRElectricity.h 3 | // Usage 4 | // 5 | // Created by huanwh on 16/4/11. 6 | // Copyright © 2016年 huanwh. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | typedef void (^TBElectrictiyHandle)(float); 13 | 14 | @interface TBRElectricity : NSObject 15 | /** 16 | * 设置电量阈值 17 | * 18 | * @param minLevel 电量阈值 ,默认 20% 19 | */ 20 | +(void)setMinElectricityLevel:(float)minLevel; 21 | /** 22 | * 监听电量变化 23 | * 24 | * @param electricityLevel 添加需要监听的回调 25 | * 26 | * @return 返回当前电量管理类 27 | */ 28 | +(instancetype)electricityLevel:(TBElectrictiyHandle)electricityLevel; 29 | @end 30 | 31 | extern NSString * const TBDeviceBatteryStateDidChangeNotification; 32 | -------------------------------------------------------------------------------- /TBRMonitorFramework/TBRElectricity/TBRElectricity.m: -------------------------------------------------------------------------------- 1 | // 2 | // TBRElectricity.m 3 | // Usage 4 | // 5 | // Created by huanwh on 16/4/11. 6 | // Copyright © 2016年 huanwh. All rights reserved. 7 | // 8 | 9 | #import "TBRElectricity.h" 10 | #import "TBREnvConfig.h" 11 | 12 | NSString * const TBDeviceBatteryStateDidChangeNotification = @"TBDeviceBatteryStateDidChangeNotification"; 13 | 14 | @interface TBRElectricity () 15 | @property(copy, nonatomic) TBElectrictiyHandle electricityBlock; 16 | @end 17 | 18 | 19 | @implementation TBRElectricity 20 | - (instancetype)init 21 | { 22 | self = [super init]; 23 | 24 | if (self) { 25 | } 26 | 27 | return self; 28 | } 29 | +(instancetype)shareInstance { 30 | static TBRElectricity * instance = nil; 31 | 32 | static dispatch_once_t onceToken; 33 | dispatch_once(&onceToken, ^{ 34 | instance = [TBRElectricity new]; 35 | }); 36 | 37 | return instance; 38 | } 39 | 40 | #pragma mark - public 41 | +(void)setMinElectricityLevel:(float)minLevel { 42 | [[TBREnvConfig shareInstance] setMinBatteryLevel:minLevel]; 43 | } 44 | +(instancetype)electricityLevel:(TBElectrictiyHandle)electricityLevel{ 45 | TBRElectricity * newObserver = [TBRElectricity new]; 46 | 47 | [newObserver setElectricityBlock:electricityLevel]; 48 | 49 | return newObserver; 50 | } 51 | #pragma mark - private 52 | -(void)setMinElectricityLevel:(float)minLevel { 53 | float minLevelOfElectricity = [[TBREnvConfig shareInstance] minBatteryLevel]; 54 | 55 | if (minLevel >100) { 56 | minLevelOfElectricity = 100; 57 | }else if (minLevel <0) { 58 | minLevelOfElectricity = 0; 59 | }else { 60 | minLevelOfElectricity = minLevel; 61 | } 62 | TBRLog(@"设置最小电量 %f 时发送通知",minLevelOfElectricity); 63 | [[TBREnvConfig shareInstance] setMinBatteryLevel:minLevelOfElectricity]; 64 | } 65 | -(void)electricityLevel:(TBElectrictiyHandle)electricityLevel { 66 | _electricityBlock = electricityLevel; 67 | 68 | //add notificition to observe battery change value; 69 | [[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceBatteryLevelDidChangeNotification object:nil]; 70 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(observeElectricityChanged) name:UIDeviceBatteryLevelDidChangeNotification object:nil]; 71 | } 72 | -(void)observeElectricityChanged { 73 | if (_electricityBlock) { 74 | float level = [self electricity]; 75 | TBRLog([NSString stringWithFormat:@"当前电量 %f ",level]); 76 | _electricityBlock(level); 77 | } 78 | } 79 | -(float)electricity { 80 | UIDevice * device = [UIDevice currentDevice]; 81 | 82 | device.batteryMonitoringEnabled = true; 83 | float batteryLevel = device.batteryLevel; 84 | 85 | return batteryLevel*100; 86 | } 87 | -(void)dealloc { 88 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 89 | } 90 | @end 91 | -------------------------------------------------------------------------------- /TBRMonitorFramework/TBREnvConfig.h: -------------------------------------------------------------------------------- 1 | // 2 | // TBREnvConfig.h 3 | // Usage 4 | // 5 | // Created by huanwh on 16/4/12. 6 | // Copyright © 2016年 huanwh. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface TBREnvConfig : NSObject { 12 | } 13 | 14 | #pragma mark - 电量 15 | @property (assign) float minBatteryLevel;//默认为20%,低于这个值通知注册通知的对象 16 | @property (assign) BOOL enableDebugInfo;//是否打开debug 开关。打开后,会显示debug信息 17 | 18 | #pragma mark - URL 19 | @property (copy,readonly) NSMutableArray * allowHosts;//设定需要监控的host 列表 20 | 21 | +(instancetype)shareInstance; 22 | @end 23 | 24 | 25 | extern NSString * const BundleIdentify; 26 | 27 | 28 | 29 | #ifdef TBR_DEBUG 30 | #define TBRLog(FORMAT, ...) fprintf(stderr,"\n\n||===========================\n||\n|| [TBR USAGE]\n|| %s\n||\n||===========================\n", [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]); 31 | #else 32 | #define TBRLog(...) 33 | #endif 34 | -------------------------------------------------------------------------------- /TBRMonitorFramework/TBREnvConfig.m: -------------------------------------------------------------------------------- 1 | // 2 | // TBREnvConfig.m 3 | // Usage 4 | // 5 | // Created by huanwh on 16/4/12. 6 | // Copyright © 2016年 huanwh. All rights reserved. 7 | // 8 | 9 | #import "TBREnvConfig.h" 10 | NSString * const BundleIdentify = @"[TBR USAGE]"; 11 | 12 | @implementation TBREnvConfig 13 | 14 | static TBREnvConfig * instance = nil; 15 | +(instancetype)shareInstance { 16 | static dispatch_once_t onceToken; 17 | dispatch_once(&onceToken, ^{ 18 | instance = [[TBREnvConfig alloc] init]; 19 | }); 20 | 21 | return instance; 22 | } 23 | 24 | -(instancetype)init { 25 | self = [super init]; 26 | if (self) { 27 | _enableDebugInfo = true; 28 | dispatch_async(dispatch_get_global_queue(0, 0), ^{ 29 | [self configAllowHosts]; 30 | }); 31 | } 32 | return self; 33 | } 34 | -(void)setHosts:(NSArray *)hosts { 35 | if (!hosts) { 36 | return; 37 | } 38 | _allowHosts = [NSMutableArray arrayWithArray:hosts]; 39 | } 40 | 41 | #pragma mark - 42 | -(void)configAllowHosts { 43 | @synchronized (self) { 44 | NSString * path = [[NSBundle mainBundle] pathForResource:@"Hosts" ofType:@"plist"]; 45 | if (path == nil) { 46 | 47 | NSLog(@"查无配置host 文件,监控所以host请求\n--如果需要监控指定host,请在main bundle下创建 Hosts.plist 文件,root 为 NSArray"); 48 | return ; 49 | } 50 | NSArray * hosts = [NSArray arrayWithContentsOfFile:path]; 51 | if (!hosts) { 52 | NSLog(@"初始化 host 过滤表 为空"); 53 | return; 54 | } 55 | if (![hosts isKindOfClass:[NSArray class]]) { 56 | NSLog(@"配置host格式错误,要求配置为NSArray -> %@",[hosts class]); 57 | #ifdef DEBUG 58 | NSAssert(true, @"配置host格式错误,要求配置为NSArray"); 59 | #endif 60 | return; 61 | } 62 | TBRLog(@"%@",hosts); 63 | [self setHosts:hosts]; 64 | } 65 | } 66 | @end 67 | -------------------------------------------------------------------------------- /TBRMonitorFramework/TBRMemory/TBRDeviceUsage.h: -------------------------------------------------------------------------------- 1 | // 2 | // TBRMemory.h 3 | // Usage 4 | // 5 | // Created by huanwh on 16/4/13. 6 | // Copyright © 2016年 huanwh. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef void (^TBRDeviceInfoHandle)(float usage,float free,float cpuUsage); 12 | 13 | @interface TBRDeviceUsage : NSObject { 14 | 15 | } 16 | +(instancetype)observeMemoryHandle:(TBRDeviceInfoHandle)observer; 17 | @end 18 | -------------------------------------------------------------------------------- /TBRMonitorFramework/TBRMemory/TBRDeviceUsage.m: -------------------------------------------------------------------------------- 1 | // 2 | // TBRMemory.m 3 | // Usage 4 | // 5 | // Created by huanwh on 16/4/13. 6 | // Copyright © 2016年 huanwh. All rights reserved. 7 | // 8 | 9 | #import "TBRDeviceUsage.h" 10 | #import 11 | 12 | @interface TBRDeviceUsage () { 13 | NSTimer * _timer; 14 | } 15 | @property(nonatomic, copy) TBRDeviceInfoHandle observeHandle; 16 | @property(nonatomic, assign) float interval; 17 | @end 18 | 19 | @implementation TBRDeviceUsage 20 | 21 | 22 | static long prevMemUsage = 0; 23 | static long curMemUsage = 0; 24 | static long memUsageDiff = 0; 25 | static long curFreeMem = 0; 26 | 27 | static long cpuUsage = 0; 28 | 29 | -(instancetype)init { 30 | self = [super init]; 31 | if (self) { 32 | _interval = 1.0;//一秒刷新一次 33 | _timer = [NSTimer scheduledTimerWithTimeInterval:_interval target:self selector:@selector(observeMemoryChanged) userInfo:nil repeats:true]; 34 | [_timer fire]; 35 | } 36 | return self; 37 | } 38 | -(void)dealloc { 39 | if (_timer && [_timer isValid]) { 40 | [_timer invalidate]; 41 | } 42 | _timer = nil; 43 | } 44 | -(instancetype)initWithMemoryHandle:(TBRDeviceInfoHandle)handle { 45 | self = [self init]; 46 | if (self) { 47 | _observeHandle = handle; 48 | } 49 | return self; 50 | } 51 | +(instancetype)observeMemoryHandle:(TBRDeviceInfoHandle)observer { 52 | return [[TBRDeviceUsage alloc] initWithMemoryHandle:observer]; 53 | } 54 | 55 | #pragma mark - private 56 | /** 57 | * 空闲内存 58 | * 59 | * @return 空闲内存。 单位bytes 60 | */ 61 | -(vm_size_t) freeMemory { 62 | mach_port_t host_port = mach_host_self(); 63 | mach_msg_type_number_t host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t); 64 | vm_size_t pagesize; 65 | vm_statistics_data_t vm_stat; 66 | 67 | host_page_size(host_port, &pagesize); 68 | (void) host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size); 69 | return vm_stat.free_count * pagesize; 70 | } 71 | /** 72 | * 已使用内存 73 | * 74 | * @return 已使用内存。 单位bytes 75 | */ 76 | -(vm_size_t) usedMemory { 77 | struct task_basic_info info; 78 | mach_msg_type_number_t size = sizeof(info); 79 | kern_return_t kerr = task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&info, &size); 80 | return (kerr == KERN_SUCCESS) ? info.resident_size : 0; // size in bytes 81 | } 82 | 83 | /** 84 | * 获取cpu 85 | * 86 | * @return cpu 使用率 87 | */ 88 | float cpu_usage() 89 | { 90 | kern_return_t kr; 91 | task_info_data_t tinfo; 92 | mach_msg_type_number_t task_info_count; 93 | 94 | task_info_count = TASK_INFO_MAX; 95 | kr = task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)tinfo, &task_info_count); 96 | if (kr != KERN_SUCCESS) { 97 | return -1; 98 | } 99 | 100 | task_basic_info_t basic_info; 101 | thread_array_t thread_list; 102 | mach_msg_type_number_t thread_count; 103 | 104 | thread_info_data_t thinfo; 105 | mach_msg_type_number_t thread_info_count; 106 | 107 | thread_basic_info_t basic_info_th; 108 | uint32_t stat_thread = 0; // Mach threads 109 | 110 | basic_info = (task_basic_info_t)tinfo; 111 | 112 | // get threads in the task 113 | kr = task_threads(mach_task_self(), &thread_list, &thread_count); 114 | if (kr != KERN_SUCCESS) { 115 | return -1; 116 | } 117 | if (thread_count > 0) 118 | stat_thread += thread_count; 119 | 120 | long tot_sec = 0; 121 | long tot_usec = 0; 122 | float tot_cpu = 0; 123 | int j; 124 | 125 | for (j = 0; j < thread_count; j++) 126 | { 127 | thread_info_count = THREAD_INFO_MAX; 128 | kr = thread_info(thread_list[j], THREAD_BASIC_INFO, 129 | (thread_info_t)thinfo, &thread_info_count); 130 | if (kr != KERN_SUCCESS) { 131 | return -1; 132 | } 133 | 134 | basic_info_th = (thread_basic_info_t)thinfo; 135 | 136 | if (!(basic_info_th->flags & TH_FLAGS_IDLE)) { 137 | tot_sec = tot_sec + basic_info_th->user_time.seconds + basic_info_th->system_time.seconds; 138 | tot_usec = tot_usec + basic_info_th->user_time.microseconds + basic_info_th->system_time.microseconds; 139 | tot_cpu = tot_cpu + basic_info_th->cpu_usage / (float)TH_USAGE_SCALE * 100.0; 140 | } 141 | 142 | } // for each thread 143 | 144 | kr = vm_deallocate(mach_task_self(), (vm_offset_t)thread_list, thread_count * sizeof(thread_t)); 145 | assert(kr == KERN_SUCCESS); 146 | 147 | 148 | return tot_cpu; 149 | } 150 | 151 | /** 152 | * 快照 153 | */ 154 | -(void) captureMemUsage { 155 | prevMemUsage = curMemUsage; 156 | curMemUsage = [self usedMemory]; 157 | memUsageDiff = curMemUsage - prevMemUsage; 158 | curFreeMem = [self freeMemory]; 159 | 160 | cpuUsage = cpu_usage(); 161 | } 162 | -(void)observeMemoryChanged { 163 | //快照 164 | [self captureMemUsage]; 165 | 166 | if (_observeHandle) { 167 | _observeHandle(curMemUsage/1024.0f,curFreeMem/1024.0f, cpuUsage); 168 | } 169 | } 170 | -(NSString*) captureMemUsageGetString{ 171 | return [self captureMemUsageGetString: @"Memory used %7.1f (%+5.0f), free %7.1f kb"]; 172 | } 173 | 174 | -(NSString*) captureMemUsageGetString:(NSString*) formatstring { 175 | [self captureMemUsage]; 176 | return [NSString stringWithFormat:formatstring,curMemUsage/1000.0f, memUsageDiff/1000.0f, curFreeMem/1000.0f]; 177 | 178 | } 179 | @end 180 | -------------------------------------------------------------------------------- /TBRMonitorFramework/TBRMonitor.h: -------------------------------------------------------------------------------- 1 | // 2 | // TBRMonitor.h 3 | // TBRMonitor 4 | // 5 | // Created by huanwh on 16/4/14. 6 | // Copyright © 2016年 Alibaba-inc. All rights reserved. 7 | // 8 | 9 | #import 10 | /** 11 | * TBRMonitor 代理方法 12 | */ 13 | @protocol TBRMonitorDelegate 14 | @required 15 | /** 16 | * TBRMonitorDelegate 必须实现次方法,以及时发现失败的URL 17 | * 18 | * @param dic 失败的URL 19 | */ 20 | -(void)applicationRecieveBadUrl:(NSDictionary *)dic; 21 | @optional 22 | /** 23 | * TBRMonitorDelegate 可选方法。当需要监听电量变化时实现此方法 24 | * 25 | * @param level 当前电量 26 | */ 27 | -(void)applicationElectricityChanged:(float)level; 28 | /** 29 | * TBRMonitorDelegate 可选方法。当需要监听RAM变化时实现此方法。 30 | * 31 | * @param usedSpace 已使用ram 32 | * @param freeSpace 剩余ram 33 | * @param cpuUsage 当前cpu性能消耗 34 | */ 35 | -(void)applicationMemoryUsed:(float)usedSpace free:(float)freeSpace cpu:(float)cpuUsage; 36 | @end 37 | 38 | /** API 暴漏接口 39 | 40 | * 电量监听类 TBRElectricity 41 | * URL 统计类 TBRURLGuard 42 | * 内存和cpu监听类为同一个 TBRDeviceUsage 43 | */ 44 | @interface TBRMonitor : NSObject 45 | /** 46 | * 不添加observer,启动 监听 47 | */ 48 | +(void)startMonotor; 49 | /** 50 | * 添加observer 并 启动监听 51 | * 52 | * @param delegate 监听者 53 | */ 54 | +(void)startMonotorWithDelegate:(id)delegate; 55 | @end 56 | 57 | 58 | -------------------------------------------------------------------------------- /TBRMonitorFramework/TBRMonitor.m: -------------------------------------------------------------------------------- 1 | // 2 | // TBRMonitor.m 3 | // TBRMonitor 4 | // 5 | // Created by huanwh on 16/4/14. 6 | // Copyright © 2016年 huanwh. All rights reserved. 7 | // 8 | 9 | #import "TBRMonitor.h" 10 | #import "TBRElectricity.h" 11 | #import "TBRDeviceUsage.h" 12 | #import "TBRURLProtocol.h" 13 | #import "TBRURLGuard.h" 14 | 15 | @interface TBRMonitor () { 16 | TBRDeviceUsage * deviceObserver; 17 | TBRElectricity * electricityObserver; 18 | } 19 | @property(nonatomic, weak) id delegate; 20 | @end 21 | 22 | @implementation TBRMonitor 23 | +(instancetype)shareInstance { 24 | static TBRMonitor * monitor = nil; 25 | static dispatch_once_t onceToken; 26 | dispatch_once(&onceToken, ^{ 27 | monitor = [[TBRMonitor alloc] init]; 28 | }); 29 | return monitor; 30 | } 31 | -(instancetype)init { 32 | self = [super init]; 33 | if (self) { 34 | } 35 | return self; 36 | } 37 | -(void)setDelegate:(id)delegate { 38 | if ([delegate respondsToSelector:@selector(applicationElectricityChanged:)]) { 39 | electricityObserver = [TBRElectricity electricityLevel:^(float level) { 40 | [delegate applicationElectricityChanged:level]; 41 | }]; 42 | } 43 | if ([delegate respondsToSelector:@selector(applicationMemoryUsed:free:cpu:)]) { 44 | deviceObserver = [TBRDeviceUsage observeMemoryHandle:^(float usage, float free, float cpuUage) { 45 | [delegate applicationMemoryUsed:usage free:free cpu:cpuUage]; 46 | }]; 47 | } 48 | 49 | [TBRURLGuard observerErrorUrlChange:^(NSDictionary * badUrl) { 50 | [delegate applicationRecieveBadUrl:badUrl]; 51 | }]; 52 | } 53 | #pragma mark - public api 54 | +(void)startMonotor { 55 | [NSURLProtocol registerClass:[TBRURLProtocol class]]; 56 | } 57 | +(void)startMonotorWithDelegate:(id)delegate { 58 | [[self class] startMonotor]; 59 | [TBRMonitor shareInstance].delegate = delegate; 60 | } 61 | @end -------------------------------------------------------------------------------- /TBRMonitorFramework/TBRMonitorFramework.h: -------------------------------------------------------------------------------- 1 | // 2 | // TBRMonitorFramework.h 3 | // TBRMonitorFramework 4 | // 5 | // Created by huanwh on 16/4/15. 6 | // Copyright © 2016年 Alibaba-inc Literature. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for TBRMonitorFramework. 12 | FOUNDATION_EXPORT double TBRMonitorFrameworkVersionNumber; 13 | 14 | //! Project version string for TBRMonitorFramework. 15 | FOUNDATION_EXPORT const unsigned char TBRMonitorFrameworkVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /TBRMonitorFramework/TBRURL/TBRURLCollectionManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // TBRURLCollectionManager.h 3 | // 负责整理用户请求 并 写入文件 4 | // 5 | // @description 6 | // 收到内存警告和app 进入后台时会刷新请求写入本地 Record.text 文件,并清空url 列表 7 | // 8 | // Created by huanwh on 16/4/12. 9 | // Copyright © 2016年 huanwh. All rights reserved. 10 | // 11 | 12 | #import 13 | 14 | @interface TBRURLCollectionManager : NSObject 15 | { 16 | NSMutableDictionary * items; 17 | 18 | } 19 | @property(assign,readonly) float interval;//间隔 20 | 21 | +(instancetype)shareInstance; 22 | 23 | /** 24 | * 网络请求监控,写文件间隔 25 | * 如果 second <=0 会暂定掉自动保存,否则自动发送 26 | * 27 | * @param second 写文件时间间隔 28 | */ 29 | +(void)setIntervalOfCheckRequests:(float)second; 30 | 31 | /** 32 | * 请求开始 33 | * 34 | * @param request 当前网络请求 35 | */ 36 | +(void)startRequest:(NSURLRequest *)request; 37 | /** 38 | * 网路请求完成并 记录 39 | * 40 | * @param request 当前网络请求 41 | */ 42 | +(void)injectFinishRequestWithRequest:(NSURLRequest *)request; 43 | /** 44 | * 网络请求收到数据并统计长度 45 | * 46 | * @param request 当前网络请求 47 | * @param length 当前接收到数据的长度 48 | */ 49 | +(void)injectRecieveDataWithRequest:(NSURLRequest *)request recieveLenght:(double)length; 50 | /** 51 | * 网络请求失败并 记录 52 | * 53 | * @param request 当前网络请求 54 | * @param error 网络失败Error 55 | */ 56 | +(void)injectFailedRequestWithRequest:(NSURLRequest *)request failedError:(NSError *)error; 57 | /** 58 | * 发出的网络请求收到 回应 并 记录 59 | * 60 | * @param response 当前网络请求收到的回应 61 | * @param request 当前网络请求 62 | */ 63 | +(void)injectReponse:(NSURLResponse *)response request:(NSURLRequest *)request; 64 | @end 65 | 66 | 67 | 68 | 69 | @interface TBRURLNode : NSObject 70 | @property(nonatomic, strong) NSString * key; 71 | @property(nonatomic, strong) NSString * urlString; 72 | @property(nonatomic, strong) NSString * httpMethed;// get and post 73 | @property(nonatomic, strong) NSNumber * stateCode; // http response 状态码 74 | @property(nonatomic, strong) NSString * stateCodeLocalDescription;//状态码本地描述 75 | @property(nonatomic, strong) NSNumber * expectedContentLength; 76 | @property(nonatomic, strong) NSString * state; 77 | @property(nonatomic, strong) NSString * errorDescription; 78 | @property(nonatomic, strong) NSNumber * recieveLength; 79 | @property(nonatomic, strong) NSNumber * recieveResponse_at; 80 | @property(nonatomic, strong) NSNumber * create_at; 81 | @property(nonatomic, strong, readonly) NSNumber * update_at; 82 | 83 | @end -------------------------------------------------------------------------------- /TBRMonitorFramework/TBRURL/TBRURLCollectionManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // TBRURLCollectionManager.m 3 | // Usage 4 | // 5 | // Created by huanwh on 16/4/12. 6 | // Copyright © 2016年 huanwh. All rights reserved. 7 | // 8 | 9 | #import "TBRURLCollectionManager.h" 10 | #import "TBR_NSString+md5.h" 11 | #import 12 | #import "TBR_NSObject+Property.h" 13 | #import "TBREnvConfig.h" 14 | #import "TBRURLGuard.h" 15 | 16 | @interface TBRURLCollectionManager () 17 | { 18 | NSFileHandle * fileWriteHandle; 19 | NSTimer * _timer; 20 | 21 | } 22 | @end 23 | @implementation TBRURLCollectionManager 24 | 25 | +(instancetype)shareInstance { 26 | static TBRURLCollectionManager * manager = nil; 27 | static dispatch_once_t onceToken; 28 | dispatch_once(&onceToken, ^{ 29 | manager = [[TBRURLCollectionManager alloc] init]; 30 | }); 31 | return manager; 32 | } 33 | -(instancetype)init { 34 | self = [super init]; 35 | if (self) { 36 | _interval = 10.0; 37 | 38 | items = [NSMutableDictionary dictionary]; 39 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(recieveMemeryWarmming) name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; 40 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(recieveMemeryWarmming) name:UIApplicationDidEnterBackgroundNotification object:nil]; 41 | } 42 | return self; 43 | } 44 | 45 | -(void)dealloc { 46 | if (_timer && [_timer isValid]) { 47 | [_timer invalidate]; 48 | _timer = nil; 49 | } 50 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 51 | } 52 | #pragma mark - class methed 53 | +(void)startRequest:(NSURLRequest *)request { 54 | [[TBRURLCollectionManager shareInstance] startRequest:request]; 55 | } 56 | +(void)setIntervalOfCheckRequests:(float)second{ 57 | [[TBRURLCollectionManager shareInstance] setSortTimeInterval:second]; 58 | } 59 | +(void)injectFinishRequestWithRequest:(NSURLRequest *)request { 60 | [[TBRURLCollectionManager shareInstance] injectFinishRequestWithRequest:request]; 61 | } 62 | +(void)injectFailedRequestWithRequest:(NSURLRequest *)request failedError:(NSError *)error { 63 | [[TBRURLCollectionManager shareInstance] injectFailedRequestWithRequest:request failedError:error]; 64 | } 65 | +(void)injectReponse:(NSURLResponse *)response request:(NSURLRequest *)request { 66 | [[TBRURLCollectionManager shareInstance] injectReponse:response request:request]; 67 | } 68 | +(void)injectRecieveDataWithRequest:(NSURLRequest *)request recieveLenght:(double)length { 69 | [[TBRURLCollectionManager shareInstance] injectRecieveDataWithRequest:request recieveLenght:length]; 70 | [TBRURLGuard appendRecieveLength:length]; 71 | } 72 | #pragma mark - private 73 | - (void)startRequest:(NSURLRequest *)request { 74 | [TBRURLGuard increaseTotalRequestCount]; 75 | 76 | [self nodeForRequest:request]; 77 | } 78 | - (void)setSortTimeInterval:(float)interval { 79 | _interval = interval; 80 | if (_interval <= 0) { 81 | TBRLog(@"关闭 自动保存失败网络请求"); 82 | if (_timer && [_timer isValid]) { 83 | [_timer invalidate]; 84 | _timer = nil; 85 | } 86 | return ; 87 | } 88 | _timer = [NSTimer scheduledTimerWithTimeInterval:interval target:self selector:@selector(recieveMemeryWarmming) userInfo:nil repeats:true]; 89 | [_timer fire]; 90 | } 91 | 92 | -(void)injectFinishRequestWithRequest:(NSURLRequest *)request { 93 | TBRURLNode * node = [self nodeForRequest:request]; 94 | node.state = @"finish"; 95 | } 96 | - (void)injectFailedRequestWithRequest:(NSURLRequest *)request failedError:(NSError *)error { 97 | TBRURLNode * node = [self nodeForRequest:request]; 98 | node.state = @"failed"; 99 | node.errorDescription = error.localizedDescription; 100 | 101 | //收集请求失败的请求 102 | [TBRURLGuard addErrorUrlDictionay:node.dictionay]; 103 | } 104 | - (void)injectReponse:(NSURLResponse *)response request:(NSURLRequest *)request { 105 | TBRURLNode * node = [self nodeForRequest:request]; 106 | if ([response isMemberOfClass:[NSHTTPURLResponse class]]) { 107 | NSHTTPURLResponse * httpResponse = (NSHTTPURLResponse *)response; 108 | node.stateCode = @(httpResponse.statusCode); 109 | node.stateCodeLocalDescription = [NSHTTPURLResponse localizedStringForStatusCode:httpResponse.statusCode]; 110 | } 111 | node.expectedContentLength = @(response.expectedContentLength); 112 | node.recieveResponse_at = @([[NSDate date] timeIntervalSince1970]); 113 | } 114 | - (void)injectRecieveDataWithRequest:(NSURLRequest *)request recieveLenght:(double)length { 115 | TBRURLNode * node = [self nodeForRequest:request]; 116 | node.recieveLength = [NSNumber numberWithDouble:[node.recieveLength doubleValue] + length]; 117 | } 118 | #pragma mark - 119 | +(NSString *)keyForRequest:(NSURLRequest *)request { 120 | if (!request) { 121 | int random = arc4random(); 122 | return [NSString stringWithFormat:@"%d",random].md5; 123 | } 124 | NSString * absolueString = request.URL.absoluteString; 125 | NSString * key = absolueString.md5; 126 | if (!key) { 127 | int random = arc4random(); 128 | key = [NSString stringWithFormat:@"%d",random].md5; 129 | } 130 | return key; 131 | } 132 | -(TBRURLNode *)nodeForRequest:(NSURLRequest *)request { 133 | NSString * key = [[self class] keyForRequest:request]; 134 | TBRURLNode * node = items[key]; 135 | if (!node) { 136 | node = [[TBRURLNode alloc] init]; 137 | node.key = key; 138 | node.urlString = [request.URL absoluteString]; 139 | if (node.urlString) { 140 | node.urlString = [request.URL relativeString]; 141 | } 142 | node.httpMethed = [request HTTPMethod]; 143 | node.create_at = @([[NSDate date] timeIntervalSince1970]); 144 | items[key] = node; 145 | } 146 | return node; 147 | } 148 | 149 | -(void)recieveMemeryWarmming { 150 | if (items.count > 0) { 151 | [self recordToFile]; 152 | } 153 | [items removeAllObjects]; 154 | TBRLog(@"收到内存警告,清楚网络记录缓存"); 155 | } 156 | -(void)recordToFile { 157 | if (items.count <= 0) { 158 | return; 159 | } 160 | 161 | NSMutableString * content = [NSMutableString string]; 162 | 163 | for (NSString * key in items.allKeys) { 164 | TBRURLNode * node = items[key]; 165 | //收集没有收到响应的请求 166 | if (node.recieveResponse_at == 0) { 167 | [TBRURLGuard addErrorUrlDictionay:node.dictionay]; 168 | } 169 | NSString * nodeJson = node.jsonString; 170 | [content appendFormat:@"%@\n",nodeJson]; 171 | } 172 | 173 | NSFileHandle *handle = [self fileHandle]; 174 | [handle writeData:[content dataUsingEncoding:NSUTF8StringEncoding]]; 175 | [handle closeFile]; 176 | } 177 | 178 | //如果是发布环境,隐藏日志文件 179 | -(NSString *)pathForRecord { 180 | #ifdef DEBUG 181 | NSString * path = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/Record.txt"]; 182 | #else 183 | NSString * path = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/.Record.txt"]; 184 | #endif 185 | 186 | BOOL isDir = NO; 187 | NSFileManager * fileManager = [NSFileManager defaultManager]; 188 | if (![fileManager fileExistsAtPath:path isDirectory:&isDir] && !isDir) { 189 | BOOL sucess = [fileManager createFileAtPath:path contents:[@"" dataUsingEncoding:NSUTF8StringEncoding] attributes:nil]; 190 | if (!sucess) { 191 | TBRLog(@"创建文件 .record.txt 失败"); 192 | #ifdef DEBUG 193 | NSAssert(sucess, @"创建文件 .record.txt 失败"); 194 | #endif 195 | } 196 | } 197 | TBRLog(@"path=%@",path); 198 | return path; 199 | } 200 | -(NSFileHandle *)fileHandle { 201 | if (!fileWriteHandle) { 202 | fileWriteHandle = [NSFileHandle fileHandleForUpdatingAtPath:[self pathForRecord]]; 203 | } 204 | [fileWriteHandle seekToEndOfFile]; 205 | 206 | return fileWriteHandle; 207 | } 208 | @end 209 | 210 | 211 | 212 | @implementation TBRURLNode 213 | -(instancetype)init { 214 | self = [super init]; 215 | if (self) { 216 | _key = @"000000000"; 217 | _urlString = @""; 218 | _httpMethed = @""; 219 | _stateCode = @0; 220 | _stateCodeLocalDescription = @""; 221 | _expectedContentLength = @(0); 222 | _state = @"init"; 223 | _errorDescription = @""; 224 | _recieveResponse_at = 0; 225 | _create_at = 0; 226 | _update_at = 0; 227 | } 228 | return self; 229 | } 230 | -(void)setCreate_at:(NSNumber *)create_at { 231 | _create_at = @10; 232 | _create_at = create_at; 233 | _update_at = create_at; 234 | } 235 | -(void)setState:(NSString *)state { 236 | _state = state; 237 | _update_at = @([[NSDate date] timeIntervalSince1970]); 238 | } 239 | @end -------------------------------------------------------------------------------- /TBRMonitorFramework/TBRURL/TBRURLGuard.h: -------------------------------------------------------------------------------- 1 | // 2 | // TBRURLGuard.h 3 | // 4 | // 负责请求数据的收集并统计 5 | // 6 | // Created by huanwh on 16/4/13. 7 | // Copyright © 2016年 huanwh. All rights reserved. 8 | // 9 | 10 | #import 11 | 12 | typedef void (^TBRURLChangeHandle)(NSDictionary * badUrl); 13 | 14 | /** 15 | * ## 统计URL 业务。包含 流量计算、请求成功次数、失败请求列表,收到失败的URL是通知观察者 16 | */ 17 | @interface TBRURLGuard : NSObject 18 | { 19 | double recieveLength;//网络消耗 20 | } 21 | /** 22 | * 收到 失败URL时,通知实现 errorUrlChangeBlock 的观察者 23 | */ 24 | @property(nonatomic, copy)TBRURLChangeHandle errorUrlChangeBlock; 25 | 26 | ///失败URL汇总列表,只读 27 | @property(nonatomic, strong, readonly) NSMutableArray * errorUrlList; 28 | 29 | @property(nonatomic, assign, readonly) NSInteger coutnOfSucessRequest; 30 | @property(nonatomic, assign, readonly) NSInteger countOfTotalRequest; 31 | /** 32 | * 创建唯一 URL统计类 33 | * 34 | * @return 唯一URL统计类 TBRURLGuard 实例 35 | */ 36 | +(instancetype)sharInstance; 37 | /** 38 | * 添加网络异常的 dictionary Of BadUrl 39 | * 40 | * @param key 异常URL dictionay 41 | */ 42 | +(void)addErrorUrlDictionay:(NSDictionary *)dictionaryOfBadUrl; 43 | /** 添加监听网络失败 监听者 44 | * 45 | * 46 | * @param errorUrlChangeBlock 网络失败回调 47 | */ 48 | +(void)observerErrorUrlChange:(TBRURLChangeHandle)errorUrlChangeBlock; 49 | #pragma mark - 成功率 50 | /** 51 | * 消耗流量递增 52 | */ 53 | +(void)increaseTotalRequestCount; 54 | /** 55 | * 返回 URL 总请求量 56 | * 57 | * @return URL总请求量 58 | */ 59 | +(NSInteger)countOfTotalRequest; 60 | #pragma mark - 流量 61 | /** 62 | * 记录网络消耗 63 | * 64 | * @param length 当次网络消耗长度 65 | */ 66 | +(void)appendRecieveLength:(double)length; 67 | /** 68 | * 获取 统计网络消耗总流量 69 | */ 70 | +(double)networkRecieveDataLenght; 71 | /** 72 | * 重新计算网络消耗 73 | */ 74 | +(void)reset; 75 | @end 76 | 77 | /** 78 | * URL 失败后 发送通知,和 observerErrorUrlChange 同时触发 79 | */ 80 | extern NSString * const TBRURLErrorStateChangedNotification; -------------------------------------------------------------------------------- /TBRMonitorFramework/TBRURL/TBRURLGuard.m: -------------------------------------------------------------------------------- 1 | // 2 | // TBRURLGuard.m 3 | // Usage 4 | // 5 | // Created by huanwh on 16/4/13. 6 | // Copyright © 2016年 huanwh. All rights reserved. 7 | // 8 | 9 | #import "TBRURLGuard.h" 10 | #import "UIKit/UIKit.h" 11 | 12 | NSString * const TBRURLErrorStateChangedNotification = @"TBRURLErrorStateChangedNotification"; 13 | static NSString * TBRURLRecieveLenghtKey = @"TBRURLRecieveLenghtKey"; 14 | 15 | @implementation TBRURLGuard 16 | 17 | +(instancetype)sharInstance { 18 | static TBRURLGuard * instance = nil; 19 | static dispatch_once_t onceToken; 20 | dispatch_once(&onceToken, ^{ 21 | instance = [[TBRURLGuard alloc] init]; 22 | }); 23 | return instance; 24 | } 25 | -(instancetype)init { 26 | self = [super init]; 27 | if (self) { 28 | _errorUrlList = [NSMutableArray array]; 29 | _countOfTotalRequest = 0; 30 | recieveLength = [[NSUserDefaults standardUserDefaults] doubleForKey:TBRURLRecieveLenghtKey]; 31 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(synchronous) name:UIApplicationDidEnterBackgroundNotification object:nil]; 32 | } 33 | return self; 34 | } 35 | #pragma mark - Public 36 | 37 | +(void)addErrorUrlDictionay:(NSDictionary *)dictionaryOfBadUrl { 38 | [[NSNotificationCenter defaultCenter] postNotificationName:TBRURLErrorStateChangedNotification object:dictionaryOfBadUrl]; 39 | [[TBRURLGuard sharInstance] addErrorUrlNode:dictionaryOfBadUrl]; 40 | } 41 | +(void)observerErrorUrlChange:(TBRURLChangeHandle)errorUrlChangeBlock { 42 | [[TBRURLGuard sharInstance] observerErrorUrlChange:errorUrlChangeBlock]; 43 | } 44 | #pragma mark - 成功率 45 | +(void)increaseTotalRequestCount { 46 | [[TBRURLGuard sharInstance] increaseCountOfTotalRequest]; 47 | } 48 | +(NSInteger)countOfTotalRequest { 49 | return [[TBRURLGuard sharInstance] countOfTotalRequest]; 50 | } 51 | #pragma mark - 流量 52 | +(void)appendRecieveLength:(double)length { 53 | [[TBRURLGuard sharInstance] appendRecieveLength:length]; 54 | } 55 | +(double)networkRecieveDataLenght { 56 | return [[TBRURLGuard sharInstance] networkRecieveDataLenght]; 57 | } 58 | +(void)reset { 59 | [[NSUserDefaults standardUserDefaults] setDouble:0 forKey:TBRURLRecieveLenghtKey]; 60 | } 61 | #pragma mark - 62 | -(void)increaseCountOfTotalRequest { 63 | _countOfTotalRequest++; 64 | } 65 | -(void)appendRecieveLength:(double)length { 66 | recieveLength += length; 67 | } 68 | -(double)networkRecieveDataLenght { 69 | return recieveLength; 70 | } 71 | -(void)synchronous { 72 | [[NSUserDefaults standardUserDefaults] setDouble:recieveLength forKey:TBRURLRecieveLenghtKey]; 73 | [[NSUserDefaults standardUserDefaults] synchronize]; 74 | } 75 | - (void)addErrorUrlNode:(NSDictionary *)badUrl { 76 | if (badUrl && ![_errorUrlList containsObject:badUrl]) { 77 | [_errorUrlList addObject:badUrl]; 78 | 79 | if (_errorUrlChangeBlock) { 80 | NSMutableDictionary * appendParams = [NSMutableDictionary dictionaryWithDictionary:badUrl]; 81 | 82 | NSDictionary * collectionDic = @{@"total":@(_countOfTotalRequest), 83 | @"error":@(_errorUrlList.count)}; 84 | appendParams[@"Collection"] = collectionDic; 85 | 86 | _errorUrlChangeBlock(appendParams); 87 | } 88 | } 89 | } 90 | - (void)observerErrorUrlChange:(TBRURLChangeHandle)errorUrlChangeBlock { 91 | _errorUrlChangeBlock = errorUrlChangeBlock; 92 | } 93 | @end 94 | -------------------------------------------------------------------------------- /TBRMonitorFramework/TBRURL/TBRURLProtocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // TBRURLProtocol.h 3 | // Usage 4 | // 使用本类时,需要在程序启动时注册 example: 5 | // 6 | // [NSURLProtocol registerClass:[TBRURLProtocol class]]; 7 | // 8 | // Created by huanwh on 16/4/12. 9 | // Copyright © 2016年 huanwh. All rights reserved. 10 | // 11 | 12 | #import 13 | #import "TBREnvConfig.h" 14 | 15 | 16 | 17 | @interface TBRURLProtocol : NSURLProtocol 18 | @end 19 | -------------------------------------------------------------------------------- /TBRMonitorFramework/TBRURL/TBRURLProtocol.m: -------------------------------------------------------------------------------- 1 | // 2 | // TBRURLProtocol.m 3 | // Usage 4 | // 5 | // Created by huanwh on 16/4/12. 6 | // Copyright © 2016年 huanwh. All rights reserved. 7 | // 8 | 9 | #import "TBRURLProtocol.h" 10 | #import "TBREnvConfig.h" 11 | #import "TBRURLCollectionManager.h" 12 | 13 | static NSString * const TBRURLProtocolHandleKey = @"TBRURLProtocolHandleKey"; 14 | 15 | 16 | @interface TBRURLProtocol () 17 | @property(strong) NSURLConnection * connection; 18 | @property(strong) NSArray * hostsList;//需要监控的host 列表 19 | @end 20 | 21 | @implementation TBRURLProtocol 22 | 23 | 24 | #pragma mark - NSURLProtocol 25 | // override 是否打算处理对应的request 26 | +(BOOL)canInitWithRequest:(NSURLRequest *)request { 27 | NSAssert(request, @"url 不能为空"); 28 | //排重 29 | if ([NSURLProtocol propertyForKey:TBRURLProtocolHandleKey inRequest:request] || !request) { 30 | return NO; 31 | } 32 | 33 | NSString * scheme = [[request URL] scheme]; 34 | NSString * host = [[request URL] host]; 35 | 36 | //过滤非http https 的请求 37 | BOOL isHttpOrHttps = NO; 38 | if ([scheme caseInsensitiveCompare:@"http"] == NSOrderedSame) { 39 | isHttpOrHttps = YES; 40 | } 41 | if ([scheme caseInsensitiveCompare:@"https"] == NSOrderedSame) { 42 | isHttpOrHttps = YES; 43 | } 44 | if (isHttpOrHttps == NO) { 45 | TBRLog(@"忽略 (%@)",scheme); 46 | 47 | return NO; 48 | } 49 | 50 | //判断是否包含需要监听的host. if = nil 监听所有host. 51 | 52 | NSArray * allowHosts = [TBREnvConfig shareInstance].allowHosts; 53 | if (!allowHosts || allowHosts.count <=0) { 54 | return YES; 55 | } 56 | 57 | BOOL isAllowObserver = NO; 58 | for (NSString * allowhost in allowHosts) { 59 | if ([allowhost.uppercaseString isEqualToString:[host uppercaseString]]) { 60 | isAllowObserver = YES; 61 | break; 62 | } 63 | } 64 | 65 | return isAllowObserver; 66 | } 67 | //overide 抽象 请求。 可以二次修改后返回最新的请求 68 | +(NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request { 69 | NSAssert(request, @"传入request 不能为空 或者 格式错误"); 70 | 71 | NSMutableURLRequest * mutableRequest = [request mutableCopy]; 72 | if (mutableRequest == nil) { 73 | [TBRURLCollectionManager injectFailedRequestWithRequest:request failedError:[NSError errorWithDomain:@"com.alibaba-inc.read" code:-1000 userInfo:nil]]; 74 | } 75 | // mutableRequest = [self redirectHostForRequest:mutableRequest]; 76 | return mutableRequest; 77 | } 78 | -(void)startLoading { 79 | NSMutableURLRequest * request = [self.request mutableCopy]; 80 | 81 | TBRLog(@"request -> %@",request.URL.absoluteString); 82 | [NSURLProtocol setProperty:@YES forKey:TBRURLProtocolHandleKey inRequest:request]; 83 | self.connection = [NSURLConnection connectionWithRequest:request delegate:self]; 84 | 85 | [TBRURLCollectionManager startRequest:request]; 86 | } 87 | -(void)stopLoading { 88 | [self.connection cancel]; 89 | } 90 | #pragma mark - NSURLConnectionDataDelegate 91 | -(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { 92 | [self.client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed]; 93 | 94 | [TBRURLCollectionManager injectReponse:response request:connection.currentRequest]; 95 | } 96 | -(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { 97 | // TBRLog(@"%s",__FUNCTION__); 98 | [self.client URLProtocol:self didLoadData:data]; 99 | 100 | [TBRURLCollectionManager injectRecieveDataWithRequest:connection.currentRequest recieveLenght:data.length]; 101 | } 102 | -(void)connectionDidFinishLoading:(NSURLConnection *)connection { 103 | [self.client URLProtocolDidFinishLoading:self]; 104 | 105 | [TBRURLCollectionManager injectFinishRequestWithRequest:connection.currentRequest]; 106 | } 107 | -(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { 108 | [self.client URLProtocol:self didFailWithError:error]; 109 | 110 | [TBRURLCollectionManager injectFailedRequestWithRequest:connection.currentRequest failedError:error]; 111 | } 112 | #pragma mark - 113 | //override 替换错误url到本地 html 网页 114 | /* 115 | +(NSMutableURLRequest *)redirectHostForRequest:(NSMutableURLRequest *)request { 116 | 117 | if ([request.URL host].length == 0) { 118 | return [self localErrorHtmlPath]; 119 | } 120 | 121 | NSString * originUrlString = [request.URL absoluteString]; 122 | NSString * originHostString = [request.URL host]; 123 | NSRange hostRange = [originUrlString rangeOfString:originHostString]; 124 | if (hostRange.location == NSNotFound) { 125 | return [self localErrorHtmlPath]; 126 | } 127 | 128 | return request; 129 | } 130 | */ 131 | +(NSMutableURLRequest *)localErrorHtmlPath { 132 | NSString * errPath = [[NSBundle mainBundle] pathForResource:@"404" ofType:@"html"]; 133 | if (!errPath) { 134 | return nil; 135 | } 136 | NSMutableURLRequest * request = [[NSMutableURLRequest alloc] initWithURL:[NSURL fileURLWithPath:errPath]]; 137 | 138 | return request; 139 | } 140 | 141 | @end 142 | --------------------------------------------------------------------------------