diff --git a/NetworkMonitor.xcodeproj/project.pbxproj b/NetworkMonitor.xcodeproj/project.pbxproj index fedda23..52d3a27 100644 --- a/NetworkMonitor.xcodeproj/project.pbxproj +++ b/NetworkMonitor.xcodeproj/project.pbxproj @@ -24,6 +24,10 @@ 7593FB6C2AFB8F06006514EF /* SysUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 755E5DEC23546BE10055946F /* SysUtils.swift */; }; 7593FB6D2AFB8F09006514EF /* StringUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 753054F0238E5B0000072D6E /* StringUtils.swift */; }; 7593FB6F2AFCCA4B006514EF /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7579DCE22372CFCB0083D47D /* Localizable.strings */; }; + 75BA1AFE2B05F73F006DAF68 /* SysInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75BA1AFD2B05F73F006DAF68 /* SysInfo.swift */; }; + 75BA1AFF2B05FC04006DAF68 /* SysInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75BA1AFD2B05F73F006DAF68 /* SysInfo.swift */; }; + 75BA1B042B06029F006DAF68 /* MemoryWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75BA1B022B0600E1006DAF68 /* MemoryWidget.swift */; }; + 75BA1B072B0605FC006DAF68 /* CpuWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75BA1B052B0605F4006DAF68 /* CpuWidget.swift */; }; 75C65D9E2351AA2500A12690 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75C65D9D2351AA2500A12690 /* AppDelegate.swift */; }; 75C65DA22351AA2600A12690 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 75C65DA12351AA2600A12690 /* Assets.xcassets */; }; 75C65DA52351AA2600A12690 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 75C65DA32351AA2600A12690 /* Main.storyboard */; }; @@ -32,10 +36,12 @@ 75E7980F2AFB3C9F0035B0E0 /* SharedData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75E7980E2AFB3C9F0035B0E0 /* SharedData.swift */; }; 75E798162AFB3CB70035B0E0 /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 75E798152AFB3CB70035B0E0 /* WidgetKit.framework */; }; 75E798182AFB3CB70035B0E0 /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 75E798172AFB3CB70035B0E0 /* SwiftUI.framework */; }; - 75E7981B2AFB3CB70035B0E0 /* widgetBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75E7981A2AFB3CB70035B0E0 /* widgetBundle.swift */; }; - 75E7981D2AFB3CB80035B0E0 /* widget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75E7981C2AFB3CB70035B0E0 /* widget.swift */; }; + 75E7981B2AFB3CB70035B0E0 /* WidgetBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75E7981A2AFB3CB70035B0E0 /* WidgetBundle.swift */; }; + 75E7981D2AFB3CB80035B0E0 /* NetworkWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75E7981C2AFB3CB70035B0E0 /* NetworkWidget.swift */; }; 75E7981F2AFB3CBA0035B0E0 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 75E7981E2AFB3CBA0035B0E0 /* Assets.xcassets */; }; 75E798242AFB3CBA0035B0E0 /* widgetExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 75E798142AFB3CB70035B0E0 /* widgetExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + F0F25DDB2B065AA5003EB2FC /* snapshot.json in Resources */ = {isa = PBXBuildFile; fileRef = F0F25DD92B065970003EB2FC /* snapshot.json */; }; + F0F25DDC2B065AA8003EB2FC /* snapshot.json in Resources */ = {isa = PBXBuildFile; fileRef = F0F25DD92B065970003EB2FC /* snapshot.json */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -96,6 +102,9 @@ 7579DCE12372CFCB0083D47D /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; 7579DCE32372D12B0083D47D /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Main.strings"; sourceTree = ""; }; 7579DCE42372D12B0083D47D /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = ""; }; + 75BA1AFD2B05F73F006DAF68 /* SysInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SysInfo.swift; sourceTree = ""; }; + 75BA1B022B0600E1006DAF68 /* MemoryWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MemoryWidget.swift; sourceTree = ""; }; + 75BA1B052B0605F4006DAF68 /* CpuWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CpuWidget.swift; sourceTree = ""; }; 75C65D9A2351AA2500A12690 /* NetworkMonitor.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NetworkMonitor.app; sourceTree = BUILT_PRODUCTS_DIR; }; 75C65D9D2351AA2500A12690 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 75C65DA12351AA2600A12690 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; @@ -109,11 +118,12 @@ 75E798142AFB3CB70035B0E0 /* widgetExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = widgetExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; 75E798152AFB3CB70035B0E0 /* WidgetKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WidgetKit.framework; path = System/Library/Frameworks/WidgetKit.framework; sourceTree = SDKROOT; }; 75E798172AFB3CB70035B0E0 /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; }; - 75E7981A2AFB3CB70035B0E0 /* widgetBundle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = widgetBundle.swift; sourceTree = ""; }; - 75E7981C2AFB3CB70035B0E0 /* widget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = widget.swift; sourceTree = ""; }; + 75E7981A2AFB3CB70035B0E0 /* WidgetBundle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetBundle.swift; sourceTree = ""; }; + 75E7981C2AFB3CB70035B0E0 /* NetworkWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkWidget.swift; sourceTree = ""; }; 75E7981E2AFB3CBA0035B0E0 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 75E798202AFB3CBA0035B0E0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 75E798212AFB3CBA0035B0E0 /* widget.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = widget.entitlements; sourceTree = ""; }; + F0F25DD92B065970003EB2FC /* snapshot.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = snapshot.json; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -163,6 +173,7 @@ 75C65D912351AA2500A12690 = { isa = PBXGroup; children = ( + F0F25DD92B065970003EB2FC /* snapshot.json */, 75515E6D23A0E84500A84695 /* InfoPlist.strings */, 753054F5238E679500072D6E /* CHANGELOG.md */, 7579DCE22372CFCB0083D47D /* Localizable.strings */, @@ -222,6 +233,7 @@ 75C65DB32351AC2800A12690 /* utils */ = { isa = PBXGroup; children = ( + 75BA1AFD2B05F73F006DAF68 /* SysInfo.swift */, 753FD0282A66B158004B9FF3 /* UIntExtensions.swift */, 75C65DB42351AC3E00A12690 /* CmdUtils.swift */, 755E5DEC23546BE10055946F /* SysUtils.swift */, @@ -251,8 +263,10 @@ 75E798192AFB3CB70035B0E0 /* widget */ = { isa = PBXGroup; children = ( - 75E7981A2AFB3CB70035B0E0 /* widgetBundle.swift */, - 75E7981C2AFB3CB70035B0E0 /* widget.swift */, + 75E7981A2AFB3CB70035B0E0 /* WidgetBundle.swift */, + 75E7981C2AFB3CB70035B0E0 /* NetworkWidget.swift */, + 75BA1B022B0600E1006DAF68 /* MemoryWidget.swift */, + 75BA1B052B0605F4006DAF68 /* CpuWidget.swift */, 75E7981E2AFB3CBA0035B0E0 /* Assets.xcassets */, 75E798202AFB3CBA0035B0E0 /* Info.plist */, 75E798212AFB3CBA0035B0E0 /* widget.entitlements */, @@ -379,6 +393,7 @@ 75515E6B23A0E84500A84695 /* InfoPlist.strings in Resources */, 7579DCE02372CFCB0083D47D /* Localizable.strings in Resources */, 75C65DA52351AA2600A12690 /* Main.storyboard in Resources */, + F0F25DDC2B065AA8003EB2FC /* snapshot.json in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -386,6 +401,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + F0F25DDB2B065AA5003EB2FC /* snapshot.json in Resources */, 75E7981F2AFB3CBA0035B0E0 /* Assets.xcassets in Resources */, 7593FB6F2AFCCA4B006514EF /* Localizable.strings in Resources */, ); @@ -407,6 +423,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 75BA1AFE2B05F73F006DAF68 /* SysInfo.swift in Sources */, 75E7980F2AFB3C9F0035B0E0 /* SharedData.swift in Sources */, 753054F1238E5B0000072D6E /* StringUtils.swift in Sources */, 75139B9C25C2B7A300FBE6EF /* Nettop.swift in Sources */, @@ -427,10 +444,13 @@ buildActionMask = 2147483647; files = ( 7593FB6D2AFB8F09006514EF /* StringUtils.swift in Sources */, + 75BA1AFF2B05FC04006DAF68 /* SysInfo.swift in Sources */, + 75BA1B042B06029F006DAF68 /* MemoryWidget.swift in Sources */, 7593FB6A2AFB8E25006514EF /* SharedData.swift in Sources */, + 75BA1B072B0605FC006DAF68 /* CpuWidget.swift in Sources */, 7593FB6C2AFB8F06006514EF /* SysUtils.swift in Sources */, - 75E7981B2AFB3CB70035B0E0 /* widgetBundle.swift in Sources */, - 75E7981D2AFB3CB80035B0E0 /* widget.swift in Sources */, + 75E7981B2AFB3CB70035B0E0 /* WidgetBundle.swift in Sources */, + 75E7981D2AFB3CB80035B0E0 /* NetworkWidget.swift in Sources */, 7593FB6B2AFB8F02006514EF /* UIntExtensions.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -651,7 +671,7 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 4; + CURRENT_PROJECT_VERSION = 5; DEAD_CODE_STRIPPING = YES; DEVELOPMENT_TEAM = ""; ENABLE_HARDENED_RUNTIME = YES; @@ -666,7 +686,7 @@ ); LIBRARY_SEARCH_PATHS = "$(PROJECT_DIR)"; MACOSX_DEPLOYMENT_TARGET = 13.0; - MARKETING_VERSION = 1.4.0; + MARKETING_VERSION = 1.4.1; PRODUCT_BUNDLE_IDENTIFIER = com.blabla.monitor; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; @@ -685,7 +705,7 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 4; + CURRENT_PROJECT_VERSION = 5; DEAD_CODE_STRIPPING = YES; DEVELOPMENT_TEAM = ""; ENABLE_HARDENED_RUNTIME = YES; @@ -700,7 +720,7 @@ ); LIBRARY_SEARCH_PATHS = "$(PROJECT_DIR)"; MACOSX_DEPLOYMENT_TARGET = 13.0; - MARKETING_VERSION = 1.4.0; + MARKETING_VERSION = 1.4.1; PRODUCT_BUNDLE_IDENTIFIER = com.blabla.monitor; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; @@ -724,7 +744,7 @@ GCC_C_LANGUAGE_STANDARD = gnu17; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = widget/Info.plist; - INFOPLIST_KEY_CFBundleDisplayName = widget; + INFOPLIST_KEY_CFBundleDisplayName = SystemStateWidget; INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2023 yahaha. All rights reserved."; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -760,7 +780,7 @@ GCC_C_LANGUAGE_STANDARD = gnu17; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = widget/Info.plist; - INFOPLIST_KEY_CFBundleDisplayName = widget; + INFOPLIST_KEY_CFBundleDisplayName = SystemStateWidget; INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2023 yahaha. All rights reserved."; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", diff --git a/NetworkMonitor.xcodeproj/project.xcworkspace/xcuserdata/wyy.xcuserdatad/UserInterfaceState.xcuserstate b/NetworkMonitor.xcodeproj/project.xcworkspace/xcuserdata/wyy.xcuserdatad/UserInterfaceState.xcuserstate index 6a73dbf..3055060 100644 Binary files a/NetworkMonitor.xcodeproj/project.xcworkspace/xcuserdata/wyy.xcuserdatad/UserInterfaceState.xcuserstate and b/NetworkMonitor.xcodeproj/project.xcworkspace/xcuserdata/wyy.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/NetworkMonitor.xcodeproj/xcshareddata/xcschemes/widgetExtension.xcscheme b/NetworkMonitor.xcodeproj/xcshareddata/xcschemes/widgetExtension.xcscheme index 970d3ee..e5078c3 100644 --- a/NetworkMonitor.xcodeproj/xcshareddata/xcschemes/widgetExtension.xcscheme +++ b/NetworkMonitor.xcodeproj/xcshareddata/xcschemes/widgetExtension.xcscheme @@ -56,8 +56,19 @@ debugServiceExtension = "internal" allowLocationSimulation = "YES" launchAutomaticallySubstyle = "2"> - + + + + + - + diff --git a/en.lproj/Localizable.strings b/en.lproj/Localizable.strings index 5482547..807ee31 100644 --- a/en.lproj/Localizable.strings +++ b/en.lproj/Localizable.strings @@ -22,3 +22,5 @@ "Basic" = "Basic"; "Status Bar" = "Status Bar"; "Keep Decimals" = "Keep Decimals"; + +"CFBundleDisplayName" = "StatusMonitor"; diff --git a/monitor/App.swift b/monitor/App.swift index 2b8ccaa..5d55d98 100644 --- a/monitor/App.swift +++ b/monitor/App.swift @@ -1,6 +1,5 @@ // // App.swift -// NetworkMonitor // // Created by wyy on 2023/11/1. // Copyright © 2023 yahaha. All rights reserved. diff --git a/monitor/Assets.xcassets/AppIcon.appiconset/1024x1024.png b/monitor/Assets.xcassets/AppIcon.appiconset/1024x1024.png deleted file mode 100644 index 7fe810e..0000000 Binary files a/monitor/Assets.xcassets/AppIcon.appiconset/1024x1024.png and /dev/null differ diff --git a/monitor/Assets.xcassets/AppIcon.appiconset/128x128.png b/monitor/Assets.xcassets/AppIcon.appiconset/128x128.png deleted file mode 100644 index 6c393a8..0000000 Binary files a/monitor/Assets.xcassets/AppIcon.appiconset/128x128.png and /dev/null differ diff --git a/monitor/Assets.xcassets/AppIcon.appiconset/16x16.png b/monitor/Assets.xcassets/AppIcon.appiconset/16x16.png deleted file mode 100644 index 5f92e2e..0000000 Binary files a/monitor/Assets.xcassets/AppIcon.appiconset/16x16.png and /dev/null differ diff --git a/monitor/Assets.xcassets/AppIcon.appiconset/256x256 1.png b/monitor/Assets.xcassets/AppIcon.appiconset/256x256 1.png deleted file mode 100644 index 86dbd31..0000000 Binary files a/monitor/Assets.xcassets/AppIcon.appiconset/256x256 1.png and /dev/null differ diff --git a/monitor/Assets.xcassets/AppIcon.appiconset/256x256.png b/monitor/Assets.xcassets/AppIcon.appiconset/256x256.png deleted file mode 100644 index 86dbd31..0000000 Binary files a/monitor/Assets.xcassets/AppIcon.appiconset/256x256.png and /dev/null differ diff --git a/monitor/Assets.xcassets/AppIcon.appiconset/32x32 1.png b/monitor/Assets.xcassets/AppIcon.appiconset/32x32 1.png deleted file mode 100644 index 5bb44fc..0000000 Binary files a/monitor/Assets.xcassets/AppIcon.appiconset/32x32 1.png and /dev/null differ diff --git a/monitor/Assets.xcassets/AppIcon.appiconset/32x32.png b/monitor/Assets.xcassets/AppIcon.appiconset/32x32.png deleted file mode 100644 index 5bb44fc..0000000 Binary files a/monitor/Assets.xcassets/AppIcon.appiconset/32x32.png and /dev/null differ diff --git a/monitor/Assets.xcassets/AppIcon.appiconset/512x512 1.png b/monitor/Assets.xcassets/AppIcon.appiconset/512x512 1.png deleted file mode 100644 index 3526d22..0000000 Binary files a/monitor/Assets.xcassets/AppIcon.appiconset/512x512 1.png and /dev/null differ diff --git a/monitor/Assets.xcassets/AppIcon.appiconset/512x512.png b/monitor/Assets.xcassets/AppIcon.appiconset/512x512.png deleted file mode 100644 index 3526d22..0000000 Binary files a/monitor/Assets.xcassets/AppIcon.appiconset/512x512.png and /dev/null differ diff --git a/monitor/Assets.xcassets/AppIcon.appiconset/64x64.png b/monitor/Assets.xcassets/AppIcon.appiconset/64x64.png deleted file mode 100644 index e8988cc..0000000 Binary files a/monitor/Assets.xcassets/AppIcon.appiconset/64x64.png and /dev/null differ diff --git a/monitor/Assets.xcassets/AppIcon.appiconset/Contents.json b/monitor/Assets.xcassets/AppIcon.appiconset/Contents.json index 60bcfd5..0a856ef 100644 --- a/monitor/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/monitor/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -1,68 +1,68 @@ { - "images" : [ - { - "filename" : "16x16.png", - "idiom" : "mac", - "scale" : "1x", - "size" : "16x16" - }, - { - "filename" : "32x32.png", - "idiom" : "mac", - "scale" : "2x", - "size" : "16x16" - }, - { - "filename" : "32x32 1.png", - "idiom" : "mac", - "scale" : "1x", - "size" : "32x32" - }, - { - "filename" : "64x64.png", - "idiom" : "mac", - "scale" : "2x", - "size" : "32x32" - }, - { - "filename" : "128x128.png", - "idiom" : "mac", - "scale" : "1x", - "size" : "128x128" - }, - { - "filename" : "256x256.png", - "idiom" : "mac", - "scale" : "2x", - "size" : "128x128" - }, - { - "filename" : "256x256 1.png", - "idiom" : "mac", - "scale" : "1x", - "size" : "256x256" - }, - { - "filename" : "512x512.png", - "idiom" : "mac", - "scale" : "2x", - "size" : "256x256" - }, - { - "filename" : "512x512 1.png", - "idiom" : "mac", - "scale" : "1x", - "size" : "512x512" - }, - { - "filename" : "1024x1024.png", - "idiom" : "mac", - "scale" : "2x", - "size" : "512x512" + "images": [ + { + "size": "16x16", + "idiom": "mac", + "filename": "icon-16.png", + "scale": "1x" + }, + { + "size": "16x16", + "idiom": "mac", + "filename": "icon-16@2x.png", + "scale": "2x" + }, + { + "size": "32x32", + "idiom": "mac", + "filename": "icon-32.png", + "scale": "1x" + }, + { + "size": "32x32", + "idiom": "mac", + "filename": "icon-32@2x.png", + "scale": "2x" + }, + { + "size": "128x128", + "idiom": "mac", + "filename": "icon-128.png", + "scale": "1x" + }, + { + "size": "128x128", + "idiom": "mac", + "filename": "icon-128@2x.png", + "scale": "2x" + }, + { + "size": "256x256", + "idiom": "mac", + "filename": "icon-256.png", + "scale": "1x" + }, + { + "size": "256x256", + "idiom": "mac", + "filename": "icon-256@2x.png", + "scale": "2x" + }, + { + "size": "512x512", + "idiom": "mac", + "filename": "icon-512.png", + "scale": "1x" + }, + { + "size": "512x512", + "idiom": "mac", + "filename": "icon-512@2x.png", + "scale": "2x" + } + ], + "info": { + "version": 1, + "author": "icon.wuruihong.com" } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} +} \ No newline at end of file diff --git a/monitor/Assets.xcassets/AppIcon.appiconset/icon-128.png b/monitor/Assets.xcassets/AppIcon.appiconset/icon-128.png new file mode 100644 index 0000000..9f1373c Binary files /dev/null and b/monitor/Assets.xcassets/AppIcon.appiconset/icon-128.png differ diff --git a/monitor/Assets.xcassets/AppIcon.appiconset/icon-128@2x.png b/monitor/Assets.xcassets/AppIcon.appiconset/icon-128@2x.png new file mode 100644 index 0000000..b4fb8ac Binary files /dev/null and b/monitor/Assets.xcassets/AppIcon.appiconset/icon-128@2x.png differ diff --git a/monitor/Assets.xcassets/AppIcon.appiconset/icon-16.png b/monitor/Assets.xcassets/AppIcon.appiconset/icon-16.png new file mode 100644 index 0000000..7441c7f Binary files /dev/null and b/monitor/Assets.xcassets/AppIcon.appiconset/icon-16.png differ diff --git a/monitor/Assets.xcassets/AppIcon.appiconset/icon-16@2x.png b/monitor/Assets.xcassets/AppIcon.appiconset/icon-16@2x.png new file mode 100644 index 0000000..b894ce4 Binary files /dev/null and b/monitor/Assets.xcassets/AppIcon.appiconset/icon-16@2x.png differ diff --git a/monitor/Assets.xcassets/AppIcon.appiconset/icon-256.png b/monitor/Assets.xcassets/AppIcon.appiconset/icon-256.png new file mode 100644 index 0000000..b4fb8ac Binary files /dev/null and b/monitor/Assets.xcassets/AppIcon.appiconset/icon-256.png differ diff --git a/monitor/Assets.xcassets/AppIcon.appiconset/icon-256@2x.png b/monitor/Assets.xcassets/AppIcon.appiconset/icon-256@2x.png new file mode 100644 index 0000000..1659955 Binary files /dev/null and b/monitor/Assets.xcassets/AppIcon.appiconset/icon-256@2x.png differ diff --git a/monitor/Assets.xcassets/AppIcon.appiconset/icon-32.png b/monitor/Assets.xcassets/AppIcon.appiconset/icon-32.png new file mode 100644 index 0000000..b894ce4 Binary files /dev/null and b/monitor/Assets.xcassets/AppIcon.appiconset/icon-32.png differ diff --git a/monitor/Assets.xcassets/AppIcon.appiconset/icon-32@2x.png b/monitor/Assets.xcassets/AppIcon.appiconset/icon-32@2x.png new file mode 100644 index 0000000..16b6a38 Binary files /dev/null and b/monitor/Assets.xcassets/AppIcon.appiconset/icon-32@2x.png differ diff --git a/monitor/Assets.xcassets/AppIcon.appiconset/icon-512.png b/monitor/Assets.xcassets/AppIcon.appiconset/icon-512.png new file mode 100644 index 0000000..1659955 Binary files /dev/null and b/monitor/Assets.xcassets/AppIcon.appiconset/icon-512.png differ diff --git a/monitor/Assets.xcassets/AppIcon.appiconset/icon-512@2x.png b/monitor/Assets.xcassets/AppIcon.appiconset/icon-512@2x.png new file mode 100644 index 0000000..f2fa607 Binary files /dev/null and b/monitor/Assets.xcassets/AppIcon.appiconset/icon-512@2x.png differ diff --git a/monitor/model/SharedData.swift b/monitor/model/SharedData.swift index 1258c33..9f30e09 100644 --- a/monitor/model/SharedData.swift +++ b/monitor/model/SharedData.swift @@ -1,6 +1,5 @@ // // SharedData.swift -// NetworkMonitor // // Created by wyy on 2023/11/7. // Copyright © 2023 yahaha. All rights reserved. @@ -41,12 +40,16 @@ class WidgetSharedData { } } - func writeData(date: Date, networkHistories: [NetworkData], maxValue: UInt) { + func writeData(date: Date, + networkHistories: [NetworkData], + maxValue: UInt, + memory: [MemoryUsageInfo], + cpu: [CpuUsageInfo]) { do { if !FileManager.default.fileExists(atPath: dataFileURL.path) { FileManager.default.createFile(atPath: dataFileURL.path, contents: nil) } else { - let data = try JSONEncoder().encode(SharedData(timestamp: date, maxNetworkValue: maxValue, networkHistory: networkHistories)) + let data = try JSONEncoder().encode(SharedData(timestamp: date, maxNetworkValue: maxValue, networkHistory: networkHistories, memory: memory, cpu: cpu)) try data.write(to: dataFileURL) } WidgetCenter.shared.reloadAllTimelines() @@ -74,6 +77,23 @@ struct SharedData: Codable { let maxNetworkValue: UInt let networkHistory: [NetworkData] + let memory: [MemoryUsageInfo] + let cpu: [CpuUsageInfo] + + + static let snapshot: SharedData? = { + guard let snapshot = Bundle.main.url(forResource: "snapshot", withExtension: "json") else { + return nil + } + do { + let data = try Data(contentsOf: snapshot) + return try JSONDecoder().decode(SharedData.self, from: data) + } catch { + Log.shared.error("error to read file \(snapshot.path), error \(error.localizedDescription)") + return nil + } + }() + var networkUnit: String { if maxNetworkValue > 1024 * 1024 { return "MB" @@ -84,6 +104,35 @@ struct SharedData: Codable { } } +struct MemoryUsageInfo: Codable, Identifiable { + let usageMB: UInt64 + let totoalMB: UInt64 + let timestamp: Date + + var id: Date { timestamp } + + var usageGB: Double { + Double(usageMB) / Double(1024) + } + + var usagePercentage: Double { + usageMB == 0 || totoalMB == 0 ? 0 : Double(usageMB / totoalMB) + } +} + +struct CpuUsageInfo: Codable, Identifiable { + let userPercentage: Double + let sysPercentage: Double + + let timestamp: Date + + let totalUser:Int64 + let totalSystem: Int64 + let total: Int64 + + var id: Date { timestamp } +} + struct NetworkData: Codable, Identifiable { let upload: UInt let download: UInt diff --git a/monitor/network/Nettop.swift b/monitor/network/Nettop.swift index 91ae9c6..0a55027 100644 --- a/monitor/network/Nettop.swift +++ b/monitor/network/Nettop.swift @@ -119,7 +119,7 @@ class Nettop: ObservableObject { } @Published var networkHisotries: [NetworkData] = [] - + @Published var started = false // 是否已经弃掉第一部分数据 @@ -129,6 +129,8 @@ class Nettop: ObservableObject { // 进程相关 var cmd: [String] var process: ProcessHelper? + var memoryHistories: [MemoryUsageInfo] = [] + var cpuHistories: [CpuUsageInfo] = [] // 缓冲 var buffer: [String] = [] @@ -172,6 +174,7 @@ class Nettop: ObservableObject { func start() { stop() + started = true DispatchQueue.global(qos: .userInteractive).async { self.process = ProcessHelper.start(arguments: self.cmd, stdout: self.parseStdout) } @@ -186,7 +189,7 @@ class Nettop: ObservableObject { appNetworkTrafficInfo.removeAll(keepingCapacity: true) WidgetSharedData.instance.reset() buffer.removeAll(keepingCapacity: true) - + totalBytesIn = 0 totalBytesOut = 0 buffer.removeAll(keepingCapacity: true) @@ -213,22 +216,47 @@ class Nettop: ObservableObject { } } + private func fillHistories() { + var histories: [NetworkData] = [] + var memories: [MemoryUsageInfo] = [] + var cpu: [CpuUsageInfo] = [] + let now = Date.now + for i in 0 ..< 60 { + if let date = Calendar.current.date(byAdding: .second, value: -(60 - i), to: now) { + histories.append(.init(upload: 0, download: 0, timestamp: date)) + memories.append(.init(usageMB: 0, totoalMB: 0, timestamp: date)) + cpu.append(.init(userPercentage: 0, sysPercentage: 0, timestamp: date, totalUser: 0, totalSystem: 0, total: 0)) + } + } + networkHisotries = histories + memoryHistories = memories + cpuHistories = cpu + networkHistoryMaxValue = 0 + } + + private func sendToWidget() { + WidgetSharedData.instance.writeData(date: Date.now, + networkHistories: networkHisotries, + maxValue: networkHistoryMaxValue, + memory: memoryHistories, + cpu: cpuHistories) + } + private func refreshData(strings: [String]) { - self.started = true if droppedCount < 2 { droppedCount += 1 buffer.removeAll(keepingCapacity: true) - - var histories: [NetworkData] = [] - let now = Date.now - for i in 0 ..< 60 { - if let date = Calendar.current.date(byAdding: .second, value: -i, to: now) { - histories.append(.init(upload: 0, download: 0, timestamp: date)) - } + fillHistories() + + + var cpu = SysInfo.getCpuUsageInfo(lastInfo: cpuHistories.last ?? .init(userPercentage: 0, sysPercentage: 0, timestamp: .now, totalUser: 0, totalSystem: 0, total: 0)) + cpuHistories.append(CpuUsageInfo(userPercentage: 0, sysPercentage: 0, timestamp: .now, totalUser: cpu.totalUser, totalSystem: cpu.totalSystem, total: cpu.total)) + while cpuHistories.count > 60 { + cpuHistories.removeFirst() + } + if droppedCount == 2 { + sendToWidget() } - networkHisotries = histories.reversed() - - WidgetSharedData.instance.writeData(date: now, networkHistories: networkHisotries, maxValue: 0) return } var map: [Int32: AppNetworks] = [:] @@ -257,18 +285,29 @@ class Nettop: ObservableObject { while networkHisotries.count > 60 { let removed = networkHisotries.removeFirst() if removed.upload == networkHistoryMaxValue || removed.download == networkHistoryMaxValue { - var maxValue:UInt = 0 + var maxValue: UInt = 0 networkHisotries.forEach { item in maxValue = max(item.upload, item.download, maxValue) } networkHistoryMaxValue = maxValue } } + if let memroy = SysInfo.getMemoryUsageInfo() { + memoryHistories.append(memroy) + while memoryHistories.count > 60 { + memoryHistories.removeFirst() + } + } + let cpu = SysInfo.getCpuUsageInfo(lastInfo: cpuHistories.last ?? .init(userPercentage: 0, sysPercentage: 0, timestamp: .now, totalUser: 0, totalSystem: 0, total: 0)) + cpuHistories.append(cpu) + while cpuHistories.count > 60 { + cpuHistories.removeFirst() + } totalBytesIn = totalInput totalBytesOut = totalOutput appNetworkTrafficInfo = map.values.sorted(using: sortOrder) - WidgetSharedData.instance.writeData(date: now, networkHistories: networkHisotries, maxValue: self.networkHistoryMaxValue) + sendToWidget() NotificationCenter.default.post(name: .networkInfoChangeNotification, object: nil) } diff --git a/monitor/utils/SysInfo.swift b/monitor/utils/SysInfo.swift new file mode 100644 index 0000000..e2ff1a6 --- /dev/null +++ b/monitor/utils/SysInfo.swift @@ -0,0 +1,83 @@ +// +// MemoryInfo.swift +// +// Created by wyy on 2023/11/16. +// Copyright © 2023 yahaha. All rights reserved. +// + +import Darwin +import Foundation + +struct SysInfo { + static func getMemoryUsageInfo() -> MemoryUsageInfo? { + var hostSize = mach_msg_type_number_t(MemoryLayout.stride / MemoryLayout.stride) + var hostInfo = vm_statistics_data_t() + let hostPort: mach_port_t = mach_host_self() + + let result = withUnsafeMutablePointer(to: &hostInfo) { + $0.withMemoryRebound(to: integer_t.self, capacity: Int(hostSize)) { + host_statistics(hostPort, HOST_VM_INFO, $0, &hostSize) + } + } + + if result == KERN_SUCCESS { + var free = UInt64(hostInfo.free_count) / 1024 + if free > UInt64.max / 4096 { + free = free / 1024 * 4096 + } else { + free = free * 4096 / 1024 + } + let total = ProcessInfo.processInfo.physicalMemory / 1024 / 1024 + return .init(usageMB: total - free, totoalMB: total, timestamp: .now) + } else { + Log.shared.error("Error with result: \(result)") + } + + return nil + } + + static func getCpuUsageInfo(lastInfo: CpuUsageInfo) -> CpuUsageInfo { + var cpuInfo: processor_info_array_t? + var processorMsgCount: mach_msg_type_number_t = 0 + var processors: natural_t = 0 + + let result = host_processor_info(mach_host_self(), PROCESSOR_CPU_LOAD_INFO, &processors, &cpuInfo, &processorMsgCount) + + let lastUserUsage = lastInfo.totalUser + let lastSystemUsage = lastInfo.totalSystem + let lastTotal = lastInfo.total + + if result == KERN_SUCCESS { + let cpuInfoArray = cpuInfo! + + var deltaUser: Int64 = lastUserUsage + var deltaSystem: Int64 = lastSystemUsage + var deltaTotal: Int64 = lastTotal + + for i in 0 ..< Int(processors) { + let user = cpuInfoArray.advanced(by: Int(CPU_STATE_MAX) * i + Int(CPU_STATE_USER)).pointee + let system = cpuInfoArray.advanced(by: Int(CPU_STATE_MAX) * i + Int(CPU_STATE_SYSTEM)).pointee + let idle = cpuInfoArray.advanced(by: Int(CPU_STATE_MAX) * i + Int(CPU_STATE_IDLE)).pointee + let nice = cpuInfoArray.advanced(by: Int(CPU_STATE_MAX) * i + Int(CPU_STATE_NICE)).pointee + deltaUser -= Int64(user) + deltaSystem = deltaSystem - Int64(system) - Int64(nice) + deltaTotal = deltaTotal - Int64(user) - Int64(system) - Int64(idle) - Int64(nice) + } + deltaTotal = -deltaTotal + deltaSystem = -deltaSystem + deltaUser = -deltaUser + + vm_deallocate(mach_task_self_, vm_address_t(Int(bitPattern: cpuInfo)), vm_size_t(processorMsgCount)) + + return CpuUsageInfo(userPercentage: Double(deltaUser) / Double(deltaTotal) * 100, + sysPercentage: Double(deltaSystem) / Double(deltaTotal) * 100, + timestamp: .now, + totalUser: lastUserUsage + deltaUser, + totalSystem: lastSystemUsage + deltaSystem, + total: lastTotal + deltaTotal) + } else { + print("Error: \(mach_error_string(result))") + } + return .init(userPercentage: 0, sysPercentage: 0, timestamp: .now, totalUser: 0, totalSystem: 0, total: 0) + } +} diff --git a/monitor/views/ContentView.swift b/monitor/views/ContentView.swift index 9e94a37..fbc9654 100644 --- a/monitor/views/ContentView.swift +++ b/monitor/views/ContentView.swift @@ -1,6 +1,5 @@ // // ContentView.swift -// NetworkMonitor // // Created by wyy on 2023/10/31. // Copyright © 2023 yahaha. All rights reserved. diff --git a/monitor/views/SettingView.swift b/monitor/views/SettingView.swift index 03e87b0..e16d06e 100644 --- a/monitor/views/SettingView.swift +++ b/monitor/views/SettingView.swift @@ -1,6 +1,5 @@ // // SettingView.swift -// NetworkMonitor // // Created by wyy on 2023/11/1. // Copyright © 2023 yahaha. All rights reserved. diff --git a/screenshot2.png b/screenshot2.png index 7ced567..9440ada 100644 Binary files a/screenshot2.png and b/screenshot2.png differ diff --git a/snapshot.json b/snapshot.json new file mode 100644 index 0000000..0bb7814 --- /dev/null +++ b/snapshot.json @@ -0,0 +1 @@ +{"cpu":[{"total":2482668,"totalSystem":145475,"sysPercentage":16.886543535620053,"timestamp":721836308.000348,"userPercentage":11.741424802110819,"totalUser":310118},{"totalSystem":145607,"timestamp":721836309.002216,"total":2483425,"totalUser":310207,"sysPercentage":17.437252311756936,"userPercentage":11.756935270805812},{"total":2484185,"totalUser":310302,"totalSystem":145736,"userPercentage":12.5,"timestamp":721836310.002283,"sysPercentage":16.973684210526315},{"sysPercentage":16.819973718791065,"total":2484946,"userPercentage":11.826544021024969,"timestamp":721836311.002232,"totalUser":310392,"totalSystem":145864},{"total":2485706,"userPercentage":9.342105263157894,"sysPercentage":16.18421052631579,"timestamp":721836312.002188,"totalSystem":145987,"totalUser":310463},{"totalUser":310534,"userPercentage":9.366754617414248,"timestamp":721836313.002218,"total":2486464,"sysPercentage":15.8311345646438,"totalSystem":146107},{"sysPercentage":16.031537450722734,"timestamp":721836314.002177,"userPercentage":9.592641261498029,"totalSystem":146229,"total":2487225,"totalUser":310607},{"userPercentage":9.486166007905137,"timestamp":721836315.002077,"totalSystem":146352,"total":2487984,"sysPercentage":16.205533596837945,"totalUser":310679},{"totalSystem":146476,"total":2488742,"totalUser":310762,"timestamp":721836316.001891,"sysPercentage":16.358839050131927,"userPercentage":10.949868073878628},{"userPercentage":12.064343163538874,"timestamp":721836317.002012,"sysPercentage":18.096514745308312,"totalUser":310852,"totalSystem":146611,"total":2489488},{"totalUser":310958,"totalSystem":146741,"userPercentage":13.94736842105263,"total":2490248,"sysPercentage":17.105263157894736,"timestamp":721836318.001834},{"sysPercentage":18.386243386243386,"totalSystem":146880,"userPercentage":14.02116402116402,"totalUser":311064,"timestamp":721836319.002042,"total":2491004},{"timestamp":721836320.002115,"totalSystem":147009,"total":2491767,"userPercentage":12.844036697247708,"sysPercentage":16.90694626474443,"totalUser":311162},{"totalUser":311260,"userPercentage":12.945838837516513,"timestamp":721836321.002084,"totalSystem":147140,"total":2492524,"sysPercentage":17.305151915455745},{"sysPercentage":17.454068241469816,"total":2493286,"userPercentage":12.860892388451445,"totalUser":311358,"totalSystem":147273,"timestamp":721836322.002178},{"sysPercentage":16.86429512516469,"totalSystem":147401,"totalUser":311442,"timestamp":721836323.002845,"total":2494045,"userPercentage":11.067193675889328},{"sysPercentage":16.62269129287599,"timestamp":721836324.002008,"totalUser":311530,"totalSystem":147527,"total":2494803,"userPercentage":11.609498680738787},{"userPercentage":14.060446780551905,"sysPercentage":17.082785808147175,"total":2495564,"totalUser":311637,"totalSystem":147657,"timestamp":721836325.002129},{"totalUser":311719,"userPercentage":10.889774236387781,"sysPercentage":16.600265604249667,"total":2496317,"timestamp":721836326.001755,"totalSystem":147782},{"total":2497080,"userPercentage":11.926605504587156,"timestamp":721836327.001879,"sysPercentage":17.300131061598954,"totalUser":311810,"totalSystem":147914},{"sysPercentage":17.654808959156785,"total":2497839,"userPercentage":12.121212121212121,"totalSystem":148048,"timestamp":721836328.001778,"totalUser":311902},{"totalSystem":148182,"userPercentage":14.868421052631579,"timestamp":721836329.001856,"sysPercentage":17.63157894736842,"totalUser":312015,"total":2498599},{"userPercentage":12.15323645970938,"timestamp":721836330.001708,"totalUser":312107,"sysPercentage":16.90885072655218,"totalSystem":148310,"total":2499356},{"total":2500117,"userPercentage":23.653088042049937,"timestamp":721836331.003894,"totalSystem":148486,"totalUser":312287,"sysPercentage":23.127463863337713},{"userPercentage":16.90694626474443,"sysPercentage":17.82437745740498,"timestamp":721836332.009122,"totalUser":312416,"totalSystem":148622,"total":2500880},{"total":2501636,"sysPercentage":18.51851851851852,"userPercentage":17.195767195767196,"timestamp":721836333.006393,"totalUser":312546,"totalSystem":148762},{"timestamp":721836334.001614,"sysPercentage":17.54617414248021,"userPercentage":15.171503957783642,"totalSystem":148895,"totalUser":312661,"total":2502394},{"totalUser":312761,"userPercentage":13.175230566534916,"total":2503153,"timestamp":721836335.00167,"sysPercentage":17.523056653491437,"totalSystem":149028},{"totalSystem":149158,"total":2503918,"userPercentage":13.071895424836603,"sysPercentage":16.99346405228758,"timestamp":721836336.009705,"totalUser":312861},{"total":2504676,"userPercentage":15.03957783641161,"timestamp":721836337.007843,"totalSystem":149297,"sysPercentage":18.337730870712402,"totalUser":312975},{"timestamp":721836338.001386,"totalUser":313092,"total":2505428,"totalSystem":149429,"sysPercentage":17.5531914893617,"userPercentage":15.558510638297873},{"sysPercentage":17.150395778364118,"timestamp":721836339.00153,"total":2506186,"userPercentage":12.401055408970976,"totalUser":313186,"totalSystem":149559},{"userPercentage":10.432395332875773,"sysPercentage":16.47220315717227,"totalSystem":149799,"timestamp":721836340.922317,"totalUser":313338,"total":2507643},{"totalUser":313373,"userPercentage":54.6875,"sysPercentage":29.6875,"total":2507707,"timestamp":721836341.006209,"totalSystem":149818},{"total":2508464,"totalSystem":149999,"userPercentage":24.30647291941876,"sysPercentage":23.91017173051519,"timestamp":721836342.003966,"totalUser":313557},{"total":2509224,"sysPercentage":17.36842105263158,"totalUser":313680,"userPercentage":16.18421052631579,"timestamp":721836343.001787,"totalSystem":150131},{"totalSystem":150265,"sysPercentage":17.562254259501966,"totalUser":313795,"total":2509987,"userPercentage":15.072083879423328,"timestamp":721836344.009038},{"userPercentage":15.8311345646438,"sysPercentage":19.261213720316622,"timestamp":721836345.006843,"totalUser":313915,"totalSystem":150411,"total":2510745},{"totalUser":313996,"userPercentage":10.67193675889328,"sysPercentage":16.205533596837945,"timestamp":721836346.007342,"totalSystem":150534,"total":2511504},{"userPercentage":11.066666666666666,"totalSystem":150667,"total":2512254,"timestamp":721836347.008969,"sysPercentage":17.733333333333334,"totalUser":314079},{"userPercentage":10.44973544973545,"totalUser":314158,"total":2513010,"timestamp":721836348.002977,"sysPercentage":16.137566137566136,"totalSystem":150789},{"timestamp":721836349.006226,"totalUser":314237,"userPercentage":10.38107752956636,"sysPercentage":16.557161629434955,"totalSystem":150915,"total":2513771},{"totalUser":314313,"totalSystem":151037,"total":2514535,"userPercentage":9.947643979057592,"sysPercentage":15.968586387434556,"timestamp":721836350.009271},{"total":2515290,"totalUser":314394,"sysPercentage":16.29139072847682,"totalSystem":151160,"userPercentage":10.728476821192052,"timestamp":721836351.004603},{"totalSystem":151283,"total":2516051,"totalUser":314474,"timestamp":721836352.005943,"sysPercentage":16.16294349540079,"userPercentage":10.512483574244415},{"totalUser":314553,"timestamp":721836353.002577,"total":2516806,"totalSystem":151404,"userPercentage":10.463576158940398,"sysPercentage":16.026490066225165},{"sysPercentage":16.600790513833992,"totalSystem":151530,"timestamp":721836354.00169,"totalUser":314633,"total":2517565,"userPercentage":10.540184453227932},{"totalSystem":151659,"total":2518327,"userPercentage":11.67979002624672,"sysPercentage":16.92913385826772,"timestamp":721836355.007273,"totalUser":314722},{"sysPercentage":17.345597897503286,"totalUser":314817,"timestamp":721836356.009776,"totalSystem":151791,"total":2519088,"userPercentage":12.483574244415244},{"sysPercentage":19.70899470899471,"timestamp":721836357.010807,"userPercentage":15.476190476190476,"totalSystem":151940,"total":2519844,"totalUser":314934},{"timestamp":721836358.00338,"sysPercentage":17.46031746031746,"totalSystem":152072,"total":2520600,"totalUser":315034,"userPercentage":13.227513227513226},{"userPercentage":10.817941952506596,"sysPercentage":16.490765171503956,"totalSystem":152197,"totalUser":315116,"timestamp":721836359.00141,"total":2521358},{"timestamp":721836360.003545,"sysPercentage":17.236842105263158,"userPercentage":13.026315789473683,"total":2522118,"totalSystem":152328,"totalUser":315215},{"timestamp":721836361.000159,"totalSystem":152451,"sysPercentage":16.334661354581673,"totalUser":315293,"userPercentage":10.358565737051793,"total":2522871},{"totalSystem":152575,"sysPercentage":16.187989556135772,"total":2523637,"userPercentage":11.096605744125327,"totalUser":315378,"timestamp":721836362.001818},{"userPercentage":10.526315789473683,"timestamp":721836363.007971,"totalUser":315458,"sysPercentage":16.18421052631579,"total":2524397,"totalSystem":152698},{"totalSystem":152824,"total":2525152,"userPercentage":10.728476821192052,"sysPercentage":16.688741721854306,"timestamp":721836364.003499,"totalUser":315539},{"totalSystem":152956,"total":2525910,"totalUser":315640,"timestamp":721836365.001476,"userPercentage":13.324538258575197,"sysPercentage":17.41424802110818},{"sysPercentage":17.63157894736842,"totalUser":315742,"totalSystem":153090,"total":2526670,"userPercentage":13.421052631578947,"timestamp":721836366.001618},{"timestamp":721836367.00138,"userPercentage":14.663143989431967,"totalUser":315853,"sysPercentage":18.09775429326288,"totalSystem":153227,"total":2527427}],"maxNetworkValue":30240,"timestamp":721836367.001417,"networkHistory":[{"upload":0,"download":0,"timestamp":721836308.000288},{"timestamp":721836309.002132,"upload":0,"download":0},{"upload":0,"timestamp":721836310.002221,"download":0},{"upload":0,"download":20,"timestamp":721836311.002167},{"upload":4996,"download":982,"timestamp":721836312.002126},{"upload":0,"download":0,"timestamp":721836313.002152},{"timestamp":721836314.002117,"upload":216,"download":0},{"upload":0,"timestamp":721836315.00202,"download":0},{"download":0,"timestamp":721836316.001826,"upload":0},{"download":0,"upload":0,"timestamp":721836317.001937},{"timestamp":721836318.001767,"download":0,"upload":0},{"timestamp":721836319.001976,"upload":0,"download":0},{"upload":0,"download":0,"timestamp":721836320.002054},{"download":52,"upload":48,"timestamp":721836321.002014},{"download":0,"upload":0,"timestamp":721836322.002103},{"timestamp":721836323.00278,"upload":0,"download":0},{"download":20,"timestamp":721836324.001942,"upload":0},{"download":0,"timestamp":721836325.00205,"upload":63},{"download":0,"upload":0,"timestamp":721836326.001688},{"upload":0,"timestamp":721836327.001819,"download":0},{"timestamp":721836328.001718,"download":0,"upload":0},{"timestamp":721836329.001785,"upload":0,"download":0},{"download":411,"timestamp":721836330.001649,"upload":0},{"upload":0,"download":0,"timestamp":721836331.003808},{"download":0,"timestamp":721836332.009063,"upload":0},{"upload":0,"download":0,"timestamp":721836333.00632},{"download":2208,"timestamp":721836334.001556,"upload":3750},{"upload":3480,"download":372,"timestamp":721836335.001603},{"upload":4664,"download":0,"timestamp":721836336.009646},{"upload":2268,"download":893,"timestamp":721836337.007787},{"upload":2809,"download":1831,"timestamp":721836338.001316},{"timestamp":721836339.001474,"download":2674,"upload":1604},{"download":63,"timestamp":721836340.922261,"upload":0},{"upload":2768,"timestamp":721836341.00615,"download":0},{"upload":63,"timestamp":721836342.003896,"download":0},{"download":0,"timestamp":721836343.001712,"upload":564},{"download":462,"upload":858,"timestamp":721836344.008979},{"upload":858,"download":462,"timestamp":721836345.006777},{"download":0,"upload":0,"timestamp":721836346.007287},{"upload":176,"timestamp":721836347.008897,"download":2420},{"upload":1722,"download":462,"timestamp":721836348.002912},{"timestamp":721836349.006149,"download":0,"upload":676},{"download":20,"upload":0,"timestamp":721836350.009214},{"download":0,"upload":0,"timestamp":721836351.004538},{"download":0,"timestamp":721836352.005866,"upload":0},{"timestamp":721836353.002514,"upload":0,"download":0},{"upload":216,"download":0,"timestamp":721836354.001616},{"timestamp":721836355.007209,"upload":0,"download":0},{"upload":0,"timestamp":721836356.009719,"download":0},{"download":375,"upload":684,"timestamp":721836357.010731},{"download":0,"timestamp":721836358.00331,"upload":0},{"timestamp":721836359.001351,"upload":30240,"download":2442},{"download":730,"timestamp":721836360.003491,"upload":3608},{"timestamp":721836361.000102,"download":512,"upload":2014},{"timestamp":721836362.001729,"upload":253,"download":549},{"download":28,"upload":0,"timestamp":721836363.007915},{"timestamp":721836364.003438,"upload":0,"download":0},{"upload":0,"download":0,"timestamp":721836365.001411},{"timestamp":721836366.001543,"upload":0,"download":138},{"timestamp":721836367.001303,"upload":0,"download":0}],"memory":[{"usageMB":16356,"timestamp":721836308.000328,"totoalMB":16384},{"totoalMB":16384,"timestamp":721836309.002177,"usageMB":16356},{"usageMB":16356,"totoalMB":16384,"timestamp":721836310.002261},{"totoalMB":16384,"timestamp":721836311.002207,"usageMB":16352},{"totoalMB":16384,"timestamp":721836312.002164,"usageMB":16352},{"usageMB":16352,"totoalMB":16384,"timestamp":721836313.002198},{"usageMB":16352,"timestamp":721836314.002152,"totoalMB":16384},{"timestamp":721836315.002056,"usageMB":16352,"totoalMB":16384},{"totoalMB":16384,"usageMB":16352,"timestamp":721836316.001867},{"totoalMB":16384,"timestamp":721836317.00199,"usageMB":16352},{"usageMB":16352,"timestamp":721836318.00181,"totoalMB":16384},{"totoalMB":16384,"timestamp":721836319.002018,"usageMB":16352},{"timestamp":721836320.002095,"usageMB":16352,"totoalMB":16384},{"usageMB":16352,"totoalMB":16384,"timestamp":721836321.002061},{"timestamp":721836322.002155,"usageMB":16352,"totoalMB":16384},{"totoalMB":16384,"timestamp":721836323.002825,"usageMB":16352},{"usageMB":16352,"totoalMB":16384,"timestamp":721836324.001976},{"timestamp":721836325.002105,"totoalMB":16384,"usageMB":16356},{"usageMB":16356,"totoalMB":16384,"timestamp":721836326.001727},{"totoalMB":16384,"usageMB":16356,"timestamp":721836327.001856},{"totoalMB":16384,"usageMB":16356,"timestamp":721836328.001755},{"timestamp":721836329.001833,"totoalMB":16384,"usageMB":16356},{"timestamp":721836330.001686,"usageMB":16356,"totoalMB":16384},{"usageMB":16348,"timestamp":721836331.003858,"totoalMB":16384},{"usageMB":16300,"timestamp":721836332.009104,"totoalMB":16384},{"usageMB":16296,"totoalMB":16384,"timestamp":721836333.006371},{"totoalMB":16384,"usageMB":16296,"timestamp":721836334.001594},{"totoalMB":16384,"usageMB":16296,"timestamp":721836335.001647},{"usageMB":16292,"totoalMB":16384,"timestamp":721836336.009684},{"usageMB":16316,"totoalMB":16384,"timestamp":721836337.007827},{"usageMB":16312,"timestamp":721836338.00136,"totoalMB":16384},{"totoalMB":16384,"usageMB":16316,"timestamp":721836339.001511},{"timestamp":721836340.922296,"totoalMB":16384,"usageMB":16308},{"timestamp":721836341.006186,"totoalMB":16384,"usageMB":16312},{"timestamp":721836342.003943,"usageMB":16368,"totoalMB":16384},{"totoalMB":16384,"timestamp":721836343.001764,"usageMB":16368},{"totoalMB":16384,"timestamp":721836344.00902,"usageMB":16368},{"usageMB":16368,"totoalMB":16384,"timestamp":721836345.006822},{"timestamp":721836346.007323,"usageMB":16364,"totoalMB":16384},{"usageMB":16364,"timestamp":721836347.008941,"totoalMB":16384},{"totoalMB":16384,"usageMB":16360,"timestamp":721836348.00295},{"timestamp":721836349.006205,"totoalMB":16384,"usageMB":16360},{"usageMB":16360,"timestamp":721836350.009251,"totoalMB":16384},{"timestamp":721836351.004578,"totoalMB":16384,"usageMB":16360},{"usageMB":16360,"totoalMB":16384,"timestamp":721836352.005914},{"usageMB":16344,"totoalMB":16384,"timestamp":721836353.00255},{"timestamp":721836354.001667,"usageMB":16344,"totoalMB":16384},{"totoalMB":16384,"timestamp":721836355.007254,"usageMB":16340},{"usageMB":16336,"totoalMB":16384,"timestamp":721836356.009756},{"timestamp":721836357.010782,"usageMB":16348,"totoalMB":16384},{"usageMB":16348,"totoalMB":16384,"timestamp":721836358.003351},{"usageMB":16344,"timestamp":721836359.001395,"totoalMB":16384},{"usageMB":16348,"totoalMB":16384,"timestamp":721836360.003526},{"totoalMB":16384,"timestamp":721836361.000138,"usageMB":16348},{"timestamp":721836362.001779,"usageMB":16348,"totoalMB":16384},{"totoalMB":16384,"timestamp":721836363.00795,"usageMB":16348},{"timestamp":721836364.003473,"usageMB":16348,"totoalMB":16384},{"usageMB":16348,"totoalMB":16384,"timestamp":721836365.001455},{"totoalMB":16384,"usageMB":16348,"timestamp":721836366.001592},{"usageMB":16348,"totoalMB":16384,"timestamp":721836367.001357}]} \ No newline at end of file diff --git a/widget/CpuWidget.swift b/widget/CpuWidget.swift new file mode 100644 index 0000000..d437653 --- /dev/null +++ b/widget/CpuWidget.swift @@ -0,0 +1,110 @@ +// +// widget.swift +// widget +// +// Created by wyy on 2023/11/16. +// Copyright © 2023 yahaha. All rights reserved. +// + +import Charts +import SwiftUI +import WidgetKit + +extension CpuUsageInfo { + var userPercentageString: String { + String(format: "%.2f", self.userPercentage) + } + var systemPercentageString: String { + String(format: "%.2f", self.sysPercentage) + } + + var usagePercentage: Double { + var total = userPercentage + sysPercentage +// total = Double(round(100*total)/100) //保留两位 + total = total > 100 ? 100 : total + return total + } +} + +struct CpuWidgetEntryView: View { + var entry: Provider.Entry + + var history: [CpuUsageInfo] { + entry.data?.cpu ?? [] + } + + var body: some View { + VStack(spacing: 16) { + if entry.data == nil { + Text("Click to start") + } else { + VStack { + HStack { + Text("CPU".localized) + .font(.title3) + .bold() + .foregroundStyle(Color.accentColor) + Spacer() + } + HStack(spacing: 2) { + Spacer() + Group { + Text("User") + + Text(entry.data?.cpu.last?.userPercentageString ?? "") + .frame(width: 38, alignment: .trailing) + Text(" %") + } + } + HStack(spacing: 2) { + Spacer() + Group { + Text("System") + Text(entry.data?.cpu.last?.systemPercentageString ?? "") + .frame(width: 38, alignment: .trailing) + Text(" %") + } + } + } + + Chart(history) { data in + LineMark( + x: .value("Time", data.timestamp), + y: .value("Value", data.usagePercentage), + series: .value("Usage", "Usage") + ) + .foregroundStyle(widgetBundle.firstColor) + } + .chartXAxis(.hidden) + .chartYAxisLabel("%") +// .chartYAxis(.hidden) + .transition(.identity) + .contentTransition(.identity) + } + } + .transition(.identity) + .contentTransition(.identity) + } +} + +struct CpuWidget: Widget { + let kind: String = "widget.cpu" + + var body: some WidgetConfiguration { + StaticConfiguration(kind: kind, provider: Provider()) { entry in + if #available(macOS 14.0, *) { + CpuWidgetEntryView(entry: entry) + .containerBackground(.fill.tertiary, for: .widget) + .widgetURL(URL(string: "main")) + } else { + CpuWidgetEntryView(entry: entry) + .padding() + .background() + .widgetURL(URL(string: "main")) + } + } + .configurationDisplayName("CPU Widget".localized) + .description("") + .supportedFamilies([.systemSmall, .systemMedium]) + } +} diff --git a/widget/MemoryWidget.swift b/widget/MemoryWidget.swift new file mode 100644 index 0000000..38be01b --- /dev/null +++ b/widget/MemoryWidget.swift @@ -0,0 +1,93 @@ +// +// widget.swift +// widget +// +// Created by wyy on 2023/11/16. +// Copyright © 2023 yahaha. All rights reserved. +// + +import Charts +import SwiftUI +import WidgetKit + +struct MemoryWidgetEntryView: View { + var entry: Provider.Entry + + var history: [MemoryUsageInfo] { + entry.data?.memory ?? [] + } + + var body: some View { + VStack(spacing: 16) { + if history.isEmpty { + Text("Click to start") + } else { + VStack { + HStack { + Text("Memory".localized) + .font(.title3) + .bold() + .foregroundStyle(Color.accentColor) + Spacer() + } + HStack { + Spacer() + Group { + Text(String(format: "%.2f", + entry.data?.memory.last?.usageGB ?? 0) + ) + Text(" GB") +// .foregroundStyle(widgetBundle.firstColor) + } + } +// HStack { +// Spacer() +// Group { +// Text("\(entry.data?.memory.last?.usagePercentage ?? 0)") + Text(" %") +// ProgressView(value: entry.data?.memory.last?.usagePercentage ?? 0) +// .progressViewStyle(.circular) +// .foregroundStyle(widgetBundle.secondColor) +// } +// } + } + + Chart(history) { data in + LineMark( + x: .value("Time", data.timestamp), + y: .value("Value", data.usageMB), + series: .value("Usage", "Usage") + ) + .foregroundStyle(widgetBundle.firstColor) + } + .chartXAxis(.hidden) + .chartYAxisLabel("MB") +// .chartYAxis(.hidden) + .transition(.identity) + .contentTransition(.identity) + } + } + .transition(.identity) + .contentTransition(.identity) + } +} + +struct MemoryWidget: Widget { + let kind: String = "widget.memory" + + var body: some WidgetConfiguration { + StaticConfiguration(kind: kind, provider: Provider()) { entry in + if #available(macOS 14.0, *) { + MemoryWidgetEntryView(entry: entry) + .containerBackground(.fill.tertiary, for: .widget) + .widgetURL(URL(string: "main")) + } else { + MemoryWidgetEntryView(entry: entry) + .padding() + .background() + .widgetURL(URL(string: "main")) + } + } + .configurationDisplayName("Memory Widget".localized) + .description("") + .supportedFamilies([.systemSmall, .systemMedium]) + } +} diff --git a/widget/widget.swift b/widget/NetworkWidget.swift similarity index 86% rename from widget/widget.swift rename to widget/NetworkWidget.swift index 49e6f67..5750798 100644 --- a/widget/widget.swift +++ b/widget/NetworkWidget.swift @@ -16,11 +16,11 @@ struct Provider: TimelineProvider { } func getSnapshot(in context: Context, completion: @escaping (SimpleEntry) -> Void) { - let entry = SimpleEntry(date: Date(), data: nil) + let entry = SimpleEntry(date: Date(), data: .snapshot) completion(entry) } - func getTimeline(in context: Context, completion: @escaping (Timeline) -> Void) { + func getTimeline(in context: Context, completion: @escaping (Timeline) -> Void) { let entries: [SimpleEntry] = [.init(date: .now.addingTimeInterval(1), data: WidgetSharedData.instance.readData())] let timeline = Timeline(entries: entries, policy: .atEnd) completion(timeline) @@ -38,9 +38,6 @@ struct widgetEntryView: View { entry.data?.networkHistory ?? [] } - let uploadForeground = Color.yellow - let downloadForegroud = Color.green - var body: some View { VStack(spacing: 16) { if entry.data == nil { @@ -57,13 +54,13 @@ struct widgetEntryView: View { HStack { Spacer() Group { - Text(entry.data?.networkHistory.last?.upload.speedFormatted ?? "") + Text(" ↑").foregroundStyle(uploadForeground) + Text(entry.data?.networkHistory.last?.upload.speedFormatted ?? "") + Text(" ↑").foregroundStyle(widgetBundle.firstColor) } } HStack { Spacer() Group { - Text(entry.data?.networkHistory.last?.download.speedFormatted ?? "") + Text(" ↓").foregroundStyle(downloadForegroud) + Text(entry.data?.networkHistory.last?.download.speedFormatted ?? "") + Text(" ↓").foregroundStyle(widgetBundle.secondColor) } } } @@ -74,14 +71,14 @@ struct widgetEntryView: View { y: .value("Value", data.adaptUploadValue(maxNetworkValue: entry.data?.maxNetworkValue ?? 0)), series: .value("Upload", "Upload") ) - .foregroundStyle(uploadForeground) + .foregroundStyle(widgetBundle.firstColor) LineMark( x: .value("Time", data.timestamp), y: .value("Value", data.adaptDownloadValue(maxNetworkValue: entry.data?.maxNetworkValue ?? 0)), series: .value("Download", "Download") ) - .foregroundStyle(downloadForegroud) + .foregroundStyle(widgetBundle.secondColor) } .chartXAxis(.hidden) .chartYAxisLabel(entry.data?.networkUnit ?? "B") @@ -95,7 +92,7 @@ struct widgetEntryView: View { } } -struct widget: Widget { +struct NetworkWidget: Widget { let kind: String = "widget.network" var body: some WidgetConfiguration { @@ -103,13 +100,15 @@ struct widget: Widget { if #available(macOS 14.0, *) { widgetEntryView(entry: entry) .containerBackground(.fill.tertiary, for: .widget) + .widgetURL(URL(string: "main")) } else { widgetEntryView(entry: entry) .padding() .background() + .widgetURL(URL(string: "main")) } } - .configurationDisplayName("Network Traffic Widget") + .configurationDisplayName("Network Widget".localized) .description("") .supportedFamilies([.systemSmall, .systemMedium]) } diff --git a/widget/widgetBundle.swift b/widget/WidgetBundle.swift similarity index 57% rename from widget/widgetBundle.swift rename to widget/WidgetBundle.swift index d4f7a7b..5d9f6b7 100644 --- a/widget/widgetBundle.swift +++ b/widget/WidgetBundle.swift @@ -11,7 +11,13 @@ import SwiftUI @main struct widgetBundle: WidgetBundle { + @WidgetBundleBuilder var body: some Widget { - widget() + NetworkWidget() + MemoryWidget() + CpuWidget() } + + static let firstColor = Color.yellow + static let secondColor = Color.green } diff --git a/zh-Hans.lproj/InfoPlist.strings b/zh-Hans.lproj/InfoPlist.strings index e6d1d2b..3a94230 100644 --- a/zh-Hans.lproj/InfoPlist.strings +++ b/zh-Hans.lproj/InfoPlist.strings @@ -5,4 +5,4 @@ Copyright © 2019 yahaha. All rights reserved. */ -"CFBundleDisplayName" = "网速监控器"; +"CFBundleDisplayName" = "系统状态监控"; diff --git a/zh-Hans.lproj/Localizable.strings b/zh-Hans.lproj/Localizable.strings index 93fab7e..ca2e297 100644 --- a/zh-Hans.lproj/Localizable.strings +++ b/zh-Hans.lproj/Localizable.strings @@ -40,3 +40,15 @@ "Exit" = "退出"; "Click to start" = "点击开始"; "Network" = "网络"; + +"Memory" = "内存"; +"User" = "用户"; +"System" = "系统"; + +"SystemStateWidget" = "系统状态小组件"; +"Network Widget" = "网络小组件"; +"Memory Widget" = "内存小组件"; +"CPU Widget" = "CPU小组件"; + + +