├── docs ├── .gitkeep ├── _media │ ├── .gitkeep │ ├── debugo.png │ ├── favicon.ico │ ├── debugo_pod.png │ ├── build-info-1.png │ ├── build-info-2.png │ ├── debugo_apple.png │ ├── debugo_file.png │ ├── debugo_touch.png │ ├── debugo_account.png │ ├── debugo_action.png │ ├── debugo_appinfo.png │ ├── debugo_plugin.png │ └── debugo_uiviewcolor.png └── build-info.md ├── _config.yml ├── Example └── Debugo-Example-ObjectiveC │ ├── Pods │ ├── Headers │ │ ├── Private │ │ │ └── FMDB │ │ │ │ ├── FMDB.h │ │ │ │ ├── FMDatabase.h │ │ │ │ ├── FMResultSet.h │ │ │ │ ├── FMDatabasePool.h │ │ │ │ ├── FMDatabaseQueue.h │ │ │ │ └── FMDatabaseAdditions.h │ │ └── Public │ │ │ └── FMDB │ │ │ ├── FMDB.h │ │ │ ├── FMDatabase.h │ │ │ ├── FMResultSet.h │ │ │ ├── FMDatabasePool.h │ │ │ ├── FMDatabaseQueue.h │ │ │ └── FMDatabaseAdditions.h │ ├── Target Support Files │ │ ├── FMDB │ │ │ ├── FMDB-dummy.m │ │ │ ├── FMDB-prefix.pch │ │ │ ├── FMDB.xcconfig │ │ │ ├── FMDB.debug.xcconfig │ │ │ └── FMDB.release.xcconfig │ │ └── Pods-Debugo-Example-ObjectiveC │ │ │ ├── Pods-Debugo-Example-ObjectiveC-dummy.m │ │ │ ├── Pods-Debugo-Example-ObjectiveC.debug.xcconfig │ │ │ ├── Pods-Debugo-Example-ObjectiveC.release.xcconfig │ │ │ ├── Pods-Debugo-Example-ObjectiveC-acknowledgements.markdown │ │ │ └── Pods-Debugo-Example-ObjectiveC-acknowledgements.plist │ ├── FMDB │ │ ├── src │ │ │ └── fmdb │ │ │ │ └── FMDB.h │ │ └── LICENSE.txt │ └── Manifest.lock │ ├── Debugo-Example-ObjectiveC │ ├── Assets.xcassets │ │ ├── Contents.json │ │ └── AppIcon.appiconset │ │ │ ├── ipad020pts1x.png │ │ │ ├── ipad020pts2x.png │ │ │ ├── ipad029pts1x.png │ │ │ ├── ipad029pts2x.png │ │ │ ├── ipad040pts1x.png │ │ │ ├── ipad040pts2x.png │ │ │ ├── ipad076pts1x.png │ │ │ ├── ipad076pts2x.png │ │ │ ├── ipad083pts2x.png │ │ │ ├── iphone020pts2x.png │ │ │ ├── iphone020pts3x.png │ │ │ ├── iphone029pts2x.png │ │ │ ├── iphone029pts3x.png │ │ │ ├── iphone040pts2x.png │ │ │ ├── iphone040pts3x.png │ │ │ ├── iphone060pts2x.png │ │ │ ├── iphone060pts3x.png │ │ │ └── Contents.json │ ├── picooc.production.sqlite │ ├── Login │ │ ├── LoginViewController.h │ │ ├── LoginSuccessViewController.h │ │ ├── LoginSuccessViewController.m │ │ └── LoginViewController.m │ ├── ViewController.h │ ├── CustomPlugin │ │ ├── CustomPlugin.h │ │ ├── CustomPlugin2.h │ │ ├── CustomPlugin2ViewController.h │ │ ├── CustomPlugin.m │ │ ├── CustomPlugin2.m │ │ └── CustomPlugin2ViewController.m │ ├── AppDelegate.h │ ├── main.m │ ├── UIView+IB.h │ ├── PrefixHeader.pch │ ├── UIView+IB.m │ ├── ViewController.m │ ├── Info.plist │ └── Base.lproj │ │ └── LaunchScreen.storyboard │ ├── Debugo-Example-ObjectiveC.xcodeproj │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ ├── Debugo-Example-ObjectiveC.xcworkspace │ ├── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── WorkspaceSettings.xcsettings │ └── contents.xcworkspacedata │ ├── Podfile │ └── Podfile.lock ├── fastlane ├── Fastfile └── README.md ├── Debugo ├── Assets │ └── Debugo.bundle │ │ ├── file_pdf@3x.png │ │ ├── file_zip@3x.png │ │ ├── file_audio@3x.png │ │ ├── file_folder@3x.png │ │ ├── file_image@3x.png │ │ ├── file_json@3x.png │ │ ├── file_plist@3x.png │ │ ├── file_video@3x.png │ │ ├── icon_bubble@3x.png │ │ ├── icon_copy@3x.png │ │ ├── plugin_file@3x.png │ │ ├── plugin_pod@3x.png │ │ ├── file_database@3x.png │ │ ├── file_default@3x.png │ │ ├── plugin_action@3x.png │ │ ├── plugin_apple@3x.png │ │ ├── plugin_touch@3x.png │ │ ├── plugin_account@3x.png │ │ ├── plugin_appinfo@3x.png │ │ ├── plugin_default@3x.png │ │ ├── tab_file_normal@3x.png │ │ ├── tab_pod_normal@3x.png │ │ ├── tab_pod_selected@3x.png │ │ ├── tab_touch_normal@3x.png │ │ ├── plugin_uiviewcolor@3x.png │ │ ├── tab_action_normal@3x.png │ │ ├── tab_appinfo_normal@3x.png │ │ ├── tab_default_normal@3x.png │ │ ├── tab_file_selected@3x.png │ │ ├── tab_plugin_normal@3x.png │ │ ├── tab_touch_selected@3x.png │ │ ├── tab_action_selected@3x.png │ │ ├── tab_appinfo_selected@3x.png │ │ ├── tab_default_selected@3x.png │ │ ├── tab_plugin_selected@3x.png │ │ ├── tab_uiviewcolor_normal@3x.png │ │ └── tab_uiviewcolor_selected@3x.png └── Classes │ ├── API │ ├── DebugoEnable.h │ ├── DGConfiguration.h │ ├── DGConfiguration.m │ └── Debugo.h │ ├── Plugin │ ├── TouchPlugin │ │ ├── DGTouchPlugin.h │ │ ├── DGTouchWindow.h │ │ ├── DGTouchPluginViewController.h │ │ ├── DGTouchFingerView.h │ │ ├── DGTouchPluginViewController.m │ │ ├── DGTouchPlugin.m │ │ └── DGTouchWindow.m │ ├── FilePlugin │ │ ├── DGFilePreviewConfiguration.m │ │ ├── DGFileViewController.h │ │ ├── DGDatabaseTableInfo.m │ │ ├── DGDatabaseColumnInfo.m │ │ ├── DGWebviewPreviewViewContoller.h │ │ ├── DGFileTableViewCell.h │ │ ├── DGDatabaseLeftTableViewCell.h │ │ ├── DGDatabaseContentParser.h │ │ ├── DGFileInfoViewController.h │ │ ├── DGDefaultPreviewViewController.h │ │ ├── DGFilePlugin.h │ │ ├── DGPreviewManager.h │ │ ├── DGFolderPreviewViewController.h │ │ ├── DGDatabaseTableInfoViewController.h │ │ ├── DGDatabaseContentTableViewCell.h │ │ ├── DGDatabaseTableInfo.h │ │ ├── DGFilePluginConfiguration.m │ │ ├── DGDatabaseColumnInfo.h │ │ ├── DGFileParser.h │ │ ├── DGDatabasePreviewViewController.h │ │ ├── DGDatabaseTableContentViewController.h │ │ ├── DGFilePluginConfiguration.h │ │ ├── DGFilePreviewConfiguration.h │ │ ├── DGDatabaseOperation.h │ │ ├── DGDatabasePreviewConfiguration.h │ │ ├── DGDefaultPreviewViewController.m │ │ ├── DGFileTableViewCell.m │ │ ├── DGDatabaseLeftTableViewCell.m │ │ ├── DGFile.h │ │ ├── DGFilePlugin.m │ │ ├── DGDatabaseContentParser.m │ │ ├── DGDatabaseGridView.h │ │ ├── DGPreviewManager.m │ │ ├── DGDatabaseTableInfoViewController.m │ │ ├── DGFileParser.m │ │ └── DGDatabaseOperation.m │ ├── AccountPlugin │ │ ├── DGAccountPluginConfiguration.m │ │ ├── DGAccountListViewController.h │ │ ├── DGAccountBackViewController.h │ │ ├── DGAccount.h │ │ ├── DGAccountPlugin.h │ │ ├── DGAccountPluginConfiguration.h │ │ ├── DGAccount.m │ │ └── DGAccountBackViewController.m │ ├── AppInfoPlugin │ │ ├── DGAppInfoPlugin.h │ │ ├── DGAppInfoViewController.h │ │ └── DGAppInfoPlugin.m │ ├── ActionPlugin │ │ ├── DGActionViewController.h │ │ ├── DGActionSubViewController.h │ │ ├── DGActionPluginConfiguration.h │ │ ├── DGActionPlugin.h │ │ ├── DGAction.h │ │ ├── DGActionPluginConfiguration.m │ │ ├── DGAction.m │ │ └── DGActionSubViewController.m │ ├── ColorPlugin │ │ ├── DGColorPlugin.h │ │ ├── DGColorPluginViewController.h │ │ ├── UIView+DGColorPlugin.h │ │ └── DGColorPlugin.m │ ├── PodPlugin │ │ ├── DGPodPluginConfiguration.m │ │ ├── DGPodPluginViewController.h │ │ ├── DGSpecRepoModel.h │ │ ├── DGPodModel.h │ │ ├── DGPodPluginConfiguration.h │ │ ├── DGSpecRepoModel.m │ │ ├── DGPodPlugin.h │ │ └── DGPodModel.m │ ├── DGPluginGridViewController.h │ ├── ApplePlugin │ │ └── DGApplePlugin.h │ ├── DGPlugin.h │ ├── DGPlugin.m │ ├── DGPluginManager.h │ └── DGPluginManager.m │ ├── Entrance │ ├── DGDebugViewController.h │ ├── DGDebugWindow.h │ ├── DGEntrance.h │ ├── DGDebugWindow.m │ └── DGBubble.h │ └── Common │ ├── UI │ ├── DGNavigationController.h │ ├── DGStaticRow.m │ ├── DGWindow.h │ ├── DGAnimationDelegate.h │ ├── DGShareBarButtonItem.h │ ├── DGAnimationDelegate.m │ ├── DGCommonGridViewController.h │ ├── DGStaticRow.h │ ├── DGNavigationController.m │ ├── DGStaticSection.m │ ├── DGStaticSection.h │ ├── DGWindow.m │ ├── DGShareBarButtonItem.m │ └── DGStaticProvider.h │ ├── Source │ ├── DGBundle.h │ ├── DGCache.h │ ├── DGBundle.m │ ├── DGBuildInfo.h │ └── DGCache.m │ ├── Category │ ├── NSNumber+Debugo.h │ ├── UIColor+Debugo.h │ ├── NSDate+Debugo.h │ ├── NSString+Debugo.h │ ├── NSFileManager+Debugo.h │ ├── UIControl+Debugo.h │ ├── NSString+Debugo.m │ ├── UIView+Debugo.h │ ├── UIColor+Debugo.m │ ├── NSNumber+Debugo.m │ ├── NSDate+Debugo.m │ ├── NSObject+Debugo.h │ ├── UIControl+Debugo.m │ └── NSFileManager+Debugo.m │ ├── DGCommon.h │ └── Utility │ ├── DGPathFetcher.h │ ├── DGPathFetcher.m │ ├── DGOrderedDictionary.h │ ├── DGPlister.h │ └── DGDevice.h ├── Debugo.podspec ├── LICENSE └── .gitignore /docs/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/_media/.gitkeep: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-architect -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Pods/Headers/Private/FMDB/FMDB.h: -------------------------------------------------------------------------------- 1 | ../../../FMDB/src/fmdb/FMDB.h -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Pods/Headers/Public/FMDB/FMDB.h: -------------------------------------------------------------------------------- 1 | ../../../FMDB/src/fmdb/FMDB.h -------------------------------------------------------------------------------- /docs/_media/debugo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/docs/_media/debugo.png -------------------------------------------------------------------------------- /docs/_media/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/docs/_media/favicon.ico -------------------------------------------------------------------------------- /docs/_media/debugo_pod.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/docs/_media/debugo_pod.png -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Pods/Headers/Private/FMDB/FMDatabase.h: -------------------------------------------------------------------------------- 1 | ../../../FMDB/src/fmdb/FMDatabase.h -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Pods/Headers/Public/FMDB/FMDatabase.h: -------------------------------------------------------------------------------- 1 | ../../../FMDB/src/fmdb/FMDatabase.h -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Pods/Headers/Public/FMDB/FMResultSet.h: -------------------------------------------------------------------------------- 1 | ../../../FMDB/src/fmdb/FMResultSet.h -------------------------------------------------------------------------------- /docs/_media/build-info-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/docs/_media/build-info-1.png -------------------------------------------------------------------------------- /docs/_media/build-info-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/docs/_media/build-info-2.png -------------------------------------------------------------------------------- /docs/_media/debugo_apple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/docs/_media/debugo_apple.png -------------------------------------------------------------------------------- /docs/_media/debugo_file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/docs/_media/debugo_file.png -------------------------------------------------------------------------------- /docs/_media/debugo_touch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/docs/_media/debugo_touch.png -------------------------------------------------------------------------------- /fastlane/Fastfile: -------------------------------------------------------------------------------- 1 | import_from_git(url: 'https://github.com/ripperhe/fastlane-files', branch: 'master') 2 | -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Pods/Headers/Private/FMDB/FMResultSet.h: -------------------------------------------------------------------------------- 1 | ../../../FMDB/src/fmdb/FMResultSet.h -------------------------------------------------------------------------------- /docs/_media/debugo_account.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/docs/_media/debugo_account.png -------------------------------------------------------------------------------- /docs/_media/debugo_action.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/docs/_media/debugo_action.png -------------------------------------------------------------------------------- /docs/_media/debugo_appinfo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/docs/_media/debugo_appinfo.png -------------------------------------------------------------------------------- /docs/_media/debugo_plugin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/docs/_media/debugo_plugin.png -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Pods/Headers/Private/FMDB/FMDatabasePool.h: -------------------------------------------------------------------------------- 1 | ../../../FMDB/src/fmdb/FMDatabasePool.h -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Pods/Headers/Private/FMDB/FMDatabaseQueue.h: -------------------------------------------------------------------------------- 1 | ../../../FMDB/src/fmdb/FMDatabaseQueue.h -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Pods/Headers/Public/FMDB/FMDatabasePool.h: -------------------------------------------------------------------------------- 1 | ../../../FMDB/src/fmdb/FMDatabasePool.h -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Pods/Headers/Public/FMDB/FMDatabaseQueue.h: -------------------------------------------------------------------------------- 1 | ../../../FMDB/src/fmdb/FMDatabaseQueue.h -------------------------------------------------------------------------------- /docs/_media/debugo_uiviewcolor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/docs/_media/debugo_uiviewcolor.png -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Pods/Headers/Private/FMDB/FMDatabaseAdditions.h: -------------------------------------------------------------------------------- 1 | ../../../FMDB/src/fmdb/FMDatabaseAdditions.h -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Pods/Headers/Public/FMDB/FMDatabaseAdditions.h: -------------------------------------------------------------------------------- 1 | ../../../FMDB/src/fmdb/FMDatabaseAdditions.h -------------------------------------------------------------------------------- /Debugo/Assets/Debugo.bundle/file_pdf@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Debugo/Assets/Debugo.bundle/file_pdf@3x.png -------------------------------------------------------------------------------- /Debugo/Assets/Debugo.bundle/file_zip@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Debugo/Assets/Debugo.bundle/file_zip@3x.png -------------------------------------------------------------------------------- /Debugo/Assets/Debugo.bundle/file_audio@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Debugo/Assets/Debugo.bundle/file_audio@3x.png -------------------------------------------------------------------------------- /Debugo/Assets/Debugo.bundle/file_folder@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Debugo/Assets/Debugo.bundle/file_folder@3x.png -------------------------------------------------------------------------------- /Debugo/Assets/Debugo.bundle/file_image@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Debugo/Assets/Debugo.bundle/file_image@3x.png -------------------------------------------------------------------------------- /Debugo/Assets/Debugo.bundle/file_json@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Debugo/Assets/Debugo.bundle/file_json@3x.png -------------------------------------------------------------------------------- /Debugo/Assets/Debugo.bundle/file_plist@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Debugo/Assets/Debugo.bundle/file_plist@3x.png -------------------------------------------------------------------------------- /Debugo/Assets/Debugo.bundle/file_video@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Debugo/Assets/Debugo.bundle/file_video@3x.png -------------------------------------------------------------------------------- /Debugo/Assets/Debugo.bundle/icon_bubble@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Debugo/Assets/Debugo.bundle/icon_bubble@3x.png -------------------------------------------------------------------------------- /Debugo/Assets/Debugo.bundle/icon_copy@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Debugo/Assets/Debugo.bundle/icon_copy@3x.png -------------------------------------------------------------------------------- /Debugo/Assets/Debugo.bundle/plugin_file@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Debugo/Assets/Debugo.bundle/plugin_file@3x.png -------------------------------------------------------------------------------- /Debugo/Assets/Debugo.bundle/plugin_pod@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Debugo/Assets/Debugo.bundle/plugin_pod@3x.png -------------------------------------------------------------------------------- /Debugo/Assets/Debugo.bundle/file_database@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Debugo/Assets/Debugo.bundle/file_database@3x.png -------------------------------------------------------------------------------- /Debugo/Assets/Debugo.bundle/file_default@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Debugo/Assets/Debugo.bundle/file_default@3x.png -------------------------------------------------------------------------------- /Debugo/Assets/Debugo.bundle/plugin_action@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Debugo/Assets/Debugo.bundle/plugin_action@3x.png -------------------------------------------------------------------------------- /Debugo/Assets/Debugo.bundle/plugin_apple@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Debugo/Assets/Debugo.bundle/plugin_apple@3x.png -------------------------------------------------------------------------------- /Debugo/Assets/Debugo.bundle/plugin_touch@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Debugo/Assets/Debugo.bundle/plugin_touch@3x.png -------------------------------------------------------------------------------- /Debugo/Assets/Debugo.bundle/plugin_account@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Debugo/Assets/Debugo.bundle/plugin_account@3x.png -------------------------------------------------------------------------------- /Debugo/Assets/Debugo.bundle/plugin_appinfo@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Debugo/Assets/Debugo.bundle/plugin_appinfo@3x.png -------------------------------------------------------------------------------- /Debugo/Assets/Debugo.bundle/plugin_default@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Debugo/Assets/Debugo.bundle/plugin_default@3x.png -------------------------------------------------------------------------------- /Debugo/Assets/Debugo.bundle/tab_file_normal@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Debugo/Assets/Debugo.bundle/tab_file_normal@3x.png -------------------------------------------------------------------------------- /Debugo/Assets/Debugo.bundle/tab_pod_normal@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Debugo/Assets/Debugo.bundle/tab_pod_normal@3x.png -------------------------------------------------------------------------------- /Debugo/Assets/Debugo.bundle/tab_pod_selected@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Debugo/Assets/Debugo.bundle/tab_pod_selected@3x.png -------------------------------------------------------------------------------- /Debugo/Assets/Debugo.bundle/tab_touch_normal@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Debugo/Assets/Debugo.bundle/tab_touch_normal@3x.png -------------------------------------------------------------------------------- /Debugo/Assets/Debugo.bundle/plugin_uiviewcolor@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Debugo/Assets/Debugo.bundle/plugin_uiviewcolor@3x.png -------------------------------------------------------------------------------- /Debugo/Assets/Debugo.bundle/tab_action_normal@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Debugo/Assets/Debugo.bundle/tab_action_normal@3x.png -------------------------------------------------------------------------------- /Debugo/Assets/Debugo.bundle/tab_appinfo_normal@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Debugo/Assets/Debugo.bundle/tab_appinfo_normal@3x.png -------------------------------------------------------------------------------- /Debugo/Assets/Debugo.bundle/tab_default_normal@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Debugo/Assets/Debugo.bundle/tab_default_normal@3x.png -------------------------------------------------------------------------------- /Debugo/Assets/Debugo.bundle/tab_file_selected@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Debugo/Assets/Debugo.bundle/tab_file_selected@3x.png -------------------------------------------------------------------------------- /Debugo/Assets/Debugo.bundle/tab_plugin_normal@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Debugo/Assets/Debugo.bundle/tab_plugin_normal@3x.png -------------------------------------------------------------------------------- /Debugo/Assets/Debugo.bundle/tab_touch_selected@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Debugo/Assets/Debugo.bundle/tab_touch_selected@3x.png -------------------------------------------------------------------------------- /Debugo/Assets/Debugo.bundle/tab_action_selected@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Debugo/Assets/Debugo.bundle/tab_action_selected@3x.png -------------------------------------------------------------------------------- /Debugo/Assets/Debugo.bundle/tab_appinfo_selected@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Debugo/Assets/Debugo.bundle/tab_appinfo_selected@3x.png -------------------------------------------------------------------------------- /Debugo/Assets/Debugo.bundle/tab_default_selected@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Debugo/Assets/Debugo.bundle/tab_default_selected@3x.png -------------------------------------------------------------------------------- /Debugo/Assets/Debugo.bundle/tab_plugin_selected@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Debugo/Assets/Debugo.bundle/tab_plugin_selected@3x.png -------------------------------------------------------------------------------- /Debugo/Assets/Debugo.bundle/tab_uiviewcolor_normal@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Debugo/Assets/Debugo.bundle/tab_uiviewcolor_normal@3x.png -------------------------------------------------------------------------------- /Debugo/Assets/Debugo.bundle/tab_uiviewcolor_selected@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Debugo/Assets/Debugo.bundle/tab_uiviewcolor_selected@3x.png -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Pods/Target Support Files/FMDB/FMDB-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_FMDB : NSObject 3 | @end 4 | @implementation PodsDummy_FMDB 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/picooc.production.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/picooc.production.sqlite -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/Assets.xcassets/AppIcon.appiconset/ipad020pts1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/Assets.xcassets/AppIcon.appiconset/ipad020pts1x.png -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/Assets.xcassets/AppIcon.appiconset/ipad020pts2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/Assets.xcassets/AppIcon.appiconset/ipad020pts2x.png -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/Assets.xcassets/AppIcon.appiconset/ipad029pts1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/Assets.xcassets/AppIcon.appiconset/ipad029pts1x.png -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/Assets.xcassets/AppIcon.appiconset/ipad029pts2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/Assets.xcassets/AppIcon.appiconset/ipad029pts2x.png -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/Assets.xcassets/AppIcon.appiconset/ipad040pts1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/Assets.xcassets/AppIcon.appiconset/ipad040pts1x.png -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/Assets.xcassets/AppIcon.appiconset/ipad040pts2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/Assets.xcassets/AppIcon.appiconset/ipad040pts2x.png -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/Assets.xcassets/AppIcon.appiconset/ipad076pts1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/Assets.xcassets/AppIcon.appiconset/ipad076pts1x.png -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/Assets.xcassets/AppIcon.appiconset/ipad076pts2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/Assets.xcassets/AppIcon.appiconset/ipad076pts2x.png -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/Assets.xcassets/AppIcon.appiconset/ipad083pts2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/Assets.xcassets/AppIcon.appiconset/ipad083pts2x.png -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/Assets.xcassets/AppIcon.appiconset/iphone020pts2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/Assets.xcassets/AppIcon.appiconset/iphone020pts2x.png -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/Assets.xcassets/AppIcon.appiconset/iphone020pts3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/Assets.xcassets/AppIcon.appiconset/iphone020pts3x.png -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/Assets.xcassets/AppIcon.appiconset/iphone029pts2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/Assets.xcassets/AppIcon.appiconset/iphone029pts2x.png -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/Assets.xcassets/AppIcon.appiconset/iphone029pts3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/Assets.xcassets/AppIcon.appiconset/iphone029pts3x.png -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/Assets.xcassets/AppIcon.appiconset/iphone040pts2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/Assets.xcassets/AppIcon.appiconset/iphone040pts2x.png -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/Assets.xcassets/AppIcon.appiconset/iphone040pts3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/Assets.xcassets/AppIcon.appiconset/iphone040pts3x.png -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/Assets.xcassets/AppIcon.appiconset/iphone060pts2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/Assets.xcassets/AppIcon.appiconset/iphone060pts2x.png -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/Assets.xcassets/AppIcon.appiconset/iphone060pts3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ripperhe/Debugo/HEAD/Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/Assets.xcassets/AppIcon.appiconset/iphone060pts3x.png -------------------------------------------------------------------------------- /Debugo/Classes/API/DebugoEnable.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGEnableConfig.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/1/21. 6 | // Copyright © 2019 ripper. All rights reserved. 7 | // 8 | 9 | #ifndef DebugoCanBeEnabled 10 | #define DebugoCanBeEnabled DEBUG 11 | #endif 12 | -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Pods/Target Support Files/Pods-Debugo-Example-ObjectiveC/Pods-Debugo-Example-ObjectiveC-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_Debugo_Example_ObjectiveC : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_Debugo_Example_ObjectiveC 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Pods/Target Support Files/FMDB/FMDB-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/TouchPlugin/DGTouchPlugin.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGTouchPlugin.h 3 | // Debugo 4 | // 5 | // GitHub https://github.com/ripperhe/Debugo 6 | // Created by ripper on 2018/9/1. 7 | // Copyright © 2018年 ripper. All rights reserved. 8 | // 9 | 10 | #import "DGPlugin.h" 11 | 12 | @interface DGTouchPlugin : DGPlugin 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Debugo/Classes/Entrance/DGDebugViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGDebugViewController.h 3 | // Debugo 4 | // 5 | // GitHub https://github.com/ripperhe/Debugo 6 | // Created by ripper on 2018/9/1. 7 | // Copyright © 2018年 ripper. All rights reserved. 8 | // 9 | #import 10 | 11 | @interface DGDebugViewController : UITabBarController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/FilePlugin/DGFilePreviewConfiguration.m: -------------------------------------------------------------------------------- 1 | // 2 | // DGFilePreviewConfiguration.m 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/3/21. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import "DGFilePreviewConfiguration.h" 10 | 11 | @implementation DGFilePreviewConfiguration 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/Login/LoginViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // LoginViewController.h 3 | // Debugo_Example 4 | // 5 | // Created by ripper on 2018/9/21. 6 | // Copyright © 2018年 ripperhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface LoginViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Pods/FMDB/src/fmdb/FMDB.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | FOUNDATION_EXPORT double FMDBVersionNumber; 4 | FOUNDATION_EXPORT const unsigned char FMDBVersionString[]; 5 | 6 | #import "FMDatabase.h" 7 | #import "FMResultSet.h" 8 | #import "FMDatabaseAdditions.h" 9 | #import "FMDatabaseQueue.h" 10 | #import "FMDatabasePool.h" 11 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/AccountPlugin/DGAccountPluginConfiguration.m: -------------------------------------------------------------------------------- 1 | // 2 | // DGAccountPluginConfiguration.m 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/5/31. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import "DGAccountPluginConfiguration.h" 10 | 11 | @implementation DGAccountPluginConfiguration 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/FilePlugin/DGFileViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGFileViewController.h 3 | // Debugo 4 | // 5 | // GitHub https://github.com/ripperhe/Debugo 6 | // Created by ripper on 2018/9/1. 7 | // Copyright © 2018年 ripper. All rights reserved. 8 | // 9 | #import 10 | 11 | @interface DGFileViewController : UITableViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildSystemType 6 | Original 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/2/20. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UITableViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /Debugo/Classes/Common/UI/DGNavigationController.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGNavigationController.h 3 | // Debugo 4 | // 5 | // GitHub https://github.com/ripperhe/Debugo 6 | // Created by ripper on 2018/9/1. 7 | // Copyright © 2018年 ripper. All rights reserved. 8 | // 9 | 10 | #import 11 | 12 | @interface DGNavigationController : UINavigationController 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment the next line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | target 'Debugo-Example-ObjectiveC' do 5 | # Uncomment the next line if you're using Swift or would like to use dynamic frameworks 6 | # use_frameworks! 7 | 8 | # Pods for Debugo-Example-ObjectiveC 9 | pod 'FMDB' 10 | 11 | end 12 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/AppInfoPlugin/DGAppInfoPlugin.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGAppInfoPlugin.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/9/9. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import "DGPlugin.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface DGAppInfoPlugin : DGPlugin 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/ActionPlugin/DGActionViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGActionViewController.h 3 | // Debugo 4 | // 5 | // GitHub https://github.com/ripperhe/Debugo 6 | // Created by ripper on 2018/9/1. 7 | // Copyright © 2018年 ripper. All rights reserved. 8 | // 9 | 10 | 11 | #import 12 | 13 | @interface DGActionViewController : UITableViewController 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/AppInfoPlugin/DGAppInfoViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGAppInfoViewController.h 3 | // Debugo 4 | // 5 | // GitHub https://github.com/ripperhe/Debugo 6 | // Created by ripper on 2018/9/1. 7 | // Copyright © 2018年 ripper. All rights reserved. 8 | // 9 | 10 | #import 11 | 12 | @interface DGAppInfoViewController : UITableViewController 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/AccountPlugin/DGAccountListViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGAccountListViewController.h 3 | // Debugo 4 | // 5 | // GitHub https://github.com/ripperhe/Debugo 6 | // Created by ripper on 2018/9/1. 7 | // Copyright © 2018年 ripper. All rights reserved. 8 | // 9 | 10 | #import 11 | 12 | @interface DGAccountListViewController : UITableViewController 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/FilePlugin/DGDatabaseTableInfo.m: -------------------------------------------------------------------------------- 1 | // 2 | // DGDatabaseTableInfo.m 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/1/9. 6 | // Copyright © 2019 ripper. All rights reserved. 7 | // 8 | 9 | #import "DGDatabaseTableInfo.h" 10 | 11 | @implementation DGDatabaseTableInfo 12 | 13 | - (void)setValue:(id)value forUndefinedKey:(NSString *)key { 14 | } 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Debugo/Classes/Common/Source/DGBundle.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGBundle.h 3 | // Debugo 4 | // 5 | // GitHub https://github.com/ripperhe/Debugo 6 | // Created by ripper on 2018/9/1. 7 | // Copyright © 2018年 ripper. All rights reserved. 8 | // 9 | 10 | #import 11 | 12 | @interface DGBundle : NSObject 13 | 14 | + (NSBundle *)bundle; 15 | 16 | + (UIImage *)imageNamed:(NSString *)name; 17 | 18 | @end 19 | 20 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/ColorPlugin/DGColorPlugin.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGColorPlugin.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/9/26. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import "DGPlugin.h" 10 | #import "UIView+DGColorPlugin.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface DGColorPlugin : DGPlugin 15 | 16 | @end 17 | 18 | NS_ASSUME_NONNULL_END 19 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/FilePlugin/DGDatabaseColumnInfo.m: -------------------------------------------------------------------------------- 1 | // 2 | // DGDatabaseColumnInfo.m 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/1/9. 6 | // Copyright © 2019 ripper. All rights reserved. 7 | // 8 | 9 | #import "DGDatabaseColumnInfo.h" 10 | 11 | @implementation DGDatabaseColumnInfo 12 | 13 | - (void)setValue:(id)value forUndefinedKey:(NSString *)key { 14 | } 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/CustomPlugin/CustomPlugin.h: -------------------------------------------------------------------------------- 1 | // 2 | // CustomPlugin.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/9/15. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import "DGPlugin.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface CustomPlugin : DGPlugin 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/CustomPlugin/CustomPlugin2.h: -------------------------------------------------------------------------------- 1 | // 2 | // CustomPlugin2.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/9/15. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import "DGPlugin.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface CustomPlugin2 : DGPlugin 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /Debugo/Classes/Common/Category/NSNumber+Debugo.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSNumber+Debugo.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/3/20. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface NSNumber (Debugo) 14 | 15 | - (NSString *)dg_sizeString; 16 | 17 | @end 18 | 19 | NS_ASSUME_NONNULL_END 20 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/PodPlugin/DGPodPluginConfiguration.m: -------------------------------------------------------------------------------- 1 | // 2 | // DGPodPluginConfiguration.m 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/10/25. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import "DGPodPluginConfiguration.h" 10 | 11 | @implementation DGGitLabSpecRepoRequestInfo 12 | 13 | @end 14 | 15 | @implementation DGPodPluginConfiguration 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/TouchPlugin/DGTouchWindow.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGTouchWindow.h 3 | // Debugo 4 | // 5 | // GitHub https://github.com/ripperhe/Debugo 6 | // Created by ripper on 2018/9/1. 7 | // Copyright © 2018年 ripper. All rights reserved. 8 | // 9 | 10 | 11 | #import 12 | #import "DGWindow.h" 13 | 14 | @interface DGTouchWindow : DGWindow 15 | 16 | - (void)displayEvent:(UIEvent *)event; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - FMDB (2.7.5): 3 | - FMDB/standard (= 2.7.5) 4 | - FMDB/standard (2.7.5) 5 | 6 | DEPENDENCIES: 7 | - FMDB 8 | 9 | SPEC REPOS: 10 | https://cdn.cocoapods.org/: 11 | - FMDB 12 | 13 | SPEC CHECKSUMS: 14 | FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a 15 | 16 | PODFILE CHECKSUM: b56b17a416dbb09682442e37b0f00c0be117af95 17 | 18 | COCOAPODS: 1.9.3 19 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/PodPlugin/DGPodPluginViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGPodPluginViewController.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/10/25. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface DGPodPluginViewController : UITableViewController 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/2/20. 6 | // Copyright © 2019 ripperhe. 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 | -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - FMDB (2.7.5): 3 | - FMDB/standard (= 2.7.5) 4 | - FMDB/standard (2.7.5) 5 | 6 | DEPENDENCIES: 7 | - FMDB 8 | 9 | SPEC REPOS: 10 | https://cdn.cocoapods.org/: 11 | - FMDB 12 | 13 | SPEC CHECKSUMS: 14 | FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a 15 | 16 | PODFILE CHECKSUM: b56b17a416dbb09682442e37b0f00c0be117af95 17 | 18 | COCOAPODS: 1.9.3 19 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/ColorPlugin/DGColorPluginViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGColorPluginViewController.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/9/26. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface DGColorPluginViewController : UITableViewController 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/TouchPlugin/DGTouchPluginViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGTouchPluginViewController.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/9/12. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface DGTouchPluginViewController : UITableViewController 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/DGPluginGridViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGPluginGridViewController.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/9/8. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import "DGCommonGridViewController.h" 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface DGPluginGridViewController : DGCommonGridViewController 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/Login/LoginSuccessViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // LoginSuccessViewController.h 3 | // Debugo_Example 4 | // 5 | // Created by ripper on 2018/9/21. 6 | // Copyright © 2018年 ripperhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface LoginSuccessViewController : UIViewController 12 | 13 | @property (nonatomic, strong) NSDictionary *accountInfo; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/AccountPlugin/DGAccountBackViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGAccountBackViewController.h 3 | // Debugo 4 | // 5 | // GitHub https://github.com/ripperhe/Debugo 6 | // Created by ripper on 2018/9/1. 7 | // Copyright © 2018年 ripper. All rights reserved. 8 | // 9 | 10 | #import 11 | 12 | @interface DGAccountBackViewController : UIViewController 13 | 14 | - (void)dismissWithAnimation:(void (^)(void))completion; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/FilePlugin/DGWebviewPreviewViewContoller.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGWebviewPreviewViewContoller.h 3 | // Debugo 4 | // 5 | // GitHub https://github.com/ripperhe/Debugo 6 | // Created by ripper on 2018/9/1. 7 | // Copyright © 2018年 ripper. All rights reserved. 8 | // 9 | 10 | #import 11 | #import "DGFile.h" 12 | 13 | @interface DGWebviewPreviewViewContoller : UIViewController 14 | @property (nonatomic, strong) DGFile *file; 15 | @end 16 | -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/CustomPlugin/CustomPlugin2ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // CustomPlugin2ViewController.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/9/15. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface CustomPlugin2ViewController : UITableViewController 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/2/20. 6 | // Copyright © 2019 ripperhe. 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 | -------------------------------------------------------------------------------- /Debugo/Classes/Common/Category/UIColor+Debugo.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIColor+Debugo.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/9/26. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface UIColor (Debugo) 14 | 15 | /// 随机色 16 | + (UIColor *)dg_randomColor; 17 | /// 浅色系的随机色 18 | + (UIColor *)dg_lightRandomColor; 19 | 20 | @end 21 | 22 | NS_ASSUME_NONNULL_END 23 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/FilePlugin/DGFileTableViewCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGFileTableViewCell.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/9/14. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "DGFile.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface DGFileTableViewCell : UITableViewCell 15 | 16 | - (void)refreshWithFile:(DGFile *)file; 17 | 18 | @end 19 | 20 | NS_ASSUME_NONNULL_END 21 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/FilePlugin/DGDatabaseLeftTableViewCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGDatabaseLeftTableViewCell.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/1/9. 6 | // Copyright © 2019 ripper. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface DGDatabaseLeftTableViewCell : UITableViewCell 14 | 15 | @property (nonatomic, strong) UILabel *label; 16 | 17 | @end 18 | 19 | NS_ASSUME_NONNULL_END 20 | -------------------------------------------------------------------------------- /Debugo/Classes/Common/Category/NSDate+Debugo.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSDate+Debugo.h 3 | // Debugo 4 | // 5 | // GitHub https://github.com/ripperhe/Debugo 6 | // Created by ripper on 2018/9/1. 7 | // Copyright © 2018年 ripper. All rights reserved. 8 | // 9 | 10 | 11 | #import 12 | 13 | @interface NSDate (Debugo) 14 | 15 | // yyyy-MM-dd HH:mm:ss.SSS 16 | - (NSString *)dg_dateString; 17 | 18 | - (NSString *)dg_dateStringWithFormat:(NSString *)format; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/FilePlugin/DGDatabaseContentParser.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGDatabaseContentParser.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/1/14. 6 | // Copyright © 2019 ripper. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface DGDatabaseContentParser : NSObject 14 | 15 | + (NSString *)parseContentForTimestamp:(NSString *)content; 16 | 17 | @end 18 | 19 | NS_ASSUME_NONNULL_END 20 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/TouchPlugin/DGTouchFingerView.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGTouchFingerView.h 3 | // Debugo 4 | // 5 | // GitHub https://github.com/ripperhe/Debugo 6 | // Created by ripper on 2018/9/1. 7 | // Copyright © 2018年 ripper. All rights reserved. 8 | // 9 | 10 | 11 | #import 12 | 13 | @interface DGTouchFingerView : UIView 14 | 15 | - (id)initWithPoint:(CGPoint)point; 16 | - (void)updateWithTouch:(UITouch *)touch; 17 | - (void)removeFromSuperviewWithAnimation; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/FilePlugin/DGFileInfoViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGFileInfoViewController.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/1/10. 6 | // Copyright © 2019 ripper. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "DGFile.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface DGFileInfoViewController : UITableViewController 15 | 16 | - (instancetype)initWithFile:(DGFile *)file; 17 | 18 | @end 19 | 20 | NS_ASSUME_NONNULL_END 21 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/FilePlugin/DGDefaultPreviewViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGDefaultPreviewViewController.h 3 | // Debugo 4 | // 5 | // GitHub https://github.com/ripperhe/Debugo 6 | // Created by ripper on 2018/9/1. 7 | // Copyright © 2018年 ripper. All rights reserved. 8 | // 9 | 10 | #import 11 | #import 12 | #import "DGFile.h" 13 | 14 | @interface DGDefaultPreviewViewController : QLPreviewController 15 | @property (nonatomic, strong) DGFile *file; 16 | @end 17 | -------------------------------------------------------------------------------- /Debugo/Classes/Entrance/DGDebugWindow.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGDebugWindow.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/9/15. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import "DGWindow.h" 10 | #import "DGDebugViewController.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface DGDebugWindow : DGWindow 15 | 16 | /// 根控制器 17 | @property (nonatomic, strong, readonly) DGDebugViewController *debugViewController; 18 | 19 | @end 20 | 21 | NS_ASSUME_NONNULL_END 22 | -------------------------------------------------------------------------------- /Debugo/Classes/Common/Category/NSString+Debugo.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+Debugo.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/10/25. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface NSString (Debugo) 14 | 15 | + (NSString *)dg_stringByCombineComponents:(NSArray *)components separatedString:(nullable NSString *)separatedString; 16 | 17 | @end 18 | 19 | NS_ASSUME_NONNULL_END 20 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/ApplePlugin/DGApplePlugin.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGApplePlugin.h 3 | // Debugo 4 | // 5 | // GitHub https://github.com/ripperhe/Debugo 6 | // Created by ripper on 2018/9/1. 7 | // Copyright © 2018年 ripper. All rights reserved. 8 | // 9 | 10 | #import "DGPlugin.h" 11 | 12 | /** 13 | 支持 iOS 10 以上系统版本,因为是系统 API 暂未找到代码关闭且不影响其他功能的方法 14 | * 通过 pluginSwitch 查看是否开启 15 | * 通过 setPluginSwitch:YES 开启 16 | * 在 DebuggingOverlay 界面上点击 Dismiss 按钮关闭 17 | */ 18 | 19 | @interface DGApplePlugin : DGPlugin 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/FilePlugin/DGFilePlugin.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGFilePlugin.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/5/31. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import "DGPlugin.h" 10 | #import "DGFilePluginConfiguration.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface DGFilePlugin : DGPlugin 15 | 16 | @property (nonatomic, strong) DGFilePluginConfiguration *configuration; 17 | 18 | + (instancetype)shared; 19 | 20 | @end 21 | 22 | NS_ASSUME_NONNULL_END 23 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/FilePlugin/DGPreviewManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGPreviewManager.h 3 | // Debugo 4 | // 5 | // GitHub https://github.com/ripperhe/Debugo 6 | // Created by ripper on 2018/9/1. 7 | // Copyright © 2018年 ripper. All rights reserved. 8 | // 9 | 10 | #import 11 | #import "DGFilePreviewConfiguration.h" 12 | 13 | @interface DGPreviewManager : NSObject 14 | 15 | + (UIViewController *)previewViewControllerForFile:(DGFile *)file configuration:(DGFilePreviewConfiguration *)configuration; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/UIView+IB.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+IB.h 3 | // Debugo_Example 4 | // 5 | // Created by ripper on 2018/9/28. 6 | // Copyright © 2018 ripperhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | IB_DESIGNABLE 12 | 13 | @interface UIView (IB) 14 | 15 | @property (nonatomic, assign) IBInspectable CGFloat dg_cornerRadius; 16 | @property (nonatomic, assign) IBInspectable CGFloat dg_borderWidth; 17 | @property (nonatomic, strong) IBInspectable UIColor *dg_borderColor; 18 | 19 | @end 20 | 21 | -------------------------------------------------------------------------------- /Debugo/Classes/Common/Source/DGCache.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGCache.h 3 | // Debugo 4 | // 5 | // GitHub https://github.com/ripperhe/Debugo 6 | // Created by ripper on 2018/9/1. 7 | // Copyright © 2018年 ripper. All rights reserved. 8 | // 9 | 10 | #import 11 | #import "DGPlister.h" 12 | 13 | @interface DGCache : NSObject 14 | 15 | /// 缓存文件夹 16 | @property (nonatomic, copy) NSString *debugoPath; 17 | 18 | /// 缓存账号的plist文件 19 | @property (nonatomic, strong, readonly) DGPlister *accountPlister; 20 | 21 | + (instancetype)shared; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/CustomPlugin/CustomPlugin.m: -------------------------------------------------------------------------------- 1 | // 2 | // CustomPlugin.m 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/9/15. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import "CustomPlugin.h" 10 | 11 | @implementation CustomPlugin 12 | 13 | + (NSString *)pluginName { 14 | return @"自定义工具"; 15 | } 16 | 17 | + (void)setPluginSwitch:(BOOL)pluginSwitch { 18 | if (pluginSwitch) { 19 | // 启动 20 | NSLog(@"启动自定义工具"); 21 | } 22 | } 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/PrefixHeader.pch: -------------------------------------------------------------------------------- 1 | // 2 | // PrefixHeader.pch 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/2/20. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #ifndef PrefixHeader_pch 10 | #define PrefixHeader_pch 11 | 12 | // Include any system framework and library headers here that should be included in all compilation units. 13 | // You will also need to set the Prefix Header build setting of one or more of your targets to reference this file. 14 | 15 | #endif /* PrefixHeader_pch */ 16 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/FilePlugin/DGFolderPreviewViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGFolderPreviewViewController.h 3 | // Debugo 4 | // 5 | // GitHub https://github.com/ripperhe/Debugo 6 | // Created by ripper on 2018/9/1. 7 | // Copyright © 2018年 ripper. All rights reserved. 8 | // 9 | 10 | #import 11 | #import "DGFilePreviewConfiguration.h" 12 | #import "DGFileTableViewCell.h" 13 | 14 | @interface DGFolderPreviewViewController : UITableViewController 15 | 16 | - (instancetype)initWithFile:(DGFile *)file configuration:(DGFilePreviewConfiguration *)configuration; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/ActionPlugin/DGActionSubViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGActionSubViewController.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/1/22. 6 | // Copyright © 2019 ripper. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "DGAction.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface DGActionSubViewController : UITableViewController 15 | 16 | + (instancetype)new NS_UNAVAILABLE; 17 | - (instancetype)init NS_UNAVAILABLE; 18 | - (instancetype)initWithActions:(NSArray *)actions; 19 | 20 | @end 21 | 22 | NS_ASSUME_NONNULL_END 23 | -------------------------------------------------------------------------------- /Debugo/Classes/Common/UI/DGStaticRow.m: -------------------------------------------------------------------------------- 1 | // 2 | // DGStaticRow.m 3 | // StaticTableView 4 | // 5 | // Created by ripper on 2019/9/25. 6 | // Copyright © 2019 ripper. All rights reserved. 7 | // 8 | 9 | #import "DGStaticRow.h" 10 | 11 | @implementation DGStaticRow 12 | 13 | + (instancetype)row:(void (^)(DGStaticRow * _Nonnull))block { 14 | DGStaticRow *obj = [self new]; 15 | block(obj); 16 | return obj; 17 | } 18 | 19 | - (NSString *)identifier { 20 | if (!_identifier) { 21 | _identifier = [NSString stringWithFormat:@"cell_%p", self]; 22 | } 23 | return _identifier; 24 | } 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/FilePlugin/DGDatabaseTableInfoViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGDatabaseTableInfoViewController.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/1/10. 6 | // Copyright © 2019 ripper. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "DGDatabaseTableInfo.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface DGDatabaseTableInfoViewController : UITableViewController 15 | 16 | @property (nonatomic, strong) DGDatabaseTableInfo *table; 17 | 18 | - (instancetype)initWithTable:(DGDatabaseTableInfo *)table; 19 | 20 | @end 21 | 22 | NS_ASSUME_NONNULL_END 23 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/FilePlugin/DGDatabaseContentTableViewCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGDatabaseContentTableViewCell.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/1/9. 6 | // Copyright © 2019 ripper. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface DGDatabaseContentTableViewCell : UITableViewCell 14 | 15 | @property (nonatomic, copy) void(^clickButton)(UIButton *button, NSInteger column); 16 | 17 | - (void)loadContents:(NSArray *)contents columnWidths:(NSArray *)columnWidths; 18 | 19 | @end 20 | 21 | NS_ASSUME_NONNULL_END 22 | -------------------------------------------------------------------------------- /Debugo/Classes/Entrance/DGEntrance.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGEntrance.h 3 | // Debugo 4 | // 5 | // GitHub https://github.com/ripperhe/Debugo 6 | // Created by ripper on 2018/9/1. 7 | // Copyright © 2018年 ripper. All rights reserved. 8 | // 9 | 10 | #import 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface DGEntrance : NSObject 15 | 16 | /// bubble 长按事件 17 | @property (nonatomic, copy) void(^bubbleLongPressBlock)(void); 18 | 19 | + (instancetype)shared; 20 | 21 | /// 显示悬浮球 22 | - (void)showBubble; 23 | 24 | /// 关闭 debug window 25 | - (void)closeDebugWindow; 26 | 27 | @end 28 | 29 | NS_ASSUME_NONNULL_END 30 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/FilePlugin/DGDatabaseTableInfo.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGDatabaseTableInfo.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/1/9. 6 | // Copyright © 2019 ripper. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface DGDatabaseTableInfo : NSObject 14 | 15 | @property (nonatomic, copy) NSString *type; 16 | @property (nonatomic, copy) NSString *name; 17 | @property (nonatomic, copy) NSString *tbl_name; 18 | @property (nonatomic, assign) NSInteger rootpage; 19 | @property (nonatomic, copy) NSString *sql; 20 | 21 | @end 22 | 23 | NS_ASSUME_NONNULL_END 24 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/FilePlugin/DGFilePluginConfiguration.m: -------------------------------------------------------------------------------- 1 | // 2 | // DGFilePreviewConfiguration.m 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/5/31. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import "DGFilePluginConfiguration.h" 10 | #import "DGCommon.h" 11 | 12 | @implementation DGFilePluginConfiguration 13 | 14 | - (instancetype)init 15 | { 16 | self = [super init]; 17 | if (self) { 18 | _shortcutForDatabasePaths = @[DGPathFetcher.documentsDirectory]; 19 | _shortcutForAnyPaths = @[DGPathFetcher.userDefaultsPlistFilePath]; 20 | } 21 | return self; 22 | } 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Pods/Target Support Files/FMDB/FMDB.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FMDB 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/FMDB" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/FMDB" 4 | PODS_BUILD_DIR = ${BUILD_DIR} 5 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 6 | PODS_ROOT = ${SRCROOT} 7 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/FMDB 8 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 9 | SKIP_INSTALL = YES 10 | -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Pods/Target Support Files/Pods-Debugo-Example-ObjectiveC/Pods-Debugo-Example-ObjectiveC.debug.xcconfig: -------------------------------------------------------------------------------- 1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 2 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/FMDB" 3 | LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FMDB" 4 | OTHER_LDFLAGS = $(inherited) -ObjC -l"FMDB" -l"sqlite3" 5 | PODS_BUILD_DIR = ${BUILD_DIR} 6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 8 | PODS_ROOT = ${SRCROOT}/Pods 9 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 10 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/AccountPlugin/DGAccount.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGAccount.h 3 | // Debugo 4 | // 5 | // GitHub https://github.com/ripperhe/Debugo 6 | // Created by ripper on 2018/9/1. 7 | // Copyright © 2018年 ripper. All rights reserved. 8 | // 9 | 10 | 11 | #import 12 | 13 | NS_ASSUME_NONNULL_BEGIN 14 | 15 | @interface DGAccount : NSObject 16 | 17 | /** App 账号的用户名 */ 18 | @property (nonatomic, copy) NSString *username; 19 | /** App 账号的密码 */ 20 | @property (nonatomic, copy) NSString *password; 21 | 22 | + (instancetype)accountWithUsername:(NSString *)username password:(NSString *)password; 23 | - (BOOL)isValid; 24 | 25 | @end 26 | 27 | NS_ASSUME_NONNULL_END 28 | -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Pods/Target Support Files/Pods-Debugo-Example-ObjectiveC/Pods-Debugo-Example-ObjectiveC.release.xcconfig: -------------------------------------------------------------------------------- 1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 2 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/FMDB" 3 | LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FMDB" 4 | OTHER_LDFLAGS = $(inherited) -ObjC -l"FMDB" -l"sqlite3" 5 | PODS_BUILD_DIR = ${BUILD_DIR} 6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 8 | PODS_ROOT = ${SRCROOT}/Pods 9 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 10 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/PodPlugin/DGSpecRepoModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGSpecRepoModel.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/10/25. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "DGPodModel.h" 11 | #import "DGOrderedDictionary.h" 12 | 13 | NS_ASSUME_NONNULL_BEGIN 14 | 15 | @interface DGSpecRepoModel : NSObject 16 | 17 | @property (nonatomic, copy) NSString *url; 18 | @property (nonatomic, assign) BOOL isOfficial; 19 | @property (nonatomic, assign) BOOL isRemote; 20 | @property (nonatomic, strong) DGOrderedDictionary *pods; 21 | 22 | @end 23 | 24 | NS_ASSUME_NONNULL_END 25 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/FilePlugin/DGDatabaseColumnInfo.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGDatabaseColumnInfo.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/1/9. 6 | // Copyright © 2019 ripper. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface DGDatabaseColumnInfo : NSObject 14 | 15 | @property (nonatomic, assign) NSInteger cid; 16 | @property (nonatomic, copy) NSString *name; 17 | @property (nonatomic, copy) NSString *type; 18 | @property (nonatomic, assign) NSInteger notnull; 19 | @property (nonatomic, strong) id dflt_value; 20 | @property (nonatomic, assign) NSInteger pk; 21 | 22 | @end 23 | 24 | NS_ASSUME_NONNULL_END 25 | -------------------------------------------------------------------------------- /Debugo/Classes/Common/Category/NSFileManager+Debugo.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSFileManager+Debugo.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/5/10. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface NSFileManager (Debugo) 14 | 15 | /** 单个文件大小,返回字节 */ 16 | - (long long)dg_fileSizeAtPath:(NSString *)path; 17 | 18 | /** 递归遍历文件夹来计算文件夹大小,返回字节 */ 19 | - (long long)dg_folderSizeAtPath:(NSString *)path; 20 | 21 | /** 异步获取文件夹大小,completion 回调字节 */ 22 | - (void)dg_asyncCalculateFolderSizeAtPath:(NSString *)path completion:(void (^)(long long size))completion; 23 | 24 | @end 25 | 26 | NS_ASSUME_NONNULL_END 27 | -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Pods/Target Support Files/FMDB/FMDB.debug.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FMDB 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/FMDB" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/FMDB" 4 | PODS_BUILD_DIR = ${BUILD_DIR} 5 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 6 | PODS_ROOT = ${SRCROOT} 7 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/FMDB 8 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 9 | SKIP_INSTALL = YES 10 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 11 | -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Pods/Target Support Files/FMDB/FMDB.release.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FMDB 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/FMDB" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/FMDB" 4 | PODS_BUILD_DIR = ${BUILD_DIR} 5 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 6 | PODS_ROOT = ${SRCROOT} 7 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/FMDB 8 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 9 | SKIP_INSTALL = YES 10 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 11 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/FilePlugin/DGFileParser.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGFileParser.h 3 | // Debugo 4 | // 5 | // GitHub https://github.com/ripperhe/Debugo 6 | // Created by ripper on 2018/9/1. 7 | // Copyright © 2018年 ripper. All rights reserved. 8 | // 9 | 10 | #import 11 | #import "DGFilePreviewConfiguration.h" 12 | 13 | @interface DGFileParser : NSObject 14 | 15 | + (NSArray *)filesForDirectory:(NSURL *)direcotryURL configuration:(DGFilePreviewConfiguration *)configuration errorHandler:(void (NS_NOESCAPE^)(NSError * error))errorHandler; 16 | 17 | + (NSArray *)filesForPath:(NSString *)path forType:(DGFileType)type errorHandler:(void (NS_NOESCAPE^)(NSError * error))errorHandler; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/FilePlugin/DGDatabasePreviewViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGDatabasePreviewViewController.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/1/9. 6 | // Copyright © 2019 ripper. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "DGFile.h" 11 | #import "DGDatabasePreviewConfiguration.h" 12 | 13 | NS_ASSUME_NONNULL_BEGIN 14 | 15 | /** 16 | Reference: 17 | * https://github.com/YanPengImp/DatabaseVisual 18 | */ 19 | @interface DGDatabasePreviewViewController : UITableViewController 20 | 21 | @property (nonatomic, strong) DGFile *file; 22 | @property (nonatomic, strong) DGDatabasePreviewConfiguration *previewConfiguration; 23 | 24 | @end 25 | 26 | NS_ASSUME_NONNULL_END 27 | -------------------------------------------------------------------------------- /Debugo/Classes/Common/UI/DGWindow.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGWindow.h 3 | // Debugo 4 | // 5 | // GitHub https://github.com/ripperhe/Debugo 6 | // Created by ripper on 2018/9/1. 7 | // Copyright © 2018年 ripper. All rights reserved. 8 | // 9 | 10 | 11 | #import 12 | 13 | NS_ASSUME_NONNULL_BEGIN 14 | 15 | @interface DGWindow : UIWindow 16 | 17 | @property (nonatomic, copy, nullable) NSString *name; 18 | @property (nonatomic, weak, nullable) UIWindow *lastKeyWindow; 19 | 20 | @property (nonatomic, assign) BOOL dg_canAffectStatusBarAppearance; 21 | @property (nonatomic, assign) BOOL dg_canBecomeKeyWindow; 22 | @property (nonatomic, assign) BOOL dg_isInternalWindow; 23 | 24 | - (void)destroy; 25 | 26 | @end 27 | 28 | NS_ASSUME_NONNULL_END 29 | -------------------------------------------------------------------------------- /Debugo/Classes/Common/UI/DGAnimationDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGAnimationDelegate.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/9/13. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface DGAnimationDelegate : NSObject 14 | 15 | @property (nonatomic, copy) void(^didStartBlock)(CAAnimation *animation); 16 | @property (nonatomic, copy) void(^didStopBlock)(CAAnimation *animation, BOOL finishFlag); 17 | 18 | + (instancetype)animationDelegateWithDidStart:(nullable void (^)(CAAnimation *animation))startBlock didStop:(nullable void (^)(CAAnimation *animation, BOOL finishFlag))stopBlock; 19 | 20 | @end 21 | 22 | NS_ASSUME_NONNULL_END 23 | -------------------------------------------------------------------------------- /Debugo/Classes/Entrance/DGDebugWindow.m: -------------------------------------------------------------------------------- 1 | // 2 | // DGDebugWindow.m 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/9/15. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import "DGDebugWindow.h" 10 | 11 | @implementation DGDebugWindow 12 | 13 | - (instancetype)initWithFrame:(CGRect)frame { 14 | if(self = [super initWithFrame:frame]) { 15 | DGDebugViewController *debugVC = [[DGDebugViewController alloc] init]; 16 | _debugViewController = debugVC; 17 | self.name = @"Debug Window"; 18 | self.rootViewController = debugVC; 19 | self.windowLevel = 1999999; 20 | // 防止 navigationbar 为 translucent 时,有黑色阴影 21 | self.backgroundColor = [UIColor whiteColor]; 22 | } 23 | return self; 24 | } 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /fastlane/README.md: -------------------------------------------------------------------------------- 1 | fastlane documentation 2 | ================ 3 | # Installation 4 | 5 | Make sure you have the latest version of the Xcode command line tools installed: 6 | 7 | ``` 8 | xcode-select --install 9 | ``` 10 | 11 | Install _fastlane_ using 12 | ``` 13 | [sudo] gem install fastlane -NV 14 | ``` 15 | or alternatively using `brew cask install fastlane` 16 | 17 | # Available Actions 18 | ### release_pod 19 | ``` 20 | fastlane release_pod 21 | ``` 22 | Release new pod version 23 | 24 | ---- 25 | 26 | This README.md is auto-generated and will be re-generated every time [fastlane](https://fastlane.tools) is run. 27 | More information about fastlane can be found on [fastlane.tools](https://fastlane.tools). 28 | The documentation of fastlane can be found on [docs.fastlane.tools](https://docs.fastlane.tools). 29 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/AccountPlugin/DGAccountPlugin.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGAccountPlugin.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/5/31. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import "DGPlugin.h" 10 | #import "DGCommon.h" 11 | #import "DGBubble.h" 12 | #import "DGAccountPluginConfiguration.h" 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | @interface DGAccountPlugin : DGPlugin 17 | 18 | @property (nonatomic, strong) DGAccountPluginConfiguration *configuration; 19 | @property (nonatomic, strong, nullable) DGOrderedDictionary *cacheAccountDic; 20 | 21 | + (instancetype)shared; 22 | 23 | - (NSArray *)currentCommonAccountArray; 24 | 25 | - (void)addAccount:(DGAccount *)account; 26 | 27 | @end 28 | 29 | NS_ASSUME_NONNULL_END 30 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/FilePlugin/DGDatabaseTableContentViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGDatabaseTableContentViewController.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/1/9. 6 | // Copyright © 2019 ripper. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "DGDatabaseOperation.h" 11 | #import "DGDatabasePreviewConfiguration.h" 12 | 13 | NS_ASSUME_NONNULL_BEGIN 14 | 15 | @interface DGDatabaseTableContentViewController : UIViewController 16 | 17 | + (instancetype)new NS_UNAVAILABLE; 18 | - (instancetype)init NS_UNAVAILABLE; 19 | - (instancetype)initWithDatabaseOperation:(DGDatabaseOperation *)operation table:(DGDatabaseTableInfo *)table previewConfiguration:(nullable DGDatabasePreviewConfiguration *)previewConfiguration; 20 | 21 | @end 22 | 23 | NS_ASSUME_NONNULL_END 24 | -------------------------------------------------------------------------------- /Debugo/Classes/Common/Category/UIControl+Debugo.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIControl+Debugo.h 3 | // StaticTableView 4 | // 5 | // Created by ripper on 2019/9/25. 6 | // Copyright © 2019 ripper. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface DGReceiver : NSObject 14 | 15 | @property (nonatomic, copy) void(^handler)(id sender); 16 | @property (nonatomic, assign) UIControlEvents controlEvents; 17 | 18 | - (void)receiveAction:(id)sender; 19 | 20 | @end 21 | 22 | @interface UIControl (DGStaticProvider) 23 | 24 | - (DGReceiver *)dg_addReceiverForControlEvents:(UIControlEvents)controlEvents handler:(void (^)(id sender))handler; 25 | 26 | - (void)dg_removeReceiver:(DGReceiver *)receiver; 27 | 28 | - (void)dg_removeAllReceivers; 29 | 30 | @end 31 | 32 | NS_ASSUME_NONNULL_END 33 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/ActionPlugin/DGActionPluginConfiguration.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGActionPluginConfiguration.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/9/15. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "DGAction.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface DGActionPluginConfiguration : NSObject 15 | 16 | /// 添加共享指令,触发后自动关闭 Debug Window 17 | - (void)addCommonActionWithTitle:(NSString *)title handler:(DGActionHandlerBlock)handler; 18 | 19 | /// 添加共享指令,通过 autoClose 控制触发后是否自动关闭 Debug Window 20 | - (void)addCommonActionWithTitle:(NSString *)title handler:(DGActionHandlerBlock)handler autoClose:(BOOL)autoClose; 21 | 22 | /// 获取所有共享指令;外部一般不需要使用 23 | - (NSArray *)getAllCommonActions; 24 | 25 | @end 26 | 27 | NS_ASSUME_NONNULL_END 28 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/FilePlugin/DGFilePluginConfiguration.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGFilePreviewConfiguration.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/5/31. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "DGFilePreviewConfiguration.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface DGFilePluginConfiguration : NSObject 15 | 16 | /// 自定义快捷显示数据库文件(数据库文件或包含数据库的文件夹) 17 | @property (nonatomic, strong) NSArray *shortcutForDatabasePaths; 18 | /// 自定义快捷显示任意文件(文件或文件夹均可) 19 | @property (nonatomic, strong) NSArray *shortcutForAnyPaths; 20 | 21 | /// 需要自行控制显示数据库文件的表的列宽的时候,设置该block 22 | @property (nonatomic, copy) DGDatabasePreviewConfiguration * _Nullable(^databaseFilePreviewConfigurationBlock)(NSString *filePath); 23 | 24 | @end 25 | 26 | NS_ASSUME_NONNULL_END 27 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/AppInfoPlugin/DGAppInfoPlugin.m: -------------------------------------------------------------------------------- 1 | // 2 | // DGAppInfoPlugin.m 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/9/9. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import "DGAppInfoPlugin.h" 10 | #import "DGAppInfoViewController.h" 11 | #import "DGCommon.h" 12 | 13 | @implementation DGAppInfoPlugin 14 | 15 | + (NSString *)pluginName { 16 | return @"APP信息"; 17 | } 18 | 19 | + (UIImage *)pluginImage { 20 | return [DGBundle imageNamed:@"plugin_appinfo"]; 21 | } 22 | 23 | + (UIImage *)pluginTabBarImage:(BOOL)isSelected { 24 | if (isSelected) { 25 | return [DGBundle imageNamed:@"tab_appinfo_selected"]; 26 | } 27 | return [DGBundle imageNamed:@"tab_appinfo_normal"]; 28 | } 29 | 30 | + (UIViewController *)pluginViewController { 31 | return [DGAppInfoViewController new]; 32 | } 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/PodPlugin/DGPodModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGPodModel.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/10/24. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "DGCommon.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface DGPodModel : NSObject 15 | 16 | @property (nonatomic, copy) NSString *name; 17 | @property (nonatomic, copy) NSString *version; 18 | @property (nonatomic, strong) NSArray *nameComponents; 19 | @property (nonatomic, strong) DGOrderedDictionary *subPods; 20 | 21 | // 以下为网络请求获取 22 | 23 | @property (nonatomic, copy, nullable) NSString *latestVersion; 24 | @property (nonatomic, copy, nullable) NSString *homepage; 25 | @property (nonatomic, copy, nullable) NSString *specFilePath; 26 | 27 | @end 28 | 29 | NS_ASSUME_NONNULL_END 30 | -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/Login/LoginSuccessViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // LoginSuccessViewController.m 3 | // Debugo_Example 4 | // 5 | // Created by ripper on 2018/9/21. 6 | // Copyright © 2018年 ripperhe. All rights reserved. 7 | // 8 | 9 | #import "LoginSuccessViewController.h" 10 | #import "Debugo.h" 11 | 12 | @interface LoginSuccessViewController () 13 | 14 | @end 15 | 16 | @implementation LoginSuccessViewController 17 | 18 | - (void)viewDidLoad { 19 | [super viewDidLoad]; 20 | // Do any additional setup after loading the view. 21 | 22 | [self.navigationItem setHidesBackButton:YES]; 23 | if (self.accountInfo.count) { 24 | self.title = self.accountInfo.allKeys.firstObject; 25 | } 26 | } 27 | 28 | - (IBAction)clickLogout:(id)sender { 29 | [self.navigationController popViewControllerAnimated:YES]; 30 | } 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /Debugo/Classes/Common/Category/NSString+Debugo.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+Debugo.m 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/10/25. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import "NSString+Debugo.h" 10 | 11 | @implementation NSString (Debugo) 12 | 13 | + (NSString *)dg_stringByCombineComponents:(NSArray *)components separatedString:(NSString *)separatedString { 14 | if (!components.count) { 15 | return nil; 16 | } 17 | NSMutableString *string = [NSMutableString string]; 18 | [components enumerateObjectsUsingBlock:^(NSString * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 19 | [string appendString:obj]; 20 | if (separatedString.length && idx != components.count - 1) { 21 | [string appendString:separatedString]; 22 | } 23 | }]; 24 | return string; 25 | } 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /Debugo/Classes/Common/DGCommon.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGCommon.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/1/20. 6 | // Copyright © 2019 ripper. All rights reserved. 7 | // 8 | 9 | #import "DGBundle.h" 10 | #import "DGCache.h" 11 | #import "DGBuildInfo.h" 12 | 13 | #import "NSObject+Debugo.h" 14 | #import "NSString+Debugo.h" 15 | #import "NSDate+Debugo.h" 16 | #import "NSNumber+Debugo.h" 17 | #import "NSFileManager+Debugo.h" 18 | #import "UIView+Debugo.h" 19 | #import "UIControl+Debugo.h" 20 | #import "UIColor+Debugo.h" 21 | 22 | #import "DGTool.h" 23 | #import "DGPlister.h" 24 | #import "DGOrderedDictionary.h" 25 | #import "DGDevice.h" 26 | #import "DGPathFetcher.h" 27 | 28 | #import "DGNavigationController.h" 29 | #import "DGCommonGridViewController.h" 30 | #import "DGWindow.h" 31 | #import "DGShareBarButtonItem.h" 32 | #import "DGAnimationDelegate.h" 33 | #import "DGStaticProvider.h" 34 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/FilePlugin/DGFilePreviewConfiguration.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGFilePreviewConfiguration.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/3/21. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "DGFile.h" 11 | #import "DGDatabasePreviewConfiguration.h" 12 | 13 | NS_ASSUME_NONNULL_BEGIN 14 | 15 | @interface DGFilePreviewConfiguration : NSObject 16 | 17 | @property (nonatomic, strong) NSArray *allowedFileTypes; 18 | 19 | @property (nonatomic, strong) NSArray *ignoredFileTypes; 20 | 21 | @property (nonatomic, assign) BOOL forbidEditing; 22 | 23 | @property (nonatomic, copy) void(^didSelectFileBlock)(DGFile *file); 24 | 25 | @property (nonatomic, copy) DGDatabasePreviewConfiguration * _Nullable(^databaseFilePreviewConfigurationBlock)(DGFile *file); 26 | 27 | @end 28 | 29 | NS_ASSUME_NONNULL_END 30 | -------------------------------------------------------------------------------- /Debugo/Classes/Common/Category/UIView+Debugo.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+Debugo.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/9/8. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface UIView (Debugo) 14 | 15 | @property (nonatomic, assign) CGFloat dg_x; 16 | @property (nonatomic, assign) CGFloat dg_y; 17 | @property (nonatomic, assign) CGFloat dg_width; 18 | @property (nonatomic, assign) CGFloat dg_height; 19 | @property (nonatomic, assign) CGFloat dg_bottom; 20 | @property (nonatomic, assign) CGFloat dg_right; 21 | @property (nonatomic, assign) CGFloat dg_centerX; 22 | @property (nonatomic, assign) CGFloat dg_centerY; 23 | @property (nonatomic, assign) CGPoint dg_origin; 24 | @property (nonatomic, assign) CGSize dg_size; 25 | 26 | - (UIEdgeInsets)dg_safeAreaInsets; 27 | 28 | @end 29 | 30 | NS_ASSUME_NONNULL_END 31 | -------------------------------------------------------------------------------- /Debugo/Classes/Common/UI/DGShareBarButtonItem.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGShareBarButtonItem.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/3/20. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface DGShareBarButtonItem : UIBarButtonItem 14 | 15 | @property (nonatomic, weak) UIViewController *viewController; 16 | @property (nonatomic, copy) NSArray *(^shareFilePathsWhenClickedBlock)(DGShareBarButtonItem *); 17 | 18 | - (instancetype)initWithBarButtonSystemItem:(UIBarButtonSystemItem)systemItem target:(nullable id)target action:(nullable SEL)action NS_UNAVAILABLE ; 19 | - (instancetype)initWithViewController:(UIViewController *)viewController shareFilePathsWhenClickedBlock:(nullable NSArray * (^)(DGShareBarButtonItem *item))shareFilePathsWhenClickedBlock; 20 | 21 | @end 22 | 23 | NS_ASSUME_NONNULL_END 24 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/FilePlugin/DGDatabaseOperation.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGDatabaseOperation.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/1/9. 6 | // Copyright © 2019 ripper. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "DGDatabaseTableInfo.h" 11 | #import "DGDatabaseColumnInfo.h" 12 | @class FMDatabaseQueue; 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | @interface DGDatabaseOperation : NSObject 17 | 18 | + (instancetype)new NS_UNAVAILABLE; 19 | - (instancetype)init NS_UNAVAILABLE; 20 | - (instancetype)initWithURL:(NSURL *)url; 21 | - (instancetype)initWithDBQueue:(FMDatabaseQueue *)dbQueue; 22 | 23 | - (NSArray *)queryAllTableInfo; 24 | - (NSArray *)queryAllColumnInfoForTable:(DGDatabaseTableInfo *)table; 25 | - (NSArray *)queryAllContentForTable:(DGDatabaseTableInfo *)table; 26 | 27 | 28 | @end 29 | 30 | NS_ASSUME_NONNULL_END 31 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/FilePlugin/DGDatabasePreviewConfiguration.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGDatabasePreviewConfiguration.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/1/16. 6 | // Copyright © 2019 ripper. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface DGDatabasePreviewConfiguration : NSObject 14 | 15 | /// 设置整个数据库通用的列宽,默认100,范围[50, 1000] 16 | - (void)setCommonColumnWidth:(CGFloat)columnWidth; 17 | 18 | /// 设置某个表通用的列宽 19 | - (void)setCommonColumnWidth:(CGFloat)columnWidth forTable:(NSString *)tableName; 20 | 21 | /// 设置某个表指定列的列宽,字典key值为列名,value和列宽 22 | - (void)setSpecialColumnWidthDictionary:(NSDictionary *)columnNameToWidth forTable:(NSString *)tableName; 23 | 24 | /// 根据表名和列名获取列宽;外部一般不需要使用 25 | - (CGFloat)columnWidthForTable:(NSString *)tableName column:(NSString *)columnName; 26 | 27 | @end 28 | 29 | NS_ASSUME_NONNULL_END 30 | -------------------------------------------------------------------------------- /Debugo/Classes/Common/Utility/DGPathFetcher.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGPathFetcher.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/2/22. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface DGPathFetcher : NSObject 14 | 15 | + (NSString *)bundleDirectory; 16 | + (NSURL *)bundleDirectoryURL; 17 | 18 | + (NSString *)sandboxDirectory; 19 | + (NSURL *)sandboxDirectoryURL; 20 | 21 | + (NSString *)documentsDirectory; 22 | + (NSURL *)documentsDirectoryURL; 23 | 24 | + (NSString *)libraryDirectory; 25 | + (NSURL *)libraryDirectoryURL; 26 | 27 | + (NSString *)cachesDirectory; 28 | + (NSURL *)cachesDirectoryURL; 29 | 30 | + (NSString *)temporaryDirectory; 31 | + (NSURL *)temporaryDirectoryURL; 32 | 33 | + (NSString *)userDefaultsPlistFilePath; 34 | + (NSURL *)userDefaultsPlistFileURL; 35 | 36 | @end 37 | 38 | NS_ASSUME_NONNULL_END 39 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/PodPlugin/DGPodPluginConfiguration.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGPodPluginConfiguration.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/10/25. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface DGGitLabSpecRepoRequestInfo : NSObject 14 | 15 | /// gitlab 私有库网址; e.g. @"https://gitlab.example.com" 16 | @property (nonatomic, copy) NSString *website; 17 | /// spec repo id; e.g. @"182" 18 | @property (nonatomic, copy) NSString *repoId; 19 | /// gitlab token; e.g. @"ozx_6hEs1J7G5E9ZFHhn" 20 | @property (nonatomic, copy) NSString *privateToken; 21 | 22 | @end 23 | 24 | @interface DGPodPluginConfiguration : NSObject 25 | 26 | /// 配置私有的 gitlab spec 库的信息 27 | @property (nonatomic, copy) DGGitLabSpecRepoRequestInfo * _Nullable (^gitLabSpecRepoRequestInfoBlock)(NSString *specRepoUrl); 28 | 29 | @end 30 | 31 | NS_ASSUME_NONNULL_END 32 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/AccountPlugin/DGAccountPluginConfiguration.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGAccountPluginConfiguration.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/5/31. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "DGAccount.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface DGAccountPluginConfiguration : NSObject 15 | 16 | /** 当前的账号环境是否为生产环境;默认为 NO */ 17 | @property (nonatomic, assign) BOOL isProductionEnvironment; 18 | /** 共享开发环境账号 */ 19 | @property (nullable, nonatomic, strong) NSArray *commonDevelopmentAccounts; 20 | /** 共享生产环境账号;如果不需要, 只设置开发环境账号即可 */ 21 | @property (nullable, nonatomic, strong) NSArray *commonProductionAccounts; 22 | 23 | /** 使用 login bubble 选中列表中的某个账号时,会调用这个 block,并传回账号信息,你需要在这个 block 中实现自动登录 */ 24 | @property (nonatomic, copy) void(^executeLoginBlock)(DGAccount *account); 25 | 26 | @end 27 | 28 | NS_ASSUME_NONNULL_END 29 | -------------------------------------------------------------------------------- /Debugo/Classes/Common/UI/DGAnimationDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // DGAnimationDelegate.m 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/9/13. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import "DGAnimationDelegate.h" 10 | 11 | @implementation DGAnimationDelegate 12 | 13 | + (instancetype)animationDelegateWithDidStart:(void (^)(CAAnimation * _Nonnull))startBlock didStop:(void (^)(CAAnimation * _Nonnull, BOOL))stopBlock { 14 | DGAnimationDelegate *delegate = [self new]; 15 | delegate.didStartBlock = startBlock; 16 | delegate.didStopBlock = stopBlock; 17 | return delegate; 18 | } 19 | 20 | - (void)animationDidStart:(CAAnimation *)anim { 21 | if (self.didStartBlock) { 22 | self.didStartBlock(anim); 23 | } 24 | } 25 | 26 | - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag { 27 | if (self.didStopBlock) { 28 | self.didStopBlock(anim, flag); 29 | } 30 | } 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/DGPlugin.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGPlugin.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/9/9. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @protocol DGPluginProtocol 14 | 15 | /// 组件名称;默认为类名 16 | + (NSString *)pluginName; 17 | 18 | /// 组件图像;不设置则使用默认图像 19 | + (UIImage *)pluginImage; 20 | 21 | /// 组件放在 tabBar 的图像;不设置则使用默认图形 22 | + (UIImage *)pluginTabBarImage:(BOOL)isSelected; 23 | 24 | /// 组件在当前环境是否可以使用;默认为 YES; 25 | + (BOOL)pluginSupport; 26 | 27 | /// 组件对应视图控制器实例对象;如果实现了本方法,点击本工具按钮会跳转到该页面;否则,会直接启用本工具 28 | /// 不能是 UINavigationController 及其子类 29 | + (UIViewController *)pluginViewController; 30 | 31 | /// 组件开关 32 | @property (class, nonatomic, assign) BOOL pluginSwitch; 33 | 34 | @end 35 | 36 | // 所有组件方法均用于子类重写(所有方法可不重写),无需调用父类 37 | @interface DGPlugin : NSObject 38 | 39 | @end 40 | 41 | NS_ASSUME_NONNULL_END 42 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/ActionPlugin/DGActionPlugin.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGActionPlugin.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/5/31. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import "DGPlugin.h" 10 | #import "DGActionPluginConfiguration.h" 11 | #import "DGOrderedDictionary.h" 12 | 13 | NS_ASSUME_NONNULL_BEGIN 14 | 15 | @interface DGActionPlugin : DGPlugin 16 | 17 | @property (nonatomic, strong) DGActionPluginConfiguration *configuration; 18 | 19 | @property (nonatomic, strong, nullable) DGOrderedDictionary *anonymousActionDic; 20 | 21 | @property (nonatomic, strong, nullable) NSMutableDictionary *>*usersActionsDic; 22 | 23 | + (instancetype)shared; 24 | 25 | - (void)addActionForUser:(nullable NSString *)user withTitle:(NSString *)title autoClose:(BOOL)autoClose handler:(DGActionHandlerBlock)handler; 26 | 27 | @end 28 | 29 | NS_ASSUME_NONNULL_END 30 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/DGPlugin.m: -------------------------------------------------------------------------------- 1 | // 2 | // DGPlugin.m 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/9/9. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import "DGPlugin.h" 10 | #import "DGCommon.h" 11 | 12 | @implementation DGPlugin 13 | 14 | + (NSString *)pluginName { 15 | return NSStringFromClass([self class]); 16 | } 17 | 18 | + (UIImage *)pluginImage { 19 | return [DGBundle imageNamed:@"plugin_default"]; 20 | } 21 | 22 | + (UIImage *)pluginTabBarImage:(BOOL)isSelected { 23 | if (isSelected) { 24 | return [DGBundle imageNamed:@"tab_default_selected"]; 25 | } 26 | return [DGBundle imageNamed:@"tab_default_normal"]; 27 | } 28 | 29 | + (BOOL)pluginSupport { 30 | return YES; 31 | } 32 | 33 | + (UIViewController *)pluginViewController { 34 | return nil; 35 | } 36 | 37 | + (void)setPluginSwitch:(BOOL)pluginSwitch { 38 | } 39 | 40 | + (BOOL)pluginSwitch { 41 | return NO; 42 | } 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/UIView+IB.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+IB.m 3 | // Debugo_Example 4 | // 5 | // Created by ripper on 2018/9/28. 6 | // Copyright © 2018 ripperhe. All rights reserved. 7 | // 8 | 9 | #import "UIView+IB.h" 10 | 11 | @implementation UIView (IB) 12 | 13 | - (void)setDg_cornerRadius:(CGFloat)dg_cornerRadius { 14 | self.layer.cornerRadius = dg_cornerRadius; 15 | self.layer.masksToBounds = YES; 16 | } 17 | 18 | - (CGFloat)dg_cornerRadius { 19 | return self.layer.cornerRadius; 20 | } 21 | 22 | - (void)setDg_borderWidth:(CGFloat)dg_borderWidth { 23 | self.layer.borderWidth = dg_borderWidth; 24 | } 25 | 26 | - (CGFloat)dg_borderWidth { 27 | return self.layer.borderWidth; 28 | } 29 | 30 | - (void)setDg_borderColor:(UIColor *)dg_borderColor { 31 | self.layer.borderColor = dg_borderColor.CGColor; 32 | } 33 | 34 | - (UIColor *)dg_borderColor { 35 | return [UIColor colorWithCGColor:self.layer.borderColor]; 36 | } 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/PodPlugin/DGSpecRepoModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // DGSpecRepoModel.m 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/10/25. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import "DGSpecRepoModel.h" 10 | 11 | @implementation DGSpecRepoModel 12 | 13 | - (void)setUrl:(NSString *)url { 14 | _url = url; 15 | NSString *lowercaseString = url.lowercaseString; 16 | if ([lowercaseString hasPrefix:@"https://github.com/cocoapods/specs.git"] || 17 | [lowercaseString hasPrefix:@"https://cdn.cocoapods.org"]) { 18 | _isOfficial = YES; 19 | }else { 20 | _isOfficial = NO; 21 | } 22 | if ([lowercaseString hasPrefix:@"http"]) { 23 | _isRemote = YES; 24 | }else { 25 | _isRemote = NO; 26 | } 27 | } 28 | 29 | - (DGOrderedDictionary *)pods { 30 | if (!_pods) { 31 | _pods = [DGOrderedDictionary dictionary]; 32 | } 33 | return _pods; 34 | } 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/CustomPlugin/CustomPlugin2.m: -------------------------------------------------------------------------------- 1 | // 2 | // CustomPlugin2.m 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/9/15. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import "CustomPlugin2.h" 10 | #import "CustomPlugin2ViewController.h" 11 | 12 | @implementation CustomPlugin2 13 | 14 | + (UIViewController *)pluginViewController { 15 | // 如果点击工具之后,需要跳转到页面,而不是直接开启工具的话,就在这里返回需要跳转的控制器实例对象 16 | return [CustomPlugin2ViewController new]; 17 | } 18 | 19 | static BOOL _switch = NO; 20 | + (NSString *)pluginName { 21 | return @"自定义工具2"; 22 | } 23 | 24 | + (void)setPluginSwitch:(BOOL)pluginSwitch { 25 | if (pluginSwitch == _switch) { 26 | return; 27 | } 28 | _switch = pluginSwitch; 29 | if (pluginSwitch) { 30 | NSLog(@"启动自定义工具2"); 31 | }else { 32 | NSLog(@"关闭自定义工具2"); 33 | } 34 | } 35 | 36 | + (BOOL)pluginSwitch { 37 | return _switch; 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /Debugo/Classes/Common/Category/UIColor+Debugo.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIColor+Debugo.m 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/9/26. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import "UIColor+Debugo.h" 10 | 11 | @implementation UIColor (Debugo) 12 | 13 | + (UIColor *)dg_randomColor { 14 | CGFloat r = (CGFloat)(1 + arc4random() % 100) / 100 ; 15 | CGFloat g = (CGFloat)(1 + arc4random() % 100) / 100 ; 16 | CGFloat b = (CGFloat)(1 + arc4random() % 100) / 100 ; 17 | return [self colorWithRed:r green:g blue:b alpha:1]; 18 | } 19 | 20 | + (UIColor *)dg_lightRandomColor { 21 | // rgb 值均为 1,则为白色,让所有值为 0.6以上,则颜色较浅 22 | int start = 60; 23 | int length = 40; 24 | CGFloat r = (CGFloat)(1 + start + arc4random() % length) / 100 ; 25 | CGFloat g = (CGFloat)(1 + start + arc4random() % length) / 100 ; 26 | CGFloat b = (CGFloat)(1 + start + arc4random() % length) / 100 ; 27 | return [self colorWithRed:r green:g blue:b alpha:1]; 28 | } 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /Debugo.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod lib lint Debugo.podspec' to ensure this is a 3 | # valid spec before submitting. 4 | # 5 | # Any lines starting with a # are optional, but their use is encouraged 6 | # To learn more about a Podspec see https://guides.cocoapods.org/syntax/podspec.html 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | s.name = 'Debugo' 11 | s.version = '0.4.0' 12 | s.summary = '☄️ 一个可能有点用的 iOS 调试工具~' 13 | s.homepage = 'https://github.com/ripperhe/Debugo' 14 | s.license = { :type => 'MIT', :file => 'LICENSE' } 15 | s.author = { 'ripperhe' => '453942056@qq.com' } 16 | s.source = { :git => 'https://github.com/ripperhe/Debugo.git', :tag => s.version.to_s } 17 | s.ios.deployment_target = '8.0' 18 | s.requires_arc = true 19 | s.default_subspec = 'Core' 20 | 21 | s.subspec 'Core' do |sb| 22 | sb.source_files = 'Debugo/Classes/**/*' 23 | sb.resources = 'Debugo/Assets/Debugo.bundle' 24 | sb.dependency 'FMDB', '>= 2.7.2' 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/FilePlugin/DGDefaultPreviewViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // DGDefaultPreviewViewController.m 3 | // Debugo 4 | // 5 | // GitHub https://github.com/ripperhe/Debugo 6 | // Created by ripper on 2018/9/1. 7 | // Copyright © 2018年 ripper. All rights reserved. 8 | // 9 | 10 | #import "DGDefaultPreviewViewController.h" 11 | 12 | @interface DGDefaultPreviewViewController () 13 | 14 | @end 15 | 16 | @implementation DGDefaultPreviewViewController 17 | 18 | - (void)viewDidLoad { 19 | [super viewDidLoad]; 20 | 21 | self.dataSource = self; 22 | } 23 | 24 | - (void)setFile:(DGFile *)file { 25 | _file = file; 26 | self.title = file.displayName; 27 | } 28 | 29 | #pragma mark - QLPreviewControllerDataSource 30 | - (NSInteger)numberOfPreviewItemsInPreviewController:(QLPreviewController *)controller { 31 | return 1; 32 | } 33 | 34 | - (id)previewController:(QLPreviewController *)controller previewItemAtIndex:(NSInteger)index { 35 | return self.file; 36 | } 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/ActionPlugin/DGAction.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGAction.h 3 | // Debugo 4 | // 5 | // GitHub https://github.com/ripperhe/Debugo 6 | // Created by ripper on 2018/9/1. 7 | // Copyright © 2018年 ripper. All rights reserved. 8 | // 9 | 10 | 11 | #import 12 | @class DGAction; 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | typedef void(^DGActionHandlerBlock)(DGAction *action); 17 | 18 | @interface DGAction : NSObject 19 | 20 | /** action 的标题,即 cell title */ 21 | @property (nonatomic, copy) NSString *title; 22 | /** 点击执行 Action 后是否自动关闭 */ 23 | @property (nonatomic, assign) BOOL autoClose; 24 | /** 实际执行的代码 */ 25 | @property (nonatomic, copy) DGActionHandlerBlock handler; 26 | /** 当前 action 归属于哪个使用者 */ 27 | @property (nonatomic, copy) NSString *user; 28 | /** 触发当前 action 的控制器,可以用来推出页面 */ 29 | @property (nonatomic, weak) UIViewController *viewController; 30 | 31 | + (instancetype)actionWithTitle:(NSString *)title autoClose:(BOOL)autoClose handler:(DGActionHandlerBlock)handler; 32 | - (BOOL)isValid; 33 | 34 | @end 35 | 36 | NS_ASSUME_NONNULL_END 37 | -------------------------------------------------------------------------------- /Debugo/Classes/Common/Category/NSNumber+Debugo.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSNumber+Debugo.m 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/3/20. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import "NSNumber+Debugo.h" 10 | 11 | @implementation NSNumber (Debugo) 12 | 13 | - (NSString *)dg_sizeString { 14 | double convertedValue = [self doubleValue]; 15 | if (convertedValue <= 0) return @"0 byte"; 16 | 17 | static NSArray *_unitArray = nil; 18 | static dispatch_once_t onceToken; 19 | dispatch_once(&onceToken, ^{ 20 | _unitArray = @[@"bytes",@"KB",@"MB",@"GB",@"TB",@"PB", @"EB", @"ZB", @"YB"]; 21 | }); 22 | 23 | int idx = 0; 24 | while (convertedValue > 1024) { 25 | convertedValue /= 1024; 26 | idx++; 27 | } 28 | NSString *str = [NSString stringWithFormat:@"%.2f",convertedValue]; 29 | if ([str hasSuffix:@".00"]) { 30 | str = [str substringToIndex:str.length - 3]; 31 | } 32 | return [str stringByAppendingFormat:@" %@", _unitArray[idx]]; 33 | } 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /Debugo/Classes/Common/Category/NSDate+Debugo.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSDate+Debugo.m 3 | // Debugo 4 | // 5 | // GitHub https://github.com/ripperhe/Debugo 6 | // Created by ripper on 2018/9/1. 7 | // Copyright © 2018年 ripper. All rights reserved. 8 | // 9 | 10 | 11 | #import "NSDate+Debugo.h" 12 | 13 | @implementation NSDate (Debugo) 14 | 15 | - (NSString *)dg_dateString { 16 | return [self dg_dateStringWithFormat:@"yyyy-MM-dd HH:mm:ss.SSS"]; 17 | } 18 | 19 | - (NSString *)dg_dateStringWithFormat:(NSString *)format { 20 | // https://stackoverflow.com/questions/1526990/nstimezone-what-is-the-difference-between-localtimezone-and-systemtimezone 21 | NSDateFormatter *dateFormatter = [NSDateFormatter new]; 22 | dateFormatter.dateFormat = format; 23 | dateFormatter.timeZone = [NSTimeZone localTimeZone]; 24 | dateFormatter.timeZone = [NSTimeZone timeZoneWithName:@"Asia/Shanghai"]; 25 | dateFormatter.locale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]; 26 | NSString *dateStr = [dateFormatter stringFromDate:self]; 27 | return dateStr; 28 | } 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /Debugo/Classes/Common/UI/DGCommonGridViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGCommonGridViewController.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/9/8. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface DGCommonGridConfiguration : NSObject 14 | 15 | @property (nonatomic, copy) NSString *title; 16 | @property (nonatomic, copy) NSString *imageName; 17 | @property (nonatomic, strong) UIImage *image; 18 | @property (nonatomic, assign) Class selectedPushViewControllerClass; 19 | @property (nonatomic, copy) UIViewController *(^selectedPushViewControlerBlock)(void); 20 | @property (nonatomic, copy) void(^selectedBlock)(void); 21 | 22 | @end 23 | 24 | @interface DGCommonGridViewController : UIViewController 25 | 26 | @property (nonatomic, strong) NSMutableArray *dataArray; 27 | 28 | /// 用于子类重写,配置数据源 29 | - (void)setupDatasouce; 30 | /// 用于子类方便添加网格 31 | - (void)addGrid:(void (^)(DGCommonGridConfiguration *configuration))block; 32 | 33 | @end 34 | 35 | NS_ASSUME_NONNULL_END 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018 ripperhe <453942056@qq.com> 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/DGPluginManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGPluginManager.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/10/30. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "DGActionPlugin.h" 11 | #import "DGFilePlugin.h" 12 | #import "DGAppInfoPlugin.h" 13 | #import "DGAccountPlugin.h" 14 | #import "DGApplePlugin.h" 15 | #import "DGTouchPlugin.h" 16 | #import "DGColorPlugin.h" 17 | #import "DGPodPlugin.h" 18 | 19 | NS_ASSUME_NONNULL_BEGIN 20 | 21 | @interface DGPluginManager : NSObject 22 | 23 | /// debugo 自带的工具 24 | @property (nonatomic, strong) NSArray> *debugoPlugins; 25 | /// 自定义工具 26 | @property (nonatomic, strong) NSMutableArray> *customPlugins; 27 | /// 放在 tabBar 的工具 28 | @property (nonatomic, strong) NSMutableArray> *tabBarPlugins; 29 | 30 | + (instancetype)shared; 31 | 32 | - (void)addCustomPlugin:(Class)plugin; 33 | 34 | - (void)putPluginsToTabBar:(nullable NSArray> *)plugins; 35 | 36 | @end 37 | 38 | NS_ASSUME_NONNULL_END 39 | -------------------------------------------------------------------------------- /Debugo/Classes/Common/UI/DGStaticRow.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGStaticRow.h 3 | // StaticTableView 4 | // 5 | // Created by ripper on 2019/9/25. 6 | // Copyright © 2019 ripper. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface DGStaticRow : NSObject 14 | 15 | /// cell 标识符,自动生成,防止复用 16 | /// 一般情况下,每行会复用自己的 cell;当遇到内存警告的时候,则会重新创建 17 | @property (nonatomic, copy) NSString *identifier; 18 | 19 | /// 创建 cell; 只有需要创建的时候才会调用此方法 20 | @property (nonatomic, copy) UITableViewCell *(^createCell)(NSIndexPath *indexPath, NSString *identifier); 21 | /// 即将显示 cell 22 | @property (nonatomic, copy) void(^willDisplay)(id cell, NSIndexPath *indexPath); 23 | 24 | /// cell 高度配置 25 | @property (nonatomic, assign) CGFloat height; 26 | @property (nonatomic, copy) CGFloat(^heightBlock)(void); 27 | 28 | /// cell 点击事件 29 | @property (nonatomic, copy) void(^didSelectCell)(NSIndexPath *indexPath); 30 | 31 | /// cell 的 accessoryButton 点击事件 32 | @property (nonatomic, copy) void(^accessoryButtonTapped)(NSIndexPath *indexPath); 33 | 34 | + (instancetype)row:(void (^)(DGStaticRow *row))block; 35 | 36 | @end 37 | 38 | NS_ASSUME_NONNULL_END 39 | -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/2/20. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "LoginViewController.h" 11 | #import "Debugo.h" 12 | 13 | @implementation ViewController 14 | 15 | - (void)viewDidLoad { 16 | [super viewDidLoad]; 17 | // Do any additional setup after loading the view, typically from a nib. 18 | } 19 | 20 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 21 | [tableView deselectRowAtIndexPath:indexPath animated:YES]; 22 | if (indexPath.section == 0 && indexPath.row == 0) { 23 | [self clickGoToTestLogin]; 24 | } 25 | } 26 | 27 | - (void)clickGoToTestLogin { 28 | UIStoryboard *board = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]]; 29 | LoginViewController *loginVC = [board instantiateViewControllerWithIdentifier:@"LoginViewController"]; 30 | [self.navigationController pushViewController:loginVC animated:YES]; 31 | } 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/FilePlugin/DGFileTableViewCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // DGFileTableViewCell.m 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/9/14. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import "DGFileTableViewCell.h" 10 | 11 | @implementation DGFileTableViewCell 12 | 13 | - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { 14 | if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) { 15 | self.textLabel.lineBreakMode = NSLineBreakByTruncatingMiddle; 16 | self.selectionStyle = UITableViewCellSelectionStyleBlue; 17 | self.detailTextLabel.textColor = [UIColor grayColor]; 18 | } 19 | return self; 20 | } 21 | 22 | - (void)refreshWithFile:(DGFile *)file { 23 | self.textLabel.text = file.displayName; 24 | self.detailTextLabel.text = file.simpleInfo; 25 | self.imageView.image = file.image; 26 | self.accessoryType = file.isDirectory?UITableViewCellAccessoryDisclosureIndicator:UITableViewCellAccessoryDetailButton; 27 | self.accessoryView.userInteractionEnabled = !file.isDirectory; 28 | } 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /Debugo/Classes/Common/Source/DGBundle.m: -------------------------------------------------------------------------------- 1 | // 2 | // DGBundle.m 3 | // Debugo 4 | // 5 | // GitHub https://github.com/ripperhe/Debugo 6 | // Created by ripper on 2018/9/1. 7 | // Copyright © 2018年 ripper. All rights reserved. 8 | // 9 | 10 | #import "DGBundle.h" 11 | 12 | @implementation DGBundle 13 | 14 | + (NSBundle *)bundle { 15 | static NSBundle *_bundle = nil; 16 | static dispatch_once_t onceToken; 17 | dispatch_once(&onceToken, ^{ 18 | // 利用 cocoapods 安装,不使用 framework 的情况下 就是 main bundle 19 | // 使用 use_frameworks! 则会生成 Debugo.framework 20 | // 而 Debugo.bundle 在 Debugo.framework 内部,所以直接使用 [NSBundle mainBundle] 不行 21 | NSBundle *selfBundle = [NSBundle bundleForClass:[self class]]; 22 | NSString *bundlePath = [selfBundle pathForResource:@"Debugo" ofType:@"bundle"]; 23 | _bundle = [NSBundle bundleWithPath:bundlePath]; 24 | }); 25 | return _bundle; 26 | } 27 | 28 | + (UIImage *)imageNamed:(NSString *)name; { 29 | NSBundle *bundle = self.bundle; 30 | UIImage *image = [UIImage imageNamed:name inBundle:bundle compatibleWithTraitCollection:nil]; 31 | NSAssert(image, @"DGBundle:name 为 %@ 的图片找不到", name); 32 | return image; 33 | } 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/AccountPlugin/DGAccount.m: -------------------------------------------------------------------------------- 1 | // 2 | // DGAccount.m 3 | // Debugo 4 | // 5 | // GitHub https://github.com/ripperhe/Debugo 6 | // Created by ripper on 2018/9/1. 7 | // Copyright © 2018年 ripper. All rights reserved. 8 | // 9 | 10 | 11 | #import "DGAccount.h" 12 | 13 | @implementation DGAccount 14 | 15 | + (instancetype)accountWithUsername:(NSString *)username password:(NSString *)password; { 16 | return [[self alloc] initWithUsername:username password:password]; 17 | } 18 | 19 | - (instancetype)initWithUsername:(NSString *)username password:(NSString *)password { 20 | self = [super init]; 21 | if (self) { 22 | NSAssert(username.length > 0 && password.length > 0, @"DGAccount: username 和 password 不能为空!"); 23 | self.username = username; 24 | self.password = password; 25 | } 26 | return self; 27 | } 28 | 29 | - (BOOL)isValid { 30 | if (self.username.length > 0 && self.password.length > 0) { 31 | return YES; 32 | } 33 | return NO; 34 | } 35 | 36 | - (NSString *)description { 37 | return [NSString stringWithFormat:@"<%@: %p, username: %@, password: %@>", NSStringFromClass([self class]), self, self.username, self.password]; 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/ActionPlugin/DGActionPluginConfiguration.m: -------------------------------------------------------------------------------- 1 | // 2 | // DGActionPluginConfiguration.m 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/9/15. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import "DGActionPluginConfiguration.h" 10 | 11 | @interface DGActionPluginConfiguration() 12 | 13 | @property (nonatomic, strong) NSMutableArray *commonActions; 14 | 15 | @end 16 | 17 | @implementation DGActionPluginConfiguration 18 | 19 | - (NSMutableArray *)commonActions { 20 | if (!_commonActions) { 21 | _commonActions = [NSMutableArray array]; 22 | } 23 | return _commonActions; 24 | } 25 | 26 | - (void)addCommonActionWithTitle:(NSString *)title handler:(DGActionHandlerBlock)handler { 27 | [self.commonActions addObject:[DGAction actionWithTitle:title autoClose:YES handler:handler]]; 28 | } 29 | 30 | - (void)addCommonActionWithTitle:(NSString *)title handler:(DGActionHandlerBlock)handler autoClose:(BOOL)autoClose { 31 | [self.commonActions addObject:[DGAction actionWithTitle:title autoClose:autoClose handler:handler]]; 32 | } 33 | 34 | - (NSArray *)getAllCommonActions { 35 | return self.commonActions; 36 | } 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /Debugo/Classes/Common/UI/DGNavigationController.m: -------------------------------------------------------------------------------- 1 | // 2 | // DGNavigationController.m 3 | // Debugo 4 | // 5 | // GitHub https://github.com/ripperhe/Debugo 6 | // Created by ripper on 2018/9/1. 7 | // Copyright © 2018年 ripper. All rights reserved. 8 | // 9 | 10 | #import "DGNavigationController.h" 11 | #import "DGCommon.h" 12 | 13 | @interface DGNavigationController () 14 | 15 | @end 16 | 17 | @implementation DGNavigationController 18 | 19 | - (void)viewDidLoad { 20 | [super viewDidLoad]; 21 | [self.navigationBar setTintColor:kDGHighlightColor]; 22 | // [self.navigationBar setTranslucent:NO]; 23 | } 24 | 25 | - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated { 26 | // 下一个控制器被推出来的时候隐藏 tabBar 27 | if (self.viewControllers.count > 0) { 28 | viewController.hidesBottomBarWhenPushed = YES; 29 | } 30 | 31 | // 去掉返回按钮文字 32 | UIViewController *currentViewController = self.topViewController; 33 | if (currentViewController) { 34 | currentViewController.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:NULL]; 35 | } 36 | 37 | [super pushViewController:viewController animated:animated]; 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/ColorPlugin/UIView+DGColorPlugin.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+DGColorPlugin.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/9/26. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | typedef NS_ENUM(NSUInteger, DGRenderType) { 14 | /// 不渲染 15 | DGRenderTypeNone, 16 | /// 渲染子视图 17 | DGRenderTypeLeaves, 18 | /// 渲染自己和子视图 19 | DGRenderTypeContainerAndLeaves, 20 | }; 21 | 22 | typedef NS_ENUM(NSUInteger, DGColorType) { 23 | /// 随机色 24 | DGColorTypeRandomColor, 25 | /// 半透明随机色 26 | DGColorTypeRandomColorWithAlpha, 27 | /// 半透明红色 28 | DGColorTypeRedColorWithAlpha, 29 | }; 30 | 31 | @interface UIView (DGColorPlugin) 32 | 33 | /// 背景色渲染规则 34 | @property (nonatomic, assign) DGRenderType dg_renderType; 35 | /// 背景色类型 36 | @property (nonatomic, assign) DGColorType dg_colorType; 37 | /// 标记一个view是否渲染过 38 | @property (nonatomic, assign, readonly) BOOL dg_hasBeenRendered; 39 | /// 标记一个view是否已经被添加了debug背景色,外部一般不使用 40 | @property (nonatomic, assign, readonly) BOOL dg_hasDebugColor; 41 | /// 视图原始色,外部一般不使用 42 | @property (nonatomic, strong, readonly, nullable) UIColor *dg_originalColor; 43 | 44 | @end 45 | 46 | NS_ASSUME_NONNULL_END 47 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/PodPlugin/DGPodPlugin.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGPodPlugin.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/10/25. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import "DGPlugin.h" 10 | #import "DGSpecRepoModel.h" 11 | #import "DGPodModel.h" 12 | #import "DGPodPluginConfiguration.h" 13 | 14 | NS_ASSUME_NONNULL_BEGIN 15 | 16 | @interface DGPodPlugin : DGPlugin 17 | 18 | @property (nonatomic, strong) DGPodPluginConfiguration *configuration; 19 | 20 | + (instancetype)shared; 21 | 22 | /// 解析 podfile.lock 文件 23 | + (nullable NSArray *)parsePodfileLockWithPath:(NSString *)path; 24 | 25 | /// 从 CocoaPods 官方库获取某个 pod 最新版本信息 26 | + (void)queryLatestPodInfoFromCocoaPodsSpecRepoWithPodName:(NSString *)podName completion:(void (^)(NSDictionary * _Nullable podInfo, NSError * _Nullable error))completion; 27 | 28 | /// 从某个 GitLab 私有 spec 库获取所有 pod 最新版本信息 29 | + (void)queryLatestPodInfoFromGitLabSpecRepoWithRequestInfo:(DGGitLabSpecRepoRequestInfo *)requestInfo completion:(void (^)(DGSpecRepoModel * _Nullable specRepo, NSError * _Nullable error))completion; 30 | 31 | /// 比较两个版本大小 32 | + (NSComparisonResult)compareVersionA:(NSString *)versionA withVersionB:(NSString *)versionB; 33 | 34 | @end 35 | 36 | NS_ASSUME_NONNULL_END 37 | -------------------------------------------------------------------------------- /Debugo/Classes/Entrance/DGBubble.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGBubble.h 3 | // Debugo 4 | // 5 | // GitHub https://github.com/ripperhe/Debugo 6 | // Created by ripper on 2018/9/1. 7 | // Copyright © 2018年 ripper. All rights reserved. 8 | // 9 | 10 | 11 | #import "DGWindow.h" 12 | 13 | @interface DGBubbleConfig : NSObject 14 | 15 | @property (nonatomic, assign) UIButtonType buttonType; 16 | @property (nonatomic, assign) BOOL showClickAnimation; 17 | @property (nonatomic, assign) BOOL showLongPressAnimation; 18 | 19 | @end 20 | 21 | @interface DGBubble : DGWindow 22 | 23 | @property (nonatomic, strong, readonly) DGBubbleConfig *config; 24 | /// 内容视图 25 | @property (nonatomic, weak, readonly) UIView *contentView; 26 | /// 默认 button 27 | @property (nonatomic, weak, readonly) UIButton *button; 28 | 29 | @property (nonatomic, copy) void(^clickBlock)(DGBubble *bubble); 30 | @property (nonatomic, copy) void(^longPressStartBlock)(DGBubble *bubble); 31 | @property (nonatomic, copy) void(^longPressEndBlock)(DGBubble *bubble); 32 | @property (nonatomic, copy) void(^panStartBlock)(DGBubble *bubble); 33 | @property (nonatomic, copy) void(^panEndBlock)(DGBubble *bubble); 34 | 35 | - (instancetype)initWithFrame:(CGRect)frame config:(DGBubbleConfig *)config; 36 | 37 | /// 显示 38 | - (void)show; 39 | 40 | /// 销毁 41 | - (void)removeFromScreen; 42 | 43 | @end 44 | 45 | 46 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/ActionPlugin/DGAction.m: -------------------------------------------------------------------------------- 1 | // 2 | // DGAction.m 3 | // Debugo 4 | // 5 | // GitHub https://github.com/ripperhe/Debugo 6 | // Created by ripper on 2018/9/1. 7 | // Copyright © 2018年 ripper. All rights reserved. 8 | // 9 | 10 | 11 | #import "DGAction.h" 12 | 13 | @implementation DGAction 14 | 15 | + (instancetype)actionWithTitle:(NSString *)title autoClose:(BOOL)autoClose handler:(DGActionHandlerBlock)handler { 16 | return [[self alloc] initWithTitle:title autoClose:autoClose handler:handler]; 17 | } 18 | 19 | - (instancetype)initWithTitle:(NSString *)title autoClose:(BOOL)autoClose handler:(DGActionHandlerBlock)handler { 20 | self = [super init]; 21 | if (self) { 22 | NSAssert(title.length > 0 && handler != nil, @"DGAction: titile 和 handler 不能为空!"); 23 | self.title = title; 24 | self.autoClose = autoClose; 25 | self.handler = handler; 26 | } 27 | return self; 28 | } 29 | 30 | - (BOOL)isValid { 31 | if (self.title.length > 0 && self.handler != nil) { 32 | return YES; 33 | } 34 | return NO; 35 | } 36 | 37 | - (NSString *)description { 38 | return [NSString stringWithFormat:@"<%@: %p, user: %@, title: %@, autioClose: %@, handler: %@>", NSStringFromClass([self class]), self, self.user, self.title, self.autoClose?@"YES":@"NO", self.handler]; 39 | } 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /Debugo/Classes/Common/Category/NSObject+Debugo.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+Debugo.h 3 | // Debugo 4 | // 5 | // GitHub https://github.com/ripperhe/Debugo 6 | // Created by ripper on 2018/9/1. 7 | // Copyright © 2018年 ripper. All rights reserved. 8 | // 9 | 10 | 11 | #import 12 | 13 | @interface NSObject (Debugo) 14 | 15 | /// 扩展 strong 属性 16 | @property (nonatomic, strong) id dg_extStrongObj; 17 | /// 扩展 weak 属性 18 | @property (nonatomic, weak) id dg_extWeakObj; 19 | /// 扩展 copy 属性 20 | @property (nonatomic, copy) id dg_extCopyObj; 21 | /// 扩展可变数组,懒加载初始化 22 | @property (nonatomic, strong) NSMutableArray *dg_extArray; 23 | /// 扩展可变字典,懒加载初始化 24 | @property (nonatomic, strong) NSMutableDictionary *dg_extDictionary; 25 | /// 扩展弱引用 value 的 hash table,懒加载初始化 26 | @property (nonatomic, strong) NSHashTable *dg_extHash; 27 | /// 扩展强引用 key,弱引用 value 的 map table,懒加载初始化 28 | @property (nonatomic, strong) NSMapTable *dg_extMap; 29 | 30 | @end 31 | 32 | @interface NSObject (Debugo_Runtime) 33 | 34 | + (void)dg_swizzleInstanceMethod:(SEL)originalSelector newSelector:(SEL)newSelector; 35 | 36 | + (void)dg_swizzleClassMethod:(SEL)originalSelector newSelector:(SEL)newSelector; 37 | 38 | @end 39 | 40 | @interface NSObject (Debugo_Make) 41 | 42 | + (instancetype)dg_make:(void (^)(id obj))block; 43 | 44 | - (id)dg_put:(void (^)(id obj))block; 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/ColorPlugin/DGColorPlugin.m: -------------------------------------------------------------------------------- 1 | // 2 | // DGColorPlugin.m 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/9/26. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import "DGColorPlugin.h" 10 | #import "DGCommon.h" 11 | #import "DGColorPluginViewController.h" 12 | 13 | @implementation DGColorPlugin 14 | 15 | + (NSString *)pluginName { 16 | return @"UIView背景色"; 17 | } 18 | 19 | + (UIImage *)pluginImage { 20 | return [DGBundle imageNamed:@"plugin_uiviewcolor"]; 21 | } 22 | 23 | + (UIImage *)pluginTabBarImage:(BOOL)isSelected { 24 | if (isSelected) { 25 | return [DGBundle imageNamed:@"tab_uiviewcolor_selected"]; 26 | } 27 | return [DGBundle imageNamed:@"tab_uiviewcolor_normal"]; 28 | } 29 | 30 | + (UIViewController *)pluginViewController { 31 | return [DGColorPluginViewController new]; 32 | } 33 | 34 | + (BOOL)pluginSwitch { 35 | UIViewController *vc = dg_topViewController(); 36 | if ([vc isViewLoaded] && vc.view.dg_renderType > 0) { 37 | return YES; 38 | } 39 | return NO; 40 | } 41 | 42 | + (void)setPluginSwitch:(BOOL)pluginSwitch { 43 | UIViewController *vc = dg_topViewController(); 44 | if (pluginSwitch) { 45 | vc.view.dg_renderType = DGRenderTypeLeaves; 46 | }else { 47 | vc.view.dg_renderType = DGRenderTypeNone; 48 | } 49 | } 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /Debugo/Classes/Common/UI/DGStaticSection.m: -------------------------------------------------------------------------------- 1 | // 2 | // DGStaticSection.m 3 | // StaticTableView 4 | // 5 | // Created by ripper on 2019/9/25. 6 | // Copyright © 2019 ripper. All rights reserved. 7 | // 8 | 9 | #import "DGStaticSection.h" 10 | 11 | @implementation DGStaticSection 12 | 13 | + (instancetype)section:(void (^)(DGStaticSection * _Nonnull))block { 14 | DGStaticSection *obj = [DGStaticSection new]; 15 | block(obj); 16 | return obj; 17 | } 18 | 19 | - (NSMutableArray *)rows { 20 | if (!_rows) { 21 | _rows = [NSMutableArray array]; 22 | } 23 | return _rows; 24 | } 25 | 26 | - (void)addRow:(DGStaticRow *)row; { 27 | [self.rows addObject:row]; 28 | } 29 | 30 | - (void)addRowWithBlock:(void (^)(DGStaticRow * _Nonnull))block { 31 | DGStaticRow *row = [DGStaticRow new]; 32 | block(row); 33 | [self.rows addObject:row]; 34 | } 35 | 36 | - (void)addRows:(NSArray *)rows { 37 | [self.rows addObjectsFromArray:rows]; 38 | } 39 | 40 | - (NSString *)headerIdentifier { 41 | if (!_headerIdentifier) { 42 | _headerIdentifier = [NSString stringWithFormat:@"header_%p", self]; 43 | } 44 | return _headerIdentifier; 45 | } 46 | 47 | - (NSString *)footerIdentifier { 48 | if (!_footerIdentifier) { 49 | _footerIdentifier = [NSString stringWithFormat:@"footer_%p", self]; 50 | } 51 | return _footerIdentifier; 52 | } 53 | 54 | @end 55 | -------------------------------------------------------------------------------- /Debugo/Classes/Common/Source/DGBuildInfo.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGBuildInfo.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/10/25. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface DGBuildInfo : NSObject 14 | 15 | /// 配置脚本的网址 16 | @property (nonatomic, copy) NSString *configURL; 17 | /// 脚本版本 18 | @property (nonatomic, copy) NSString *scriptVersion; 19 | /// plist 文件更新时间(build 时间) 20 | @property (nonatomic, copy) NSString *plistUpdateTimestamp; 21 | /// 编译配置 22 | @property (nonatomic, copy) NSString *buildConfiguration; 23 | /// 编译包的电脑 当前用户名 24 | @property (nonatomic, copy) NSString *computerUser; 25 | /// 编译的电脑的UUID 26 | @property (nonatomic, copy) NSString *computerUUID; 27 | /// 编译包的电脑 是否安装 git 28 | @property (nonatomic, assign) BOOL gitEnable; 29 | /// 当前 git 分支 30 | @property (nonatomic, copy) NSString *gitBranch; 31 | /// 最后一次提交的缩写 hash 32 | @property (nonatomic, copy) NSString *gitLastCommitAbbreviatedHash; 33 | /// 最后一次提交的用户 34 | @property (nonatomic, copy) NSString *gitLastCommitUser; 35 | /// 最后一次提交的时间 36 | @property (nonatomic, copy) NSString *gitLastCommitTimestamp; 37 | /// 是否拷贝了 Podfile.lock 文件 38 | @property (nonatomic, assign) BOOL cocoaPodsLockFileExist; 39 | /// Podfile.lock 文件名 40 | @property (nonatomic, copy) NSString *cocoaPodsLockFileName; 41 | 42 | + (instancetype)shared; 43 | 44 | @end 45 | 46 | NS_ASSUME_NONNULL_END 47 | -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Pods/FMDB/LICENSE.txt: -------------------------------------------------------------------------------- 1 | If you are using FMDB in your project, I'd love to hear about it. Let Gus know 2 | by sending an email to gus@flyingmeat.com. 3 | 4 | And if you happen to come across either Gus Mueller or Rob Ryan in a bar, you 5 | might consider purchasing a drink of their choosing if FMDB has been useful to 6 | you. 7 | 8 | Finally, and shortly, this is the MIT License. 9 | 10 | Copyright (c) 2008-2014 Flying Meat Inc. 11 | 12 | Permission is hereby granted, free of charge, to any person obtaining a copy 13 | of this software and associated documentation files (the "Software"), to deal 14 | in the Software without restriction, including without limitation the rights 15 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | copies of the Software, and to permit persons to whom the Software is 17 | furnished to do so, subject to the following conditions: 18 | 19 | The above copyright notice and this permission notice shall be included in 20 | all copies or substantial portions of the Software. 21 | 22 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 28 | THE SOFTWARE. -------------------------------------------------------------------------------- /docs/build-info.md: -------------------------------------------------------------------------------- 1 | # 获取 Build 信息 2 | 3 | 如果你想实现以下功能: 4 | 5 | * 获取安装包 build 时间 6 | * 获取 build 安装包的电脑 hostname、UUID 7 | * 获取当前代码的 git 分支以及最后一次 commit 信息 8 | * 获取工程依赖的 CocoaPods 库 9 | 10 | 那么你需要添加脚本到工程中,具体如下 11 | 12 | 1. 在 TARGETS 选中当前工程 13 | 2. 选中 Build Phases 14 | 3. 点击左上方 ✚ 号 15 | 4. 选中 New Run Script Phase 16 | 17 | ![](_media/build-info-1.png) 18 | 5. 建议将新建的 `Run Script` 更名为 `Debugo Build Info` 19 | 20 | ![](_media/build-info-2.png) 21 | 6. 展开这个选项,将 shell 脚本粘贴到输入框,保存即可 22 | 23 | ```bash 24 | # 直接拖拽引入或者 CocoaPods 没有使用 use_frameworks! 25 | buildInfoSh="${BUILT_PRODUCTS_DIR}/${EXECUTABLE_FOLDER_PATH}/Debugo.bundle/com.ripperhe.debugo.build.info.sh" 26 | # CocoaPods use_frameworks! 27 | buildInfoSh2="${BUILT_PRODUCTS_DIR}/${EXECUTABLE_FOLDER_PATH}/Frameworks/Debugo.framework/Debugo.bundle/com.ripperhe.debugo.build.info.sh" 28 | 29 | if [ -x "${buildInfoSh}" ]; then 30 | ${buildInfoSh} 31 | echo "com.ripperhe.debugo.build.info.sh path: ${buildInfoSh}" 32 | elif [ -x "${buildInfoSh2}" ]; then 33 | ${buildInfoSh2} 34 | echo "com.ripperhe.debugo.build.info.sh path: ${buildInfoSh2}" 35 | else 36 | echo "com.ripperhe.debugo.build.info.sh not found!!! " 37 | fi 38 | ``` 39 | 40 | ⚠️ 上面这段脚本的其实就是从 bundle 中获取实际起作用的脚本进行执行。因为是从 budle 中获取脚本进行执行,所以第一次 build 的时候获取不到脚本,从第二次开始正常,个人认为不影响操作,不过需要知道这个点。 41 | 42 | 如果使用脚本1的时候,build 信息中总是提示 `com.ripperhe.debugo.build.info.sh not found!!! `,可能是因为什么未知的原因没有找到脚本。 43 | 44 | [跳转到实际起作用的脚本文件链接 🚀](https://github.com/ripperhe/Debugo/blob/master/Debugo/Assets/Debugo.bundle/com.ripperhe.debugo.build.info.sh) 45 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/FilePlugin/DGDatabaseLeftTableViewCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // DGDatabaseLeftTableViewCell.m 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/1/9. 6 | // Copyright © 2019 ripper. All rights reserved. 7 | // 8 | 9 | #import "DGDatabaseLeftTableViewCell.h" 10 | 11 | @implementation DGDatabaseLeftTableViewCell 12 | 13 | - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { 14 | if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) { 15 | self.selectionStyle = UITableViewCellSelectionStyleNone; 16 | self.label = [[UILabel alloc] init]; 17 | self.label.textColor = [UIColor colorWithRed:51/255.0 green:51/255.0 blue:51/255.0 alpha:1]; 18 | self.label.font = [UIFont boldSystemFontOfSize:14]; 19 | self.label.textAlignment = NSTextAlignmentCenter; 20 | [self.contentView addSubview:self.label]; 21 | } 22 | return self; 23 | } 24 | 25 | - (void)layoutSubviews { 26 | [super layoutSubviews]; 27 | 28 | self.label.frame = self.contentView.bounds; 29 | } 30 | 31 | - (void)awakeFromNib { 32 | [super awakeFromNib]; 33 | // Initialization code 34 | } 35 | 36 | - (void)setSelected:(BOOL)selected animated:(BOOL)animated { 37 | [super setSelected:selected animated:animated]; 38 | 39 | // Configure the view for the selected state 40 | // self.contentView.backgroundColor = selected?[UIColor colorWithRed:0.96 green:0.89 blue:0.89 alpha:1.00]:UIColor.clearColor; 41 | } 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/FilePlugin/DGFile.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGFile.h 3 | // Debugo 4 | // 5 | // GitHub https://github.com/ripperhe/Debugo 6 | // Created by ripper on 2018/9/1. 7 | // Copyright © 2018年 ripper. All rights reserved. 8 | // 9 | 10 | #import 11 | #import 12 | 13 | typedef NS_ENUM(NSUInteger, DGFileType) { 14 | DGFileTypeDefault, 15 | DGFileTypeDirectory, 16 | DGFileTypeImage, 17 | DGFileTypeAudio, 18 | DGFileTypeVideo, 19 | DGFileTypePDF, 20 | DGFileTypeJSON, 21 | DGFileTypePLIST, 22 | DGFileTypeZIP, 23 | DGFileTypeDB 24 | }; 25 | 26 | NS_ASSUME_NONNULL_BEGIN 27 | 28 | @interface DGFile : NSObject 29 | 30 | @property (nonatomic, strong, readonly) NSURL *fileURL; 31 | @property (nonatomic, strong, readonly) NSString *filePath; 32 | @property (nonatomic, copy, readonly) NSString *fileName; 33 | @property (nonatomic, copy, nullable, readonly) NSString *fileExtension; 34 | @property (nonatomic, assign, readonly) DGFileType type; 35 | @property (nonatomic, assign, readonly) BOOL isDirectory; 36 | @property (nonatomic, copy) NSString *displayName; 37 | 38 | - (instancetype)initWithPath:(NSString *)path; 39 | - (instancetype)initWithURL:(NSURL *)URL; 40 | - (void)deleteWithErrorHandler:(void (NS_NOESCAPE^)(NSError * error))errorHandler; 41 | - (BOOL)isExist; 42 | - (NSDictionary *)fileAttributes; 43 | - (void)calculateSize:(void (^)(long long size))completion; 44 | - (nullable NSString *)simpleInfo; 45 | - (UIImage *)image; 46 | 47 | @end 48 | 49 | NS_ASSUME_NONNULL_END 50 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/FilePlugin/DGFilePlugin.m: -------------------------------------------------------------------------------- 1 | // 2 | // DGFilePlugin.m 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/5/31. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import "DGFilePlugin.h" 10 | #import "DGCommon.h" 11 | #import "DGFileViewController.h" 12 | 13 | @implementation DGFilePlugin 14 | 15 | + (NSString *)pluginName { 16 | return @"文件"; 17 | } 18 | 19 | + (UIImage *)pluginImage { 20 | return [DGBundle imageNamed:@"plugin_file"]; 21 | } 22 | 23 | + (UIImage *)pluginTabBarImage:(BOOL)isSelected { 24 | if (isSelected) { 25 | return [DGBundle imageNamed:@"tab_file_selected"]; 26 | } 27 | return [DGBundle imageNamed:@"tab_file_normal"]; 28 | } 29 | 30 | + (UIViewController *)pluginViewController { 31 | return [DGFileViewController new]; 32 | } 33 | 34 | #pragma mark - 35 | 36 | static DGFilePlugin *_instance; 37 | + (instancetype)shared { 38 | if (!_instance) { 39 | static dispatch_once_t onceToken; 40 | dispatch_once(&onceToken, ^{ 41 | _instance = [[self alloc] init]; 42 | }); 43 | } 44 | return _instance; 45 | } 46 | 47 | + (instancetype)allocWithZone:(struct _NSZone *)zone { 48 | static dispatch_once_t onceToken; 49 | dispatch_once(&onceToken, ^{ 50 | _instance = [super allocWithZone:zone]; 51 | }); 52 | return _instance; 53 | } 54 | 55 | - (DGFilePluginConfiguration *)configuration { 56 | if (!_configuration) { 57 | _configuration = [DGFilePluginConfiguration new]; 58 | } 59 | return _configuration; 60 | } 61 | 62 | @end 63 | -------------------------------------------------------------------------------- /Debugo/Classes/API/DGConfiguration.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGConfiguration.h 3 | // Debugo 4 | // 5 | // GitHub https://github.com/ripperhe/Debugo 6 | // Created by ripper on 2018/9/1. 7 | // Copyright © 2018年 ripper. All rights reserved. 8 | // 9 | 10 | 11 | #import 12 | #import "DGActionPlugin.h" 13 | #import "DGFilePlugin.h" 14 | #import "DGAppInfoPlugin.h" 15 | #import "DGAccountPlugin.h" 16 | #import "DGApplePlugin.h" 17 | #import "DGTouchPlugin.h" 18 | #import "DGColorPlugin.h" 19 | #import "DGPodPlugin.h" 20 | 21 | NS_ASSUME_NONNULL_BEGIN 22 | 23 | @interface DGConfiguration : NSObject 24 | 25 | /// 添加自定义工具,需继承自 DGPlugin 或遵守 DGPluginProtocol 协议 26 | - (void)addCustomPlugin:(Class)plugin; 27 | 28 | /// 将工具放到 tabBar 上;默认是 DGActionPlugin 29 | /// 目前支持 DGActionPlugin DGFilePlugin DGAppInfoPlugin DGAccountPlugin DGColorPlugin DGPodPlugin 30 | /// 以及实现了 pluginViewController 的自定义工具 31 | - (void)putPluginsToTabBar:(nullable NSArray> *)plugins; 32 | 33 | /// 自定义悬浮球的长按事件,可用于某些需要快捷操作的事情(点击事件是开启和关闭 Debug Window) 34 | - (void)setupBubbleLongPressAction:(void (^)(void))block; 35 | 36 | /// 配置指令 37 | - (void)setupActionPlugin:(void (^)(DGActionPluginConfiguration *actionConfiguration))block; 38 | 39 | /// 配置文件 40 | - (void)setupFilePlugin:(void (^)(DGFilePluginConfiguration *fileConfiguration))block; 41 | 42 | /// 配置快速登录 43 | - (void)setupAccountPlugin:(void (^)(DGAccountPluginConfiguration *accountConfiguration))block; 44 | 45 | /// 配置CocoaPods 46 | - (void)setupPodPlugin:(void (^)(DGPodPluginConfiguration *podConfiguration))block; 47 | 48 | @end 49 | 50 | NS_ASSUME_NONNULL_END 51 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/PodPlugin/DGPodModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // DGPodModel.m 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/10/24. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import "DGPodModel.h" 10 | 11 | @interface DGPodModel () 12 | { 13 | NSString *_realName; 14 | NSString *_realVersion; 15 | } 16 | 17 | @end 18 | 19 | @implementation DGPodModel 20 | 21 | - (NSString *)name { 22 | if (_realName.length) { 23 | return _realName; 24 | } 25 | DGPodModel *sub = self.subPods.sortedValues.firstObject; 26 | if (sub.name.length) { 27 | NSString *name = [sub.name stringByDeletingLastPathComponent]; 28 | if (name.length) { 29 | return name; 30 | } 31 | } 32 | return nil; 33 | } 34 | 35 | - (void)setName:(NSString *)name { 36 | _realName = name; 37 | if ([name containsString:@"/"]) { 38 | self.nameComponents = [name componentsSeparatedByString:@"/"]; 39 | }else { 40 | self.nameComponents = @[name]; 41 | } 42 | } 43 | 44 | - (NSString *)version { 45 | if (_realVersion.length) { 46 | return _realVersion; 47 | } 48 | DGPodModel *sub = self.subPods.sortedValues.firstObject; 49 | if (sub.version.length) { 50 | return sub.version; 51 | } 52 | return nil; 53 | } 54 | 55 | - (void)setVersion:(NSString *)version { 56 | _realVersion = version; 57 | } 58 | 59 | - (DGOrderedDictionary *)subPods { 60 | if (!_subPods) { 61 | _subPods = [DGOrderedDictionary dictionary]; 62 | } 63 | return _subPods; 64 | } 65 | 66 | @end 67 | -------------------------------------------------------------------------------- /Debugo/Classes/Common/UI/DGStaticSection.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGStaticSection.h 3 | // StaticTableView 4 | // 5 | // Created by ripper on 2019/9/25. 6 | // Copyright © 2019 ripper. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "DGStaticRow.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface DGStaticSection : NSObject 15 | 16 | /// 行 17 | @property (nonatomic, strong) NSMutableArray *rows; 18 | 19 | /// header 标识符,自动生成,防止其他 section 复用当前 section 的 header 20 | /// 一般情况下,每行会复用自己的 header;当遇到内存警告的时候,则会重新创建 21 | @property (nonatomic, copy) NSString *headerIdentifier; 22 | /// 创建 header 23 | @property (nonatomic, copy) UIView *(^createHeader)(NSInteger section, NSString *identifier); 24 | /// 即将显示 header 25 | @property (nonatomic, copy) void(^willDisplayHeader)(id header, NSInteger section); 26 | /// header 高度 27 | @property (nonatomic, assign) CGFloat headerHeight; 28 | 29 | /// footer 标识符,自动生成,防止其他 section 复用当前 section 的 footer 30 | /// 一般情况下,每行会复用自己的 footer;当遇到内存警告的时候,则会重新创建 31 | @property (nonatomic, copy) NSString *footerIdentifier; 32 | /// 创建 footer 33 | @property (nonatomic, copy) UIView *(^createFooter)(NSInteger section, NSString *identifier); 34 | /// 即将显示 footer 35 | @property (nonatomic, copy) void(^willDispalyFooter)(id footer, NSInteger section); 36 | /// footer 高度 37 | @property (nonatomic, assign) CGFloat footerHeight; 38 | 39 | + (instancetype)section:(void (^)(DGStaticSection *section))block; 40 | 41 | - (void)addRow:(DGStaticRow *)row; 42 | - (void)addRowWithBlock:(void (^)(DGStaticRow *row))block; 43 | - (void)addRows:(NSArray *)rows; 44 | 45 | @end 46 | 47 | NS_ASSUME_NONNULL_END 48 | -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | Debugo 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xccheckout 23 | *.xcscmblueprint 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | *.ipa 28 | *.dSYM.zip 29 | *.dSYM 30 | 31 | # CocoaPods 32 | # 33 | # We recommend against adding the Pods directory to your .gitignore. However 34 | # you should judge for yourself, the pros and cons are mentioned at: 35 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 36 | # 37 | # Pods/ 38 | # 39 | # Add this line if you want to avoid checking in source code from the Xcode workspace 40 | # *.xcworkspace 41 | 42 | # Carthage 43 | # 44 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 45 | # Carthage/Checkouts 46 | 47 | Carthage/Build 48 | 49 | # fastlane 50 | # 51 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 52 | # screenshots whenever they are needed. 53 | # For more information about the recommended setup visit: 54 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 55 | 56 | fastlane/report.xml 57 | fastlane/Preview.html 58 | fastlane/screenshots/**/*.png 59 | fastlane/test_output 60 | 61 | # Code Injection 62 | # 63 | # After new code Injection tools there's a generated folder /iOSInjectionProject 64 | # https://github.com/johnno1962/injectionforxcode 65 | 66 | iOSInjectionProject/ 67 | -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Pods/Target Support Files/Pods-Debugo-Example-ObjectiveC/Pods-Debugo-Example-ObjectiveC-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## FMDB 5 | 6 | If you are using FMDB in your project, I'd love to hear about it. Let Gus know 7 | by sending an email to gus@flyingmeat.com. 8 | 9 | And if you happen to come across either Gus Mueller or Rob Ryan in a bar, you 10 | might consider purchasing a drink of their choosing if FMDB has been useful to 11 | you. 12 | 13 | Finally, and shortly, this is the MIT License. 14 | 15 | Copyright (c) 2008-2014 Flying Meat Inc. 16 | 17 | Permission is hereby granted, free of charge, to any person obtaining a copy 18 | of this software and associated documentation files (the "Software"), to deal 19 | in the Software without restriction, including without limitation the rights 20 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 21 | copies of the Software, and to permit persons to whom the Software is 22 | furnished to do so, subject to the following conditions: 23 | 24 | The above copyright notice and this permission notice shall be included in 25 | all copies or substantial portions of the Software. 26 | 27 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 28 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 29 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 30 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 31 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 32 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 33 | THE SOFTWARE. 34 | Generated by CocoaPods - https://cocoapods.org 35 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/FilePlugin/DGDatabaseContentParser.m: -------------------------------------------------------------------------------- 1 | // 2 | // DGDatabaseContentParser.m 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/1/14. 6 | // Copyright © 2019 ripper. All rights reserved. 7 | // 8 | 9 | #import "DGDatabaseContentParser.h" 10 | 11 | @implementation DGDatabaseContentParser 12 | 13 | + (BOOL)checkString:(NSString *)string pattern:(NSString *)pattern { 14 | NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", pattern]; 15 | return [predicate evaluateWithObject:string]; 16 | } 17 | 18 | + (NSString *)parseContentForTimestamp:(NSString *)content { 19 | if (!content.length) return nil; 20 | 21 | NSTimeInterval time = 0; 22 | 23 | NSString *pattern10Int = @"^[0-9]{10}$"; 24 | NSString *pattern10Double = @"^[0-9]{10}.[0-9]+$"; 25 | NSString *pattern13Int = @"^[0-9]{13}$"; 26 | NSString *pattern13Double = @"^[0-9]{13}.[0-9]+$"; 27 | 28 | if ([self checkString:content pattern:pattern10Int] || [self checkString:content pattern:pattern10Double]) { 29 | time = [content doubleValue]; 30 | }else if ([self checkString:content pattern:pattern13Int] || [self checkString:content pattern:pattern13Double]) { 31 | time = content.doubleValue / 1000; 32 | }else { 33 | return nil; 34 | } 35 | 36 | NSDate *date = [NSDate dateWithTimeIntervalSince1970:time]; 37 | NSDateFormatter *dateFormatter = [NSDateFormatter new]; 38 | dateFormatter.dateFormat = @"yyyy-MM-dd HH:mm:ss.SSS"; 39 | dateFormatter.timeZone = [NSTimeZone localTimeZone]; 40 | dateFormatter.timeZone = [NSTimeZone timeZoneWithName:@"Asia/Shanghai"]; 41 | dateFormatter.locale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]; 42 | NSString *dateString = [dateFormatter stringFromDate:date]; 43 | return dateString; 44 | } 45 | 46 | 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/FilePlugin/DGDatabaseGridView.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGDatabaseGridView.h 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/1/9. 6 | // Copyright © 2019 ripper. All rights reserved. 7 | // 8 | 9 | #import 10 | @class DGDatabaseGridView; 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | typedef struct _DGGridIndex { 15 | NSInteger column; 16 | NSInteger row; 17 | } DGGridIndex; 18 | 19 | DGGridIndex DGGridIndexMake(NSInteger column, NSInteger row); 20 | 21 | @protocol DGDatabaseGridViewDelegate 22 | 23 | @optional 24 | - (void)gridView:(DGDatabaseGridView *)gridView didClickContentButton:(UIButton *)button gridIndex:(DGGridIndex)gridIndex; 25 | - (void)gridView:(DGDatabaseGridView *)gridView didSelectedRow:(NSInteger)row; 26 | - (void)gridView:(DGDatabaseGridView *)gridView didDeselectedRow:(NSInteger)row; 27 | 28 | @end 29 | 30 | @protocol DGDatabaseGridViewDataSource 31 | 32 | @required 33 | - (NSInteger)numberOfColumnsInGridView:(DGDatabaseGridView *)gridView; 34 | - (NSInteger)numberOfRowsInGridView:(DGDatabaseGridView *)gridView; 35 | - (NSString *)columnNameInColumn:(NSInteger)column; 36 | - (NSString *)rowNameInRow:(NSInteger)row; 37 | - (NSArray *)contentsAtRow:(NSInteger)row; 38 | @optional 39 | - (NSString *)gridView:(DGDatabaseGridView *)gridView contentAtGridIndex:(DGGridIndex)gridIndex; 40 | - (CGFloat)gridView:(DGDatabaseGridView *)gridView widthForContentCellInColumn:(NSInteger)column; 41 | - (CGFloat)gridView:(DGDatabaseGridView *)gridView heightForContentCellInRow:(NSInteger)row; 42 | 43 | @end 44 | 45 | 46 | @interface DGDatabaseGridView : UIView 47 | 48 | @property (nonatomic, weak) id delegate; 49 | @property (nonatomic, weak) id dataSource; 50 | 51 | - (void)reloadData; 52 | 53 | @end 54 | 55 | NS_ASSUME_NONNULL_END 56 | -------------------------------------------------------------------------------- /Debugo/Classes/Common/Category/UIControl+Debugo.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIControl+Debugo.m 3 | // StaticTableView 4 | // 5 | // Created by ripper on 2019/9/25. 6 | // Copyright © 2019 ripper. All rights reserved. 7 | // 8 | 9 | #import "UIControl+Debugo.h" 10 | #import 11 | 12 | @implementation DGReceiver 13 | 14 | - (void)receiveAction:(id)sender { 15 | if (self.handler) { 16 | self.handler(sender); 17 | } 18 | } 19 | 20 | @end 21 | 22 | @implementation UIControl (DGStaticProvider) 23 | 24 | static const void * kAssociatedObjectKey_receivers = &kAssociatedObjectKey_receivers; 25 | - (NSMutableArray *)dg_receivers { 26 | NSMutableArray *array = objc_getAssociatedObject(self, kAssociatedObjectKey_receivers); 27 | if (!array) { 28 | array = [NSMutableArray array]; 29 | objc_setAssociatedObject(self, kAssociatedObjectKey_receivers, array, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 30 | } 31 | return array; 32 | } 33 | 34 | - (DGReceiver *)dg_addReceiverForControlEvents:(UIControlEvents)controlEvents handler:(void (^)(id _Nonnull))handler { 35 | DGReceiver *receiver = [DGReceiver new]; 36 | receiver.handler = handler; 37 | receiver.controlEvents = controlEvents; 38 | [self addTarget:receiver action:@selector(receiveAction:) forControlEvents:controlEvents]; 39 | [self.dg_receivers addObject:receiver]; 40 | return receiver; 41 | } 42 | 43 | - (void)dg_removeReceiver:(DGReceiver *)receiver { 44 | if ([self.dg_receivers containsObject:receiver]) { 45 | [self removeTarget:receiver action:@selector(receiveAction:) forControlEvents:receiver.controlEvents]; 46 | [self.dg_receivers removeObject:receiver]; 47 | } 48 | } 49 | 50 | - (void)dg_removeAllReceivers { 51 | [self.dg_receivers enumerateObjectsUsingBlock:^(DGReceiver * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 52 | [self dg_removeReceiver:obj]; 53 | }]; 54 | } 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/TouchPlugin/DGTouchPluginViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // DGTouchPluginViewController.m 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/9/12. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import "DGTouchPluginViewController.h" 10 | #import "DGCommon.h" 11 | #import "DGTouchPlugin.h" 12 | 13 | @implementation DGTouchPluginViewController 14 | 15 | - (instancetype)initWithStyle:(UITableViewStyle)style { 16 | if (self = [super initWithStyle:UITableViewStyleGrouped]) { 17 | } 18 | return self; 19 | } 20 | 21 | - (void)viewDidLoad { 22 | [super viewDidLoad]; 23 | 24 | self.title = [DGTouchPlugin pluginName]; 25 | 26 | DGStaticProvider *provider = [DGStaticProvider new]; 27 | [provider addSectionWithBlock:^(DGStaticSection * _Nonnull section) { 28 | [section addRowWithBlock:^(DGStaticRow * _Nonnull row) { 29 | [row setCreateCell:^UITableViewCell * _Nonnull(NSIndexPath * _Nonnull indexPath, NSString * _Nonnull identifier) { 30 | UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier]; 31 | cell.textLabel.text = @"是否开启触摸监听"; 32 | UISwitch *switchView = [UISwitch new]; 33 | [switchView setOn:[DGTouchPlugin pluginSwitch]]; 34 | [switchView dg_addReceiverForControlEvents:UIControlEventValueChanged handler:^(UISwitch * _Nonnull sender) { 35 | [DGTouchPlugin setPluginSwitch:sender.isOn]; 36 | }]; 37 | cell.accessoryView = switchView; 38 | return cell; 39 | }]; 40 | [row setHeight:60]; 41 | }]; 42 | [section setHeaderHeight:20]; 43 | }]; 44 | self.tableView.allowsSelection = NO; 45 | self.tableView.bounces = NO; 46 | [self.tableView setDg_staticProvider:provider]; 47 | [self.tableView reloadData]; 48 | } 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/CustomPlugin/CustomPlugin2ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // CustomPlugin2ViewController.m 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/9/15. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import "CustomPlugin2ViewController.h" 10 | #import "CustomPlugin2.h" 11 | #import "DGCommon.h" 12 | 13 | @implementation CustomPlugin2ViewController 14 | 15 | - (instancetype)initWithStyle:(UITableViewStyle)style { 16 | if (self = [super initWithStyle:UITableViewStyleGrouped]) { 17 | } 18 | return self; 19 | } 20 | 21 | - (void)viewDidLoad { 22 | [super viewDidLoad]; 23 | 24 | self.title = [CustomPlugin2 pluginName]; 25 | 26 | DGStaticProvider *provider = [DGStaticProvider new]; 27 | [provider addSectionWithBlock:^(DGStaticSection * _Nonnull section) { 28 | [section addRowWithBlock:^(DGStaticRow * _Nonnull row) { 29 | [row setCreateCell:^UITableViewCell * _Nonnull(NSIndexPath * _Nonnull indexPath, NSString * _Nonnull identifier) { 30 | UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier]; 31 | cell.textLabel.text = @"是否开启自定义工具2"; 32 | UISwitch *switchView = [UISwitch new]; 33 | [switchView setOn:[CustomPlugin2 pluginSwitch]]; 34 | [switchView dg_addReceiverForControlEvents:UIControlEventValueChanged handler:^(UISwitch * _Nonnull sender) { 35 | [CustomPlugin2 setPluginSwitch:sender.isOn]; 36 | }]; 37 | cell.accessoryView = switchView; 38 | return cell; 39 | }]; 40 | [row setHeight:60]; 41 | }]; 42 | [section setHeaderHeight:20]; 43 | }]; 44 | self.tableView.allowsSelection = NO; 45 | self.tableView.bounces = NO; 46 | [self.tableView setDg_staticProvider:provider]; 47 | [self.tableView reloadData]; 48 | } 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/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 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /Debugo/Classes/API/DGConfiguration.m: -------------------------------------------------------------------------------- 1 | // 2 | // DGConfiguration.m 3 | // Debugo 4 | // 5 | // GitHub https://github.com/ripperhe/Debugo 6 | // Created by ripper on 2018/9/1. 7 | // Copyright © 2018年 ripper. All rights reserved. 8 | // 9 | 10 | 11 | #import "DGConfiguration.h" 12 | #import "DGEntrance.h" 13 | #import "DGPluginManager.h" 14 | 15 | @implementation DGConfiguration 16 | 17 | - (void)addCustomPlugin:(Class)plugin { 18 | [DGPluginManager.shared addCustomPlugin:plugin]; 19 | } 20 | 21 | - (void)putPluginsToTabBar:(NSArray> *)plugins { 22 | [DGPluginManager.shared putPluginsToTabBar:plugins]; 23 | } 24 | 25 | - (void)setupBubbleLongPressAction:(void (^)(void))block { 26 | if (block) { 27 | DGEntrance.shared.bubbleLongPressBlock = block; 28 | } 29 | } 30 | 31 | - (void)setupActionPlugin:(void (^)(DGActionPluginConfiguration * _Nonnull))block { 32 | DGActionPluginConfiguration *configuration = [DGActionPluginConfiguration new]; 33 | if (block) { 34 | block(configuration); 35 | } 36 | DGActionPlugin.shared.configuration = configuration; 37 | } 38 | 39 | - (void)setupFilePlugin:(void (^)(DGFilePluginConfiguration * _Nonnull))block { 40 | DGFilePluginConfiguration *configuration = [DGFilePluginConfiguration new]; 41 | if (block) { 42 | block(configuration); 43 | } 44 | DGFilePlugin.shared.configuration = configuration; 45 | } 46 | 47 | - (void)setupAccountPlugin:(void (^)(DGAccountPluginConfiguration * _Nonnull))block { 48 | DGAccountPluginConfiguration *configuration = [DGAccountPluginConfiguration new]; 49 | if (block) { 50 | block(configuration); 51 | } 52 | DGAccountPlugin.shared.configuration = configuration; 53 | } 54 | 55 | - (void)setupPodPlugin:(void (^)(DGPodPluginConfiguration * _Nonnull))block { 56 | DGPodPluginConfiguration *configuration = [DGPodPluginConfiguration new]; 57 | if (block) { 58 | block(configuration); 59 | } 60 | DGPodPlugin.shared.configuration = configuration; 61 | } 62 | 63 | @end 64 | -------------------------------------------------------------------------------- /Debugo/Classes/Common/Category/NSFileManager+Debugo.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSFileManager+Debugo.m 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/5/10. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import "NSFileManager+Debugo.h" 10 | #import "DGTool.h" 11 | 12 | @implementation NSFileManager (Debugo) 13 | 14 | - (long long)dg_fileSizeAtPath:(NSString *)path { 15 | if (![self fileExistsAtPath:path]) return 0; 16 | return [[self attributesOfItemAtPath:path error:nil] fileSize]; 17 | } 18 | 19 | - (long long)dg_folderSizeAtPath:(NSString *)path { 20 | long long folderSize = 0; 21 | @try { 22 | BOOL isDirectory = NO; 23 | if (![self fileExistsAtPath:path isDirectory:&isDirectory]) return 0; 24 | if (!isDirectory) return [self dg_fileSizeAtPath:path]; 25 | NSArray *items = [self contentsOfDirectoryAtPath:path error:nil]; 26 | for (int i = 0; i < items.count; i++) { 27 | BOOL subIsDir; 28 | NSString *fileAbsolutePath = [path stringByAppendingPathComponent:items[i]]; 29 | [self fileExistsAtPath:fileAbsolutePath isDirectory:&subIsDir]; 30 | if (subIsDir == YES) { 31 | // 文件夹就递归计算 32 | folderSize += [self dg_folderSizeAtPath:fileAbsolutePath]; 33 | } else { 34 | // 文件直接计算 35 | folderSize += [self dg_fileSizeAtPath:fileAbsolutePath]; 36 | } 37 | } 38 | } @catch (NSException *exception) { 39 | NSLog(@"NSFileManager dg_folderSizeAtPath 获取文件夹大小异常: %@", exception); 40 | } @finally { 41 | return folderSize; 42 | } 43 | } 44 | 45 | - (void)dg_asyncCalculateFolderSizeAtPath:(NSString *)path completion:(void (^)(long long size))completion { 46 | dg_weakify(self) 47 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 48 | dg_strongify(self) 49 | long long size = [self dg_folderSizeAtPath:path]; 50 | dispatch_async(dispatch_get_main_queue(), ^{ 51 | if (completion) completion(size); 52 | }); 53 | }); 54 | } 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/FilePlugin/DGPreviewManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // DGPreviewManager.m 3 | // Debugo 4 | // 5 | // GitHub https://github.com/ripperhe/Debugo 6 | // Created by ripper on 2018/9/1. 7 | // Copyright © 2018年 ripper. All rights reserved. 8 | // 9 | 10 | #import "DGPreviewManager.h" 11 | #import "DGFolderPreviewViewController.h" 12 | #import "DGWebviewPreviewViewContoller.h" 13 | #import "DGDefaultPreviewViewController.h" 14 | #import "DGDatabasePreviewViewController.h" 15 | 16 | @implementation DGPreviewManager 17 | 18 | + (UIViewController *)previewViewControllerForFile:(DGFile *)file configuration:(DGFilePreviewConfiguration *)configuration { 19 | switch (file.type) { 20 | case DGFileTypeDirectory: { 21 | DGFolderPreviewViewController *fileListViewController = [[DGFolderPreviewViewController alloc] initWithFile:file configuration:configuration]; 22 | return fileListViewController; 23 | } 24 | break; 25 | case DGFileTypePLIST: 26 | case DGFileTypeJSON: { 27 | DGWebviewPreviewViewContoller *webviewPreviewViewContoller = [DGWebviewPreviewViewContoller new]; 28 | webviewPreviewViewContoller.file = file; 29 | return webviewPreviewViewContoller; 30 | } 31 | break; 32 | case DGFileTypeDB: { 33 | DGDatabasePreviewViewController *databasePreviewViewController = [DGDatabasePreviewViewController new]; 34 | databasePreviewViewController.file = file; 35 | id config = configuration.databaseFilePreviewConfigurationBlock?configuration.databaseFilePreviewConfigurationBlock(file):nil; 36 | databasePreviewViewController.previewConfiguration = config; 37 | return databasePreviewViewController; 38 | } 39 | break; 40 | default: { 41 | DGDefaultPreviewViewController *previewTransitionViewController = [DGDefaultPreviewViewController new]; 42 | previewTransitionViewController.file = file; 43 | return previewTransitionViewController; 44 | } 45 | break; 46 | } 47 | } 48 | 49 | @end 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /Debugo/Classes/Common/UI/DGWindow.m: -------------------------------------------------------------------------------- 1 | // 2 | // DGWindow.m 3 | // Debugo 4 | // 5 | // GitHub https://github.com/ripperhe/Debugo 6 | // Created by ripper on 2018/9/1. 7 | // Copyright © 2018年 ripper. All rights reserved. 8 | // 9 | 10 | 11 | #import "DGWindow.h" 12 | #import "DebugoEnable.h" 13 | #import "DGTool.h" 14 | 15 | #define BoolString(boolValue) (boolValue?@"YES":@"NO") 16 | 17 | @implementation DGWindow 18 | 19 | - (instancetype)initWithFrame:(CGRect)frame { 20 | if (self = [super initWithFrame:frame]) { 21 | if (@available(iOS 13.0, *)) { 22 | // iOS13不设置无法显示 23 | self.windowScene = dg_mainWindowScene(); 24 | 25 | // 关闭深色模式 26 | self.overrideUserInterfaceStyle = UIUserInterfaceStyleLight; 27 | } 28 | 29 | // 防止旋转时四周有黑边 30 | self.clipsToBounds = YES; 31 | } 32 | return self; 33 | } 34 | 35 | - (void)destroy { 36 | self.hidden = YES; 37 | if (self.rootViewController.presentedViewController) { 38 | [self.rootViewController.presentedViewController dismissViewControllerAnimated:NO completion:nil]; 39 | } 40 | self.rootViewController = nil; 41 | } 42 | 43 | - (NSString *)description { 44 | NSString *description = [super description]; 45 | NSString *newDescription = [NSString stringWithFormat:@"%@; name = %@; level = %.0f; hidden = %@; isKey = %@>", 46 | [description substringToIndex:description.length - 1], 47 | self.name, 48 | self.windowLevel, 49 | BoolString(self.isHidden), 50 | BoolString(self.isKeyWindow)]; 51 | return newDescription; 52 | } 53 | 54 | #pragma mark - private api 55 | #if DebugoCanBeEnabled 56 | // Prevent influence status bar 57 | - (bool)_canAffectStatusBarAppearance { 58 | return self.dg_canAffectStatusBarAppearance; 59 | } 60 | 61 | // Prevent becoming keywindow 62 | - (bool)_canBecomeKeyWindow { 63 | return self.dg_canBecomeKeyWindow; 64 | } 65 | 66 | // Prevent the system add self to [UIApplication sharedApplication].windows 67 | - (bool)isInternalWindow { 68 | return self.dg_isInternalWindow; 69 | } 70 | #endif 71 | 72 | @end 73 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/TouchPlugin/DGTouchPlugin.m: -------------------------------------------------------------------------------- 1 | // 2 | // DGTouchPlugin.m 3 | // Debugo 4 | // 5 | // GitHub https://github.com/ripperhe/Debugo 6 | // Created by ripper on 2018/9/1. 7 | // Copyright © 2018年 ripper. All rights reserved. 8 | // 9 | 10 | 11 | #import "DGTouchPlugin.h" 12 | #import "DebugoEnable.h" 13 | #import "DGCommon.h" 14 | #import "DGTouchWindow.h" 15 | #import "DGTouchPluginViewController.h" 16 | 17 | static BOOL _showTouch = NO; 18 | static DGTouchWindow *_touchWindow = nil; 19 | 20 | @implementation DGTouchPlugin 21 | 22 | + (NSString *)pluginName { 23 | return @"触摸监听"; 24 | } 25 | 26 | + (UIImage *)pluginImage { 27 | return [DGBundle imageNamed:@"plugin_touch"]; 28 | } 29 | 30 | + (UIImage *)pluginTabBarImage:(BOOL)isSelected { 31 | if (isSelected) { 32 | return [DGBundle imageNamed:@"tab_touch_selected"]; 33 | } 34 | return [DGBundle imageNamed:@"tab_touch_normal"]; 35 | } 36 | 37 | + (UIViewController *)pluginViewController { 38 | return [DGTouchPluginViewController new]; 39 | } 40 | 41 | + (BOOL)pluginSwitch { 42 | return _showTouch; 43 | } 44 | 45 | + (void)setPluginSwitch:(BOOL)pluginSwitch { 46 | _showTouch = pluginSwitch; 47 | if (pluginSwitch) { 48 | if (!_touchWindow) { 49 | _touchWindow = [[DGTouchWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 50 | } 51 | _touchWindow.hidden = NO; 52 | }else { 53 | [_touchWindow destroy]; 54 | _touchWindow = nil; 55 | } 56 | } 57 | 58 | #pragma mark - 59 | 60 | + (void)handleToucheEvent:(UIEvent *)event { 61 | [_touchWindow displayEvent:event]; 62 | } 63 | 64 | @end 65 | 66 | @interface UIApplication (DGTouchPlugin) 67 | 68 | @end 69 | 70 | @implementation UIApplication (DGTouchPlugin) 71 | 72 | #if DebugoCanBeEnabled 73 | + (void)load { 74 | static dispatch_once_t onceToken; 75 | dispatch_once(&onceToken, ^{ 76 | [UIApplication dg_swizzleInstanceMethod:@selector(sendEvent:) newSelector:@selector(dg_sendEvent:)]; 77 | }); 78 | } 79 | 80 | - (void)dg_sendEvent:(UIEvent *)event { 81 | if (_showTouch && event.type == UIEventTypeTouches) { 82 | [DGTouchPlugin handleToucheEvent:event]; 83 | } 84 | [self dg_sendEvent:event]; 85 | } 86 | #endif 87 | 88 | @end 89 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/ActionPlugin/DGActionSubViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // DGActionSubViewController.m 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/1/22. 6 | // Copyright © 2019 ripper. All rights reserved. 7 | // 8 | 9 | #import "DGActionSubViewController.h" 10 | #import "DGEntrance.h" 11 | #import "DGCommon.h" 12 | 13 | @interface DGActionSubViewController () 14 | 15 | @property (nonatomic, strong) NSArray *actions; 16 | 17 | @end 18 | 19 | @implementation DGActionSubViewController 20 | 21 | - (instancetype)initWithActions:(NSArray *)actions { 22 | if (self = [super initWithStyle:UITableViewStyleGrouped]) { 23 | self.actions = actions.copy; 24 | } 25 | return self; 26 | } 27 | 28 | - (void)viewDidLoad { 29 | [super viewDidLoad]; 30 | 31 | } 32 | 33 | #pragma mark - Table view data source 34 | 35 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 36 | return 1; 37 | } 38 | 39 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 40 | return self.actions.count; 41 | } 42 | 43 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 44 | static NSString *kDGCellID = @"cell"; 45 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kDGCellID]; 46 | if (!cell) { 47 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:kDGCellID]; 48 | cell.detailTextLabel.textColor = kDGHighlightColor; 49 | } 50 | return cell; 51 | } 52 | 53 | - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { 54 | DGAction *action = [self.actions objectAtIndex:indexPath.row]; 55 | cell.textLabel.text = action.title; 56 | } 57 | 58 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 59 | kDGImpactFeedback 60 | [tableView deselectRowAtIndexPath:indexPath animated:YES]; 61 | DGAction *action = [self.actions objectAtIndex:indexPath.row]; 62 | if (action.autoClose) { 63 | [DGEntrance.shared closeDebugWindow]; 64 | } 65 | action.viewController = self; 66 | action.handler(action); 67 | } 68 | 69 | @end 70 | -------------------------------------------------------------------------------- /Debugo/Classes/API/Debugo.h: -------------------------------------------------------------------------------- 1 | // 2 | // Debugo.h 3 | // Debugo 4 | // 5 | // GitHub https://github.com/ripperhe/Debugo 6 | // Created by ripper on 2018/9/1. 7 | // Copyright © 2018年 ripper. All rights reserved. 8 | // 9 | 10 | #import 11 | #import "DebugoEnable.h" 12 | #import "DGConfiguration.h" 13 | #import "DGTool.h" 14 | 15 | NS_ASSUME_NONNULL_BEGIN 16 | 17 | @interface Debugo : NSObject 18 | 19 | /// 框架版本 20 | + (NSString *)version; 21 | 22 | /// 框架是否可以启用,目前默认为仅在 DEBUG 模式可以启用 23 | + (BOOL)canBeEnabled; 24 | 25 | /// ☄️ 启动框架 可在 configuration block 中配置参数 26 | + (void)fireWithConfiguration:(nullable void (^)(DGConfiguration *configuration))block; 27 | 28 | /// 关闭 Debug Window 29 | + (void)closeDebugWindow; 30 | 31 | /// 指令:添加匿名指令,触发后自动关闭 Debug Window 32 | + (void)addActionWithTitle:(NSString *)title handler:(DGActionHandlerBlock)handler; 33 | 34 | /// 指令:添加匿名指令,通过 autoClose 控制触发后是否自动关闭 Debug Window 35 | + (void)addActionWithTitle:(NSString *)title handler:(DGActionHandlerBlock)handler autoClose:(BOOL)autoClose; 36 | 37 | /// 指令:为某个用户添加指令,触发后自动关闭 Debug Window 38 | + (void)addActionForUser:(nullable NSString *)user title:(NSString *)title handler:(DGActionHandlerBlock)handler; 39 | 40 | /// 指令:为某个用户添加指令,通过 autoClose 控制触发后是否自动关闭 Debug Window 41 | + (void)addActionForUser:(nullable NSString *)user title:(NSString *)title handler:(DGActionHandlerBlock)handler autoClose:(BOOL)autoClose; 42 | 43 | /// 快速登录:缓存账号 44 | + (void)accountPluginAddAccount:(DGAccount *)account; 45 | 46 | @end 47 | 48 | ///------------------------------------------------ 49 | /// ⚠️ 以下为一些用于调试的实用方法,请勿用于正式业务代码中 50 | ///------------------------------------------------ 51 | 52 | @interface Debugo (Additional) 53 | 54 | /// 仅在某个用户的电脑编译的包中立即执行某些代码(canBeEnabled 为 NO 时,则统统不执行)`$ whoami` 55 | + (void)executeCodeForUser:(NSString *)user handler:(void (NS_NOESCAPE ^)(void))handler; 56 | 57 | /// 获取主 window 的顶部控制器 58 | + (nullable UIViewController *)topViewController; 59 | 60 | /// 获取某个 window 顶部的 viewController 61 | + (nullable UIViewController *)topViewControllerForWindow:(nullable UIWindow *)window; 62 | 63 | /// 获取可见的键盘 window 64 | + (nullable UIWindow *)keyboardWindow; 65 | 66 | /// 获取所有 window, 包括系统内部的 window, 例如状态栏... 67 | + (nullable NSArray *)getAllWindows; 68 | 69 | @end 70 | 71 | 72 | NS_ASSUME_NONNULL_END 73 | -------------------------------------------------------------------------------- /Debugo/Classes/Common/UI/DGShareBarButtonItem.m: -------------------------------------------------------------------------------- 1 | // 2 | // DGShareBarButtonItem.m 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/3/20. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import "DGShareBarButtonItem.h" 10 | #import "DGCommon.h" 11 | 12 | @implementation DGShareBarButtonItem 13 | 14 | - (instancetype)initWithViewController:(UIViewController *)viewController shareFilePathsWhenClickedBlock:(NSArray * _Nonnull (^)(DGShareBarButtonItem * _Nonnull))shareFilePathsWhenClickedBlock { 15 | self = [super initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self action:@selector(shareFile:)]; 16 | if (self) { 17 | self.viewController = viewController; 18 | self.shareFilePathsWhenClickedBlock = shareFilePathsWhenClickedBlock; 19 | } 20 | return self; 21 | } 22 | 23 | #pragma mark - share 24 | - (void)shareFile:(UIBarButtonItem *)sender { 25 | if (!self.viewController) return; 26 | if (!self.shareFilePathsWhenClickedBlock) return; 27 | 28 | UIViewController *viewController = self.viewController; 29 | NSArray *paths = self.shareFilePathsWhenClickedBlock(self); 30 | if (!paths.count) return; 31 | NSMutableArray *urls = [NSMutableArray arrayWithCapacity:paths.count]; 32 | [paths enumerateObjectsUsingBlock:^(NSString * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 33 | [urls addObject:[NSURL fileURLWithPath:obj]]; 34 | }]; 35 | 36 | // TODO: 微信和QQ分享时页面卡死的处理 37 | UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:urls applicationActivities:nil]; 38 | if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad 39 | && [activityViewController respondsToSelector:@selector(popoverPresentationController)]) { 40 | activityViewController.popoverPresentationController.barButtonItem = sender; 41 | } 42 | [activityViewController setCompletionWithItemsHandler:^(UIActivityType _Nullable activityType, BOOL completed, NSArray * _Nullable returnedItems, NSError * _Nullable activityError) { 43 | DGLog(@"%@", activityError); 44 | }]; 45 | [viewController presentViewController:activityViewController animated:YES completion:nil]; 46 | } 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /Debugo/Classes/Common/Source/DGCache.m: -------------------------------------------------------------------------------- 1 | // 2 | // DGCache.m 3 | // Debugo 4 | // 5 | // GitHub https://github.com/ripperhe/Debugo 6 | // Created by ripper on 2018/9/1. 7 | // Copyright © 2018年 ripper. All rights reserved. 8 | // 9 | 10 | #import "DGCache.h" 11 | #import "DGEntrance.h" 12 | #import "DGAccountPlugin.h" 13 | 14 | @interface DGCache() 15 | 16 | @property (nonatomic, strong) DGPlister *accountPlister; 17 | 18 | @end 19 | 20 | @implementation DGCache 21 | 22 | static DGCache *_instance; 23 | + (instancetype)shared { 24 | if (!_instance) { 25 | static dispatch_once_t onceToken; 26 | dispatch_once(&onceToken, ^{ 27 | _instance = [[self alloc] init]; 28 | }); 29 | } 30 | return _instance; 31 | } 32 | 33 | + (instancetype)allocWithZone:(struct _NSZone *)zone { 34 | static dispatch_once_t onceToken; 35 | dispatch_once(&onceToken, ^{ 36 | _instance = [super allocWithZone:zone]; 37 | }); 38 | return _instance; 39 | } 40 | 41 | #pragma mark - getter 42 | - (NSString *)debugoPath { 43 | if (!_debugoPath) { 44 | NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject]; 45 | NSString *debugoPath = [cachePath stringByAppendingPathComponent:@"com.ripperhe.debugo"]; 46 | NSError *error = nil; 47 | [[NSFileManager defaultManager] createDirectoryAtPath:debugoPath withIntermediateDirectories:YES attributes:nil error:&error]; 48 | if (error) { 49 | NSAssert(0, @"DGCache: 创建缓存文件文件夹失败"); 50 | } 51 | _debugoPath = debugoPath; 52 | } 53 | return _debugoPath; 54 | } 55 | 56 | - (DGPlister *)accountPlister { 57 | if (!_accountPlister) { 58 | NSString *accountPath = nil; 59 | if (DGAccountPlugin.shared.configuration.isProductionEnvironment) { 60 | accountPath = [self.debugoPath stringByAppendingPathComponent:@"com.ripperhe.debugo.account.production.plist"]; 61 | }else{ 62 | accountPath = [self.debugoPath stringByAppendingPathComponent:@"com.ripperhe.debugo.account.development.plist"]; 63 | } 64 | 65 | _accountPlister = [[DGPlister alloc] initWithFilePath:accountPath readonly:NO]; 66 | } 67 | return _accountPlister; 68 | } 69 | 70 | 71 | @end 72 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/TouchPlugin/DGTouchWindow.m: -------------------------------------------------------------------------------- 1 | // 2 | // DGTouchWindow.m 3 | // Debugo 4 | // 5 | // GitHub https://github.com/ripperhe/Debugo 6 | // Created by ripper on 2018/9/1. 7 | // Copyright © 2018年 ripper. All rights reserved. 8 | // 9 | 10 | 11 | #import "DGTouchWindow.h" 12 | #import 13 | #import "DGTouchFingerView.h" 14 | 15 | static const void* kDGFingerViewAssociatedKey = &kDGFingerViewAssociatedKey; 16 | 17 | @interface DGTouchWindow () 18 | 19 | @property (nonatomic, weak) UIView *touchesView; 20 | 21 | @end 22 | 23 | @implementation DGTouchWindow 24 | 25 | - (id)initWithFrame:(CGRect)frame { 26 | if (self = [super initWithFrame:frame]) { 27 | self.name = @"DGTouchPlugin Window"; 28 | self.windowLevel = CGFLOAT_MAX; 29 | self.userInteractionEnabled = NO; 30 | self.rootViewController = [UIViewController new]; 31 | self.rootViewController.view.userInteractionEnabled = NO; 32 | self.touchesView = self.rootViewController.view; 33 | } 34 | return self; 35 | } 36 | 37 | #pragma mark - event 38 | 39 | - (void)displayEvent:(UIEvent *)event { 40 | NSSet *touches = [event allTouches]; 41 | for (UITouch *touch in touches) { 42 | if (touch.phase == UITouchPhaseCancelled || touch.phase == UITouchPhaseEnded) { 43 | [self removeFingerViewForTouch:touch]; 44 | } else { 45 | [self updateFingerViewForTouch:touch]; 46 | } 47 | } 48 | } 49 | 50 | - (void)updateFingerViewForTouch:(UITouch *)touch { 51 | DGTouchFingerView *fingerView = objc_getAssociatedObject(touch, kDGFingerViewAssociatedKey); 52 | CGPoint point = [touch locationInView:self.touchesView]; 53 | if (!fingerView) { 54 | fingerView = [[DGTouchFingerView alloc] initWithPoint:point]; 55 | objc_setAssociatedObject(touch, kDGFingerViewAssociatedKey, fingerView, OBJC_ASSOCIATION_ASSIGN); 56 | [self.touchesView addSubview:fingerView]; 57 | } 58 | [fingerView updateWithTouch:touch]; 59 | } 60 | 61 | - (void)removeFingerViewForTouch:(UITouch *)touch { 62 | DGTouchFingerView * fingerView = objc_getAssociatedObject (touch, kDGFingerViewAssociatedKey); 63 | if (fingerView) { 64 | objc_setAssociatedObject(touch, kDGFingerViewAssociatedKey, nil, OBJC_ASSOCIATION_ASSIGN); 65 | [fingerView removeFromSuperviewWithAnimation]; 66 | } 67 | } 68 | 69 | @end 70 | -------------------------------------------------------------------------------- /Debugo/Classes/Common/Utility/DGPathFetcher.m: -------------------------------------------------------------------------------- 1 | // 2 | // DGPathFetcher.m 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/2/22. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | /** 10 | ➜ App Sandbox tree . 11 | . 12 | ├── Documents 13 | ├── Library 14 | │   ├── Caches 15 | │   └── Preferences 16 | │   └── com.ripperhe.debugo.plist 17 | ├── SystemData 18 | └── tmp 19 | */ 20 | 21 | #import "DGPathFetcher.h" 22 | 23 | @implementation DGPathFetcher 24 | 25 | + (NSString *)bundleDirectory { 26 | return [[NSBundle mainBundle] bundlePath]; 27 | } 28 | 29 | + (NSURL *)bundleDirectoryURL { 30 | return [[NSBundle mainBundle] bundleURL]; 31 | } 32 | 33 | + (NSString *)sandboxDirectory { 34 | return NSHomeDirectory(); 35 | } 36 | 37 | + (NSURL *)sandboxDirectoryURL { 38 | return [NSURL fileURLWithPath:NSHomeDirectory() isDirectory:YES]; 39 | } 40 | 41 | + (NSString *)documentsDirectory { 42 | return NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject; 43 | } 44 | 45 | + (NSURL *)documentsDirectoryURL { 46 | return [NSURL fileURLWithPath:[self documentsDirectory] isDirectory:YES]; 47 | } 48 | 49 | + (NSString *)libraryDirectory { 50 | return NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES).firstObject; 51 | } 52 | 53 | + (NSURL *)libraryDirectoryURL { 54 | return [NSURL fileURLWithPath:[self libraryDirectory] isDirectory:YES]; 55 | } 56 | 57 | + (NSString *)cachesDirectory { 58 | return NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject; 59 | } 60 | 61 | + (NSURL *)cachesDirectoryURL { 62 | return [NSURL fileURLWithPath:[self cachesDirectory] isDirectory:YES]; 63 | } 64 | 65 | + (NSString *)temporaryDirectory { 66 | return NSTemporaryDirectory(); 67 | } 68 | 69 | + (NSURL *)temporaryDirectoryURL { 70 | return [NSURL fileURLWithPath:[self temporaryDirectory] isDirectory:YES]; 71 | } 72 | 73 | + (NSString *)userDefaultsPlistFilePath { 74 | NSString *bundleIdentifier = [NSBundle.mainBundle.infoDictionary objectForKey:@"CFBundleIdentifier"]; 75 | return [NSString stringWithFormat:@"%@/Preferences/%@.plist", [self libraryDirectory], bundleIdentifier]; 76 | } 77 | 78 | + (NSURL *)userDefaultsPlistFileURL { 79 | return [NSURL fileURLWithPath:[self userDefaultsPlistFilePath] isDirectory:NO]; 80 | } 81 | 82 | @end 83 | -------------------------------------------------------------------------------- /Debugo/Classes/Common/Utility/DGOrderedDictionary.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGOrderedDictionary.h 3 | // Debugo 4 | // 5 | // GitHub https://github.com/ripperhe/Debugo 6 | // Created by ripper on 2018/9/1. 7 | // Copyright © 2018年 ripper. All rights reserved. 8 | // 9 | 10 | #import 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | /** 15 | An ordered dictionary. 16 | 17 | Inspired by http://www.cocoawithlove.com/2008/12/ordereddictionary-subclassing-cocoa.html 18 | */ 19 | 20 | @interface DGOrderedDictionary<__covariant KeyType, __covariant ObjectType> : NSObject 21 | 22 | /// 如果更新某个已经存在的Key的值,将其下标移动到最后; 默认为 NO 23 | @property (nonatomic, assign) BOOL moveToLastWhenUpdateValue; 24 | 25 | + (instancetype)dictionary; 26 | + (instancetype)dictionaryWithCapacity:(NSUInteger)numItems; 27 | - (instancetype)init; 28 | - (instancetype)initWithCapacity:(NSUInteger)numItems; 29 | /// key 和 value 必须一一对应,nil 结尾,形如key, value, key2, value2, nil 30 | - (instancetype)initWithKeysAndObjects:(id)firstKey,...; 31 | /// sortedKeys 数组的 key 值必须和 keysAndObjects 的 key 值一一对应 32 | - (instancetype)initWithSortedKeys:(NSArray *)sortedKeys keysAndObjects:(NSDictionary *)keysAndObjects; 33 | 34 | - (void)setObject:(ObjectType)anObject forKey:(KeyType)aKey; 35 | - (void)setObject:(ObjectType)anObject atIndex:(NSUInteger)anIndex; 36 | - (void)insertObject:(ObjectType)anObject forKey:(KeyType)aKey atIndex:(NSUInteger)anIndex; 37 | 38 | - (void)removeObjectForKey:(KeyType)aKey; 39 | - (void)removeObjectAtIndex:(NSUInteger)anIndex; 40 | - (void)removeAllObjects; 41 | 42 | - (NSUInteger)count; 43 | 44 | - (NSDictionary *)keysAndObjects; 45 | 46 | - (KeyType)keyAtIndex:(NSUInteger)anIndex; 47 | 48 | - (ObjectType)objectForKey:(KeyType)aKey; 49 | - (ObjectType)objectAtIndex:(NSUInteger)anIndex; 50 | 51 | - (NSArray *)allKeys; 52 | - (NSArray *)allValues; 53 | 54 | - (NSArray *)sortedKeys; 55 | - (NSArray *)reverseSortedKeys; 56 | 57 | - (NSArray *)sortedValues; 58 | - (NSArray *)reverseSortedValues; 59 | 60 | - (NSEnumerator *)keyEnumerator; 61 | - (NSEnumerator *)reverseKeyEnumerator; 62 | 63 | - (void)enumerateKeysAndObjectsUsingBlock:(void (NS_NOESCAPE ^)(KeyType key, ObjectType obj, NSUInteger idx, BOOL *stop))block; 64 | - (void)reverseEnumerateKeysAndObjectsUsingBlock:(void (NS_NOESCAPE ^)(KeyType key, ObjectType obj, NSUInteger idx, BOOL *stop))block; 65 | 66 | @end 67 | 68 | NS_ASSUME_NONNULL_END 69 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/FilePlugin/DGDatabaseTableInfoViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // DGDatabaseTableInfoViewController.m 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/1/10. 6 | // Copyright © 2019 ripper. All rights reserved. 7 | // 8 | 9 | #import "DGDatabaseTableInfoViewController.h" 10 | 11 | static NSString *kCellID = @"cell"; 12 | static NSString *kCellTitle = @"title"; 13 | static NSString *kCellValue = @"value"; 14 | 15 | @interface DGDatabaseTableInfoViewController () 16 | 17 | @property (nonatomic, strong) NSArray *dataArray; 18 | 19 | @end 20 | 21 | @implementation DGDatabaseTableInfoViewController 22 | 23 | - (instancetype)initWithTable:(DGDatabaseTableInfo *)table { 24 | self = [super initWithStyle:UITableViewStyleGrouped]; 25 | if (self) { 26 | self.table = table; 27 | } 28 | return self; 29 | } 30 | 31 | - (void)viewDidLoad { 32 | [super viewDidLoad]; 33 | 34 | self.dataArray = @[ 35 | @{kCellTitle:@"name", kCellValue:self.table.name?:@"null"}, 36 | @{kCellTitle:@"tbl_name", kCellValue:self.table.tbl_name?:@"null"}, 37 | @{kCellTitle:@"type", kCellValue:self.table.type?:@"null"}, 38 | @{kCellTitle:@"rootpage", kCellValue:@(self.table.rootpage)}, 39 | @{kCellTitle:@"sql", kCellValue:self.table.sql?:@"null"}, 40 | ]; 41 | } 42 | 43 | - (void)setTable:(DGDatabaseTableInfo *)table { 44 | _table = table; 45 | 46 | self.title = table.name; 47 | } 48 | 49 | #pragma mark - Table view data source 50 | 51 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 52 | return 1; 53 | } 54 | 55 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 56 | return self.dataArray.count; 57 | } 58 | 59 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 60 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellID]; 61 | if (!cell) { 62 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:kCellID]; 63 | cell.selectionStyle = UITableViewCellSelectionStyleNone; 64 | cell.detailTextLabel.numberOfLines = 0; 65 | } 66 | NSDictionary *data = self.dataArray[indexPath.row]; 67 | cell.textLabel.text = data[kCellTitle]; 68 | cell.detailTextLabel.text = [NSString stringWithFormat:@"%@", data[kCellValue]]; 69 | return cell; 70 | } 71 | 72 | @end 73 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/AccountPlugin/DGAccountBackViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // DGAccountBackViewController.m 3 | // Debugo 4 | // 5 | // GitHub https://github.com/ripperhe/Debugo 6 | // Created by ripper on 2018/9/1. 7 | // Copyright © 2018年 ripper. All rights reserved. 8 | // 9 | 10 | #import "DGAccountBackViewController.h" 11 | #import "DGAccountListViewController.h" 12 | #import "DGNavigationController.h" 13 | #import "DGAccountPlugin.h" 14 | #import "DGAnimationDelegate.h" 15 | 16 | #define kBottomMargin (100.0 + kDGBottomSafeMargin) 17 | #define kLeftMargin 10 18 | 19 | @interface DGAccountBackViewController () 20 | 21 | @property (nonatomic, weak) UIView *contentView; 22 | 23 | @end 24 | 25 | @implementation DGAccountBackViewController 26 | 27 | - (void)viewDidLoad { 28 | [super viewDidLoad]; 29 | 30 | self.view.backgroundColor = [UIColor clearColor]; 31 | 32 | DGNavigationController *navVC = [[DGNavigationController alloc] initWithRootViewController:[DGAccountListViewController new]]; 33 | navVC.view.layer.cornerRadius = 13.0; 34 | navVC.view.clipsToBounds = YES; 35 | navVC.view.frame = CGRectMake(kLeftMargin, 36 | kDGScreenH, 37 | [UIScreen mainScreen].bounds.size.width - 2 * kLeftMargin, 38 | [UIScreen mainScreen].bounds.size.height - kDGStatusBarHeight - kBottomMargin); 39 | [self addChildViewController:navVC]; 40 | [self.view addSubview:navVC.view]; 41 | self.contentView = navVC.view; 42 | 43 | [UIView animateWithDuration:.2 animations:^{ 44 | self.view.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:.5]; 45 | self.contentView.dg_y = kDGStatusBarHeight + 10; 46 | }]; 47 | } 48 | 49 | - (void)viewDidLayoutSubviews { 50 | [super viewDidLayoutSubviews]; 51 | 52 | self.contentView.frame = CGRectMake(kLeftMargin, 53 | kDGStatusBarHeight + 10, 54 | [UIScreen mainScreen].bounds.size.width - 2 * kLeftMargin, 55 | [UIScreen mainScreen].bounds.size.height - kDGStatusBarHeight - kBottomMargin); 56 | } 57 | 58 | - (void)dismissWithAnimation:(void (^)(void))completion { 59 | [UIView animateWithDuration:.2 animations:^{ 60 | self.view.backgroundColor = [UIColor clearColor]; 61 | self.contentView.dg_y = kDGScreenH; 62 | } completion:^(BOOL finished) { 63 | if (completion) { 64 | completion(); 65 | } 66 | }]; 67 | } 68 | 69 | @end 70 | -------------------------------------------------------------------------------- /Debugo/Classes/Common/Utility/DGPlister.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGPlister.h 3 | // Debugo 4 | // 5 | // GitHub https://github.com/ripperhe/Debugo 6 | // Created by ripper on 2018/9/1. 7 | // Copyright © 2018年 ripper. All rights reserved. 8 | // 9 | 10 | #import 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface DGPlister : NSObject 15 | 16 | @property (nonatomic, copy, readonly) NSString *filePath; 17 | 18 | + (instancetype)new NS_UNAVAILABLE; 19 | - (instancetype)init NS_UNAVAILABLE; 20 | 21 | /** 22 | 初始化(仅支持字典类型的 plist 文件) 23 | 24 | @param filePath plist文件路径 25 | @param readonly YES, 只读取,不写入; NO,可读取可写入,如果文件不存在,则创建一个 26 | @return 如果一切正常,返回DGPlister对象;如果文件读取或写入出错,返回空值 27 | */ 28 | - (instancetype)initWithFilePath:(NSString *)filePath readonly:(BOOL)readonly; 29 | 30 | - (NSMutableDictionary *)read; 31 | - (BOOL)writeDictionary:(NSDictionary *)dictionary; 32 | 33 | - (BOOL)containsKey:(NSString *)key; 34 | 35 | - (BOOL)removeAllObjects; 36 | - (BOOL)removeObjectForKey:(NSString *)key; 37 | 38 | ///------------------------------------------------ 39 | /// write 40 | ///------------------------------------------------ 41 | 42 | - (BOOL)setObject:(id)obj forKey:(NSString *)key; 43 | 44 | - (BOOL)setDictionary:(NSDictionary *)dictionary forKey:(NSString *)key; 45 | 46 | - (BOOL)setArray:(NSArray *)value forKey:(NSString *)key; 47 | 48 | - (BOOL)setString:(NSString *)value forKey:(NSString *)key; 49 | 50 | - (BOOL)setBool:(BOOL)value forKey:(NSString *)key; 51 | 52 | - (BOOL)setInteger:(NSInteger)value forKey:(NSString *)key; 53 | 54 | - (BOOL)setFloat:(float)value forKey:(NSString *)key; 55 | 56 | - (BOOL)setDouble:(double)value forKey:(NSString *)key; 57 | 58 | ///------------------------------------------------ 59 | /// read 60 | ///------------------------------------------------ 61 | 62 | - (nullable id)objectForKey:(NSString *)key; 63 | - (nullable id)objectForKey:(NSString *)key nilHandler:(nullable id (NS_NOESCAPE^)(void))nilHandler; 64 | 65 | - (nullable NSDictionary *)dictionaryForKey:(NSString *)key; 66 | - (nullable NSMutableDictionary *)mutableDictionaryForKey:(NSString *)key; 67 | 68 | - (nullable NSArray *)arrayForKey:(NSString *)key; 69 | - (nullable NSMutableArray *)mutableArrayForKey:(NSString *)key; 70 | 71 | - (nullable NSString *)stringForKey:(NSString *)key; 72 | - (nullable NSString *)stringForKey:(NSString *)key nilOrEmpty:(nullable NSString * (NS_NOESCAPE^)(void))nilOrEmptyHandler; 73 | 74 | - (BOOL)boolForKey:(NSString *)key; 75 | 76 | - (NSInteger)integerForKey:(NSString *)key; 77 | 78 | - (float)floatForKey:(NSString *)key; 79 | 80 | - (double)doubleForKey:(NSString *)key; 81 | 82 | @end 83 | 84 | NS_ASSUME_NONNULL_END 85 | -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/Login/LoginViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // LoginViewController.m 3 | // Debugo_Example 4 | // 5 | // Created by ripper on 2018/9/21. 6 | // Copyright © 2018年 ripperhe. All rights reserved. 7 | // 8 | 9 | #import "LoginViewController.h" 10 | #import "LoginSuccessViewController.h" 11 | #import "Debugo.h" 12 | 13 | @interface LoginViewController () 14 | 15 | @property (weak, nonatomic) IBOutlet UITextField *accountTF; 16 | @property (weak, nonatomic) IBOutlet UITextField *passwordTF; 17 | 18 | @end 19 | 20 | @implementation LoginViewController 21 | 22 | - (void)viewDidLoad { 23 | [super viewDidLoad]; 24 | // Do any additional setup after loading the view. 25 | 26 | } 27 | 28 | - (IBAction)clickLogin:(id)sender { 29 | 30 | if (self.accountTF.text.length && self.passwordTF.text.length) { 31 | [self sendLoginRequestWithAccount:self.accountTF.text password:self.passwordTF.text]; 32 | self.accountTF.text = @""; 33 | self.passwordTF.text = @""; 34 | } 35 | } 36 | 37 | - (void)sendLoginRequestWithAccount:(NSString *)account password:(NSString *)password { 38 | NSLog(@"LoginVC accout : %@ password : %@", account, password); 39 | 40 | // 模拟网络请求 41 | UIView *blackView = [[UIView alloc] initWithFrame:self.view.bounds]; 42 | blackView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:.7]; 43 | UIActivityIndicatorView *indicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]; 44 | indicatorView.center = CGPointMake(blackView.frame.size.width / 2.0, blackView.frame.size.height / 2.0); 45 | [indicatorView startAnimating]; 46 | [blackView addSubview:indicatorView]; 47 | [self.navigationController.view addSubview:blackView]; 48 | 49 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 50 | 51 | // remove indicator 52 | [blackView removeFromSuperview]; 53 | 54 | // push 55 | UIStoryboard *board = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]]; 56 | LoginSuccessViewController *loginSuccessVC = [board instantiateViewControllerWithIdentifier:@"LoginSuccessViewController"]; 57 | loginSuccessVC.accountInfo = @{account:password}; 58 | [self.navigationController pushViewController:loginSuccessVC animated:YES]; 59 | 60 | 61 | /** 62 | ☄️ 登陆成功之后调用登陆成功的方法,携带上账号信息,Debugo 会保存账号数据到沙盒 Library/Caches/com.ripperhe.debugo/ 内 63 | */ 64 | [Debugo accountPluginAddAccount:[DGAccount accountWithUsername:account password:password]]; 65 | }); 66 | 67 | } 68 | 69 | 70 | @end 71 | -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Pods/Target Support Files/Pods-Debugo-Example-ObjectiveC/Pods-Debugo-Example-ObjectiveC-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | If you are using FMDB in your project, I'd love to hear about it. Let Gus know 18 | by sending an email to gus@flyingmeat.com. 19 | 20 | And if you happen to come across either Gus Mueller or Rob Ryan in a bar, you 21 | might consider purchasing a drink of their choosing if FMDB has been useful to 22 | you. 23 | 24 | Finally, and shortly, this is the MIT License. 25 | 26 | Copyright (c) 2008-2014 Flying Meat Inc. 27 | 28 | Permission is hereby granted, free of charge, to any person obtaining a copy 29 | of this software and associated documentation files (the "Software"), to deal 30 | in the Software without restriction, including without limitation the rights 31 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 32 | copies of the Software, and to permit persons to whom the Software is 33 | furnished to do so, subject to the following conditions: 34 | 35 | The above copyright notice and this permission notice shall be included in 36 | all copies or substantial portions of the Software. 37 | 38 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 39 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 40 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 41 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 42 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 43 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 44 | THE SOFTWARE. 45 | License 46 | MIT 47 | Title 48 | FMDB 49 | Type 50 | PSGroupSpecifier 51 | 52 | 53 | FooterText 54 | Generated by CocoaPods - https://cocoapods.org 55 | Title 56 | 57 | Type 58 | PSGroupSpecifier 59 | 60 | 61 | StringsTable 62 | Acknowledgements 63 | Title 64 | Acknowledgements 65 | 66 | 67 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/DGPluginManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // DGPluginManager.m 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/10/30. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import "DGPluginManager.h" 10 | 11 | @implementation DGPluginManager 12 | 13 | static DGPluginManager *_instance; 14 | + (instancetype)shared { 15 | if (!_instance) { 16 | static dispatch_once_t onceToken; 17 | dispatch_once(&onceToken, ^{ 18 | _instance = [[self alloc] init]; 19 | }); 20 | } 21 | return _instance; 22 | } 23 | 24 | + (instancetype)allocWithZone:(struct _NSZone *)zone { 25 | static dispatch_once_t onceToken; 26 | dispatch_once(&onceToken, ^{ 27 | _instance = [super allocWithZone:zone]; 28 | }); 29 | return _instance; 30 | } 31 | 32 | #pragma mark - 33 | 34 | - (void)addCustomPlugin:(Class)plugin { 35 | if (![plugin conformsToProtocol:@protocol(DGPluginProtocol)]) { 36 | NSAssert(0, @"Debugo: 必须实现了 DGPluginProtocol 协议的工具才能添加"); 37 | return; 38 | } 39 | [self.customPlugins addObject:plugin]; 40 | } 41 | 42 | - (void)putPluginsToTabBar:(nullable NSArray> *)plugins { 43 | [self.tabBarPlugins removeAllObjects]; 44 | [plugins enumerateObjectsUsingBlock:^(Class _Nonnull plugin, NSUInteger idx, BOOL * _Nonnull stop) { 45 | if (![plugin conformsToProtocol:@protocol(DGPluginProtocol)]) { 46 | NSAssert(0, @"Debugo: 必须实现了 DGPluginProtocol 协议的工具才能添加到 tab bar"); 47 | return; 48 | } 49 | if (![plugin respondsToSelector:@selector(pluginViewController)]) { 50 | NSAssert(0, @"Debugo: Debugo: 必须实现了 pluginViewController 方法的工具才能添加到 tab bar"); 51 | return; 52 | } 53 | [self.tabBarPlugins addObject:plugin]; 54 | }]; 55 | } 56 | 57 | #pragma mark - getter 58 | 59 | - (NSArray *)debugoPlugins { 60 | if (!_debugoPlugins) { 61 | _debugoPlugins = @[ 62 | DGActionPlugin.class, 63 | DGFilePlugin.class, 64 | DGAppInfoPlugin.class, 65 | DGAccountPlugin.class, 66 | DGApplePlugin.class, 67 | DGTouchPlugin.class, 68 | DGColorPlugin.class, 69 | DGPodPlugin.class, 70 | ]; 71 | } 72 | return _debugoPlugins; 73 | } 74 | 75 | - (NSMutableArray *)customPlugins { 76 | if (!_customPlugins) { 77 | _customPlugins = [NSMutableArray array]; 78 | } 79 | return _customPlugins; 80 | } 81 | 82 | - (NSMutableArray *)tabBarPlugins { 83 | if (!_tabBarPlugins) { 84 | _tabBarPlugins = [NSMutableArray array]; 85 | // 默认显示指令组件 86 | [_tabBarPlugins addObject:DGActionPlugin.class]; 87 | } 88 | return _tabBarPlugins; 89 | } 90 | 91 | @end 92 | -------------------------------------------------------------------------------- /Debugo/Classes/Common/UI/DGStaticProvider.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGStaticProvider.h 3 | // Debugo 4 | // 5 | // Created by ripper on 2019/8/26. 6 | // Copyright © 2019 ripperhe. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "DGStaticRow.h" 11 | #import "DGStaticSection.h" 12 | 13 | NS_ASSUME_NONNULL_BEGIN 14 | 15 | @interface DGStaticProvider : NSObject 16 | 17 | /// 绑定的 tableView 18 | @property (nonatomic, weak) UITableView *tableView; 19 | /// 组 20 | @property (nonatomic, strong) NSMutableArray *sections; 21 | 22 | /// 返回 cell; 默认为从 tableView 复用 row 对应的 identifier 23 | @property (nonatomic, copy) UITableViewCell * (^ _Nullable cellForRowAtIndexPath)(UITableView *tableView, NSIndexPath *indexPath, NSString *identifier); 24 | /// 返回 cell 高度 25 | @property (nonatomic, copy) CGFloat(^ _Nullable heightForRowAtIndexPath)(UITableView *tableView, NSIndexPath *indexPath); 26 | /// 选中 cell 27 | @property (nonatomic, copy) void (^ _Nullable didSelectRowAtIndexPath)(UITableView *tableView, NSIndexPath *indexPath); 28 | /// 点击 accessory button 29 | @property (nonatomic, copy) void (^ _Nullable accessoryButtonTappedForRowWithIndexPath)(UITableView *tableView, NSIndexPath *indexPath); 30 | 31 | /// 返回 section header; 默认为从 tableView 复用 section 对应的 header identifier 32 | @property (nonatomic, copy) UIView *(^ _Nullable viewForHeaderInSection)(UITableView *tableView, NSInteger section, NSString *identifier); 33 | /// 返回 section header 高度 34 | @property (nonatomic, copy) CGFloat(^ _Nullable heightForHeaderInSection)(UITableView *tableView, NSInteger section); 35 | 36 | /// 返回 section footer; 默认为从 tableView 复用 section 对应的 footer identifier 37 | @property (nonatomic, copy) UIView *(^ _Nullable viewForFooterInSection)(UITableView *tableView, NSInteger section, NSString *identifier); 38 | /// 返回 section footer 高度 39 | @property (nonatomic, copy) CGFloat(^ _Nullable heightForFooterInSection)(UITableView *tableView, NSInteger section); 40 | 41 | - (void)addRow:(DGStaticRow *)row; 42 | - (void)addRowWithBlock:(void (^)(DGStaticRow *row))block; 43 | - (void)addSection:(DGStaticSection *)section; 44 | - (void)addSectionWithBlock:(void (^)(DGStaticSection *section))block; 45 | - (void)addSections:(NSArray *)sections; 46 | 47 | /// 需传入合理的 indexPath 48 | - (DGStaticRow *)rowForIndexPath:(NSIndexPath *)indexPath; 49 | /// 需传入合理的 section 50 | - (DGStaticSection *)sectionForSection:(NSUInteger)section; 51 | 52 | @end 53 | 54 | @interface UITableView (DGStaticProvider) 55 | 56 | /// 设置静态数据源 57 | @property (nonatomic, strong) DGStaticProvider *dg_staticProvider; 58 | 59 | /// 获取 row 60 | - (DGStaticRow *)dg_staticRowForIndexPath:(NSIndexPath *)indexPath; 61 | /// 获取 section 62 | - (DGStaticSection *)dg_staticSectionForSection:(NSUInteger)section; 63 | 64 | @end 65 | 66 | NS_ASSUME_NONNULL_END 67 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/FilePlugin/DGFileParser.m: -------------------------------------------------------------------------------- 1 | // 2 | // DGFileParser.m 3 | // Debugo 4 | // 5 | // GitHub https://github.com/ripperhe/Debugo 6 | // Created by ripper on 2018/9/1. 7 | // Copyright © 2018年 ripper. All rights reserved. 8 | // 9 | 10 | #import "DGFileParser.h" 11 | 12 | @implementation DGFileParser 13 | 14 | + (NSArray *)filesForDirectory:(NSURL *)direcotryURL configuration:(DGFilePreviewConfiguration *)configuration errorHandler:(void (NS_NOESCAPE^)(NSError *))errorHandler { 15 | BOOL isDirectory = NO; 16 | BOOL isExist = [NSFileManager.defaultManager fileExistsAtPath:direcotryURL.path isDirectory:&isDirectory]; 17 | if (!isExist || !isDirectory) { 18 | return nil; 19 | } 20 | 21 | NSMutableArray *files = [NSMutableArray array]; 22 | NSArray *fileURLs = [NSArray array]; 23 | 24 | // get contents 25 | NSError *error; 26 | fileURLs = [NSFileManager.defaultManager contentsOfDirectoryAtURL:direcotryURL includingPropertiesForKeys:nil options:NSDirectoryEnumerationSkipsHiddenFiles error:&error]; 27 | if (error) { 28 | NSLog(@"%@ %s error:%@", self, __func__, error); 29 | errorHandler(error); 30 | return files; 31 | } 32 | 33 | // parse 34 | for (NSURL *URL in fileURLs) { 35 | DGFile *file = [[DGFile alloc] initWithURL:URL]; 36 | 37 | if (configuration.allowedFileTypes.count) { 38 | if (![configuration.allowedFileTypes containsObject:@(file.type)]) { 39 | continue; 40 | } 41 | } 42 | if (configuration.ignoredFileTypes.count) { 43 | if ([configuration.ignoredFileTypes containsObject:@(file.type)]) { 44 | continue; 45 | } 46 | } 47 | if (file.displayName.length) { 48 | [files addObject:file]; 49 | } 50 | } 51 | 52 | // sort 53 | [files sortUsingComparator:^NSComparisonResult(DGFile * _Nonnull obj1, DGFile * _Nonnull obj2) { 54 | return [obj1.displayName compare:obj2.displayName]; 55 | }]; 56 | return files; 57 | } 58 | 59 | + (NSArray *)filesForPath:(NSString *)path forType:(DGFileType)type errorHandler:(void (NS_NOESCAPE^)(NSError * error))errorHandler { 60 | DGFile *parseFile = [[DGFile alloc] initWithPath:path]; 61 | if (!parseFile) return nil; 62 | if (parseFile.isDirectory) { 63 | if (type == DGFileTypeDirectory) return @[parseFile]; 64 | DGFilePreviewConfiguration *configuration = [DGFilePreviewConfiguration new]; 65 | configuration.allowedFileTypes = @[@(type)]; 66 | NSArray *files = [self filesForDirectory:parseFile.fileURL configuration:configuration errorHandler:errorHandler]; 67 | return files.count ? files : nil; 68 | }else if (parseFile.type == type) { 69 | return @[parseFile]; 70 | } 71 | return nil; 72 | } 73 | 74 | @end 75 | -------------------------------------------------------------------------------- /Debugo/Classes/Plugin/FilePlugin/DGDatabaseOperation.m: -------------------------------------------------------------------------------- 1 | // 2 | // DGDatabaseOperation.m 3 | // Debugo-Example-ObjectiveC 4 | // 5 | // Created by ripper on 2019/1/9. 6 | // Copyright © 2019 ripper. All rights reserved. 7 | // 8 | 9 | #import "DGDatabaseOperation.h" 10 | #if __has_include() 11 | #import 12 | #else 13 | #import "FMDB.h" 14 | #endif 15 | 16 | @interface DGDatabaseOperation () 17 | 18 | @property (nonatomic, strong) FMDatabaseQueue *queue; 19 | 20 | @end 21 | 22 | @implementation DGDatabaseOperation 23 | 24 | - (instancetype)initWithURL:(NSURL *)url { 25 | if (self = [super init]) { 26 | // 防止在没有数据库文件的情况下,自动创建数据库 27 | if ([[NSFileManager defaultManager] fileExistsAtPath:url.path]) { 28 | self.queue = [FMDatabaseQueue databaseQueueWithURL:url]; 29 | } 30 | } 31 | return self; 32 | } 33 | 34 | - (instancetype)initWithDBQueue:(FMDatabaseQueue *)dbQueue { 35 | if (self = [super init]) { 36 | self.queue = dbQueue; 37 | } 38 | return self; 39 | } 40 | 41 | - (NSArray *)queryAllTableInfo { 42 | __block NSMutableArray *tableInfos = [NSMutableArray array]; 43 | [self.queue inDatabase:^(FMDatabase * _Nonnull db) { 44 | 45 | NSString *sql = @"SELECT type, name, tbl_name, rootpage, sql FROM (SELECT * FROM sqlite_master UNION ALL SELECT * FROM sqlite_temp_master) WHERE type = 'table' ORDER BY tbl_name, name"; 46 | FMResultSet *set = [db executeQuery:sql]; 47 | while (set.next) { 48 | DGDatabaseTableInfo *table = [DGDatabaseTableInfo new]; 49 | [table setValuesForKeysWithDictionary:set.resultDictionary]; 50 | [tableInfos addObject:table]; 51 | } 52 | [set close]; 53 | }]; 54 | return tableInfos; 55 | } 56 | 57 | - (NSArray *)queryAllColumnInfoForTable:(DGDatabaseTableInfo *)table { 58 | __block NSMutableArray *columnInfos = [NSMutableArray array]; 59 | [self.queue inDatabase:^(FMDatabase * _Nonnull db) { 60 | 61 | FMResultSet *set = [db getTableSchema:table.name]; 62 | while (set.next) { 63 | DGDatabaseColumnInfo *column = [DGDatabaseColumnInfo new]; 64 | [column setValuesForKeysWithDictionary:set.resultDictionary]; 65 | [columnInfos addObject:column]; 66 | } 67 | [set close]; 68 | }]; 69 | return columnInfos; 70 | } 71 | 72 | - (NSArray *)queryAllContentForTable:(DGDatabaseTableInfo *)table { 73 | __block NSMutableArray *contents = [NSMutableArray array]; 74 | [self.queue inDatabase:^(FMDatabase * _Nonnull db) { 75 | FMResultSet *set = [db executeQuery:[NSString stringWithFormat:@"SELECT * FROM %@", table.name]]; 76 | while (set.next) { 77 | [contents addObject:set.resultDictionary]; 78 | } 79 | [set close]; 80 | }]; 81 | return contents; 82 | } 83 | 84 | @end 85 | -------------------------------------------------------------------------------- /Example/Debugo-Example-ObjectiveC/Debugo-Example-ObjectiveC/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "iphone020pts2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "iphone020pts3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "iphone029pts2x.png", 19 | "scale" : "2x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "iphone029pts3x.png", 25 | "scale" : "3x" 26 | }, 27 | { 28 | "size" : "40x40", 29 | "idiom" : "iphone", 30 | "filename" : "iphone040pts2x.png", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "iphone040pts3x.png", 37 | "scale" : "3x" 38 | }, 39 | { 40 | "size" : "60x60", 41 | "idiom" : "iphone", 42 | "filename" : "iphone060pts2x.png", 43 | "scale" : "2x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "iphone060pts3x.png", 49 | "scale" : "3x" 50 | }, 51 | { 52 | "size" : "20x20", 53 | "idiom" : "ipad", 54 | "filename" : "ipad020pts1x.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "ipad020pts2x.png", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "size" : "29x29", 65 | "idiom" : "ipad", 66 | "filename" : "ipad029pts1x.png", 67 | "scale" : "1x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "ipad029pts2x.png", 73 | "scale" : "2x" 74 | }, 75 | { 76 | "size" : "40x40", 77 | "idiom" : "ipad", 78 | "filename" : "ipad040pts1x.png", 79 | "scale" : "1x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "ipad040pts2x.png", 85 | "scale" : "2x" 86 | }, 87 | { 88 | "size" : "76x76", 89 | "idiom" : "ipad", 90 | "filename" : "ipad076pts1x.png", 91 | "scale" : "1x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "ipad076pts2x.png", 97 | "scale" : "2x" 98 | }, 99 | { 100 | "size" : "83.5x83.5", 101 | "idiom" : "ipad", 102 | "filename" : "ipad083pts2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "idiom" : "ios-marketing", 107 | "size" : "1024x1024", 108 | "scale" : "1x" 109 | } 110 | ], 111 | "info" : { 112 | "version" : 1, 113 | "author" : "xcode" 114 | } 115 | } -------------------------------------------------------------------------------- /Debugo/Classes/Common/Utility/DGDevice.h: -------------------------------------------------------------------------------- 1 | // 2 | // DGDevice.h 3 | // Debugo 4 | // 5 | // GitHub https://github.com/ripperhe/Debugo 6 | // Created by ripper on 2018/9/1. 7 | // Copyright © 2018年 ripper. All rights reserved. 8 | // 9 | 10 | 11 | #import 12 | 13 | NS_ASSUME_NONNULL_BEGIN 14 | 15 | typedef NS_ENUM(NSUInteger, DGDeviceType) { 16 | DGDeviceTypeUnknown, 17 | DGDeviceTypeSimulator, // i386 x86_64 18 | 19 | DGDeviceType_iPhone_4, // iPhone3,1 iPhone3,2 iPhone3,3 20 | DGDeviceType_iPhone_4S, // iPhone4,1 21 | DGDeviceType_iPhone_5, // iPhone5,1 iPhone5,2 22 | DGDeviceType_iPhone_5c, // iPhone5,3 iPhone5,4 23 | DGDeviceType_iPhone_5s, // iPhone6,1 iPhone6,2 24 | DGDeviceType_iPhone_6, // iPhone7,2 25 | DGDeviceType_iPhone_6_Plus, // iPhone7,1 26 | DGDeviceType_iPhone_6s, // iPhone8,1 27 | DGDeviceType_iPhone_6s_Plus, // iPhone8,2 28 | DGDeviceType_iPhone_SE, // iPhone8,4 29 | DGDeviceType_iPhone_7, // iPhone9,1 iPhone9,3 30 | DGDeviceType_iPhone_7_Plus, // iPhone9,2 iPhone9,4 31 | DGDeviceType_iPhone_8, // iPhone10,1 iPhone10,4 32 | DGDeviceType_iPhone_8_Plus, // iPhone10,2 iPhone10,5 33 | DGDeviceType_iPhone_X, // iPhone10,3 iPhone10,6 34 | DGDeviceType_iPhone_XR, // iPhone11,8 35 | DGDeviceType_iPhone_XS, // iPhone11,2 36 | DGDeviceType_iPhone_XS_Max, // iPhone11,4 iPhone11,6 37 | }; 38 | 39 | @interface DGDevice : NSObject 40 | 41 | /** e.g. "iPhone10,3" */ 42 | @property (nonatomic, copy, readonly) NSString *identifier; 43 | /** e.g. "iPhone X (Global)" */ 44 | @property (nullable, nonatomic, copy, readonly) NSString *name; 45 | /** e.g. "5.8" */ 46 | @property (nullable, nonatomic, copy, readonly) NSString *screenInch; 47 | /** e.g. DGDeviceType_iPhone_XS */ 48 | @property (nonatomic, assign, readonly) DGDeviceType type; 49 | 50 | ///------------------------------------------------ 51 | /// Only the simulator has value. 52 | ///------------------------------------------------ 53 | 54 | /** simulator identifier e.g. "iPhone10,3" */ 55 | @property (nullable, nonatomic, copy, readonly) NSString *simulatorIdentifier; 56 | /** simulator name e.g. "iPhone X (Global)" */ 57 | @property (nullable, nonatomic, copy, readonly) NSString *simulatorName; 58 | /** simulator screen inch e.g. "5.8" */ 59 | @property (nullable, nonatomic, copy, readonly) NSString *simulatorScreenInch; 60 | /** simulator type e.g. DGDeviceType_iPhone_XS */ 61 | @property (nonatomic, assign, readonly) DGDeviceType simulatorType; 62 | 63 | + (instancetype)currentDevice; 64 | 65 | - (BOOL)isSimulator; 66 | 67 | /** 物理屏幕是否为刘海屏(不代表布局是刘海布局) */ 68 | - (BOOL)isNotch; 69 | 70 | /** 布局是否为刘海 */ 71 | - (BOOL)isNotchUI; 72 | 73 | @end 74 | 75 | 76 | /** 77 | 利用硬件信息布局UI可能会有几个问题: 78 | 1. 发布新硬件的时候无法识别 79 | 2. 没有设置当前类型设备启动图的时候,按照当前硬件类型来适配,[UIScreen mainScreen].bounds可能跟当前机型物理屏幕不对应 80 | 3. 放大模式的时候,问题同2 81 | */ 82 | 83 | NS_ASSUME_NONNULL_END 84 | --------------------------------------------------------------------------------