mirror of
https://github.com/morgan9e/macos-stats
synced 2026-04-14 00:04:15 +09:00
- looking how to decode fp2e;
- add different units for sensors; - cleanup;
This commit is contained in:
4
Cartfile
4
Cartfile
@@ -1,3 +1,3 @@
|
||||
github "sindresorhus/LaunchAtLogin"
|
||||
github "sindresorhus/LaunchAtLogin" ~> 3.0.0
|
||||
github "danielgindi/Charts" ~> 3.4.0
|
||||
github "ashleymills/Reachability.swift"
|
||||
github "ashleymills/Reachability.swift" ~> 5.0.0
|
||||
3
Makefile
3
Makefile
@@ -5,13 +5,14 @@ ITC_USERNAME = $(AC_USERNAME)
|
||||
ITC_PASSWORD = @keychain:AC_PASSWORD
|
||||
ITC_PROVIDER = $(AC_PROVIDER)
|
||||
|
||||
RequestUUID = e6c7b954-d9fa-4c74-8927-ba2172c9526e
|
||||
RequestUUID = 32c80f6c-36ed-4042-9837-b9093c9f4eb9
|
||||
|
||||
BUILD_PATH = $(PWD)/build
|
||||
ARCHIVE_PATH = $(BUILD_PATH)/$(APP).xcarchive
|
||||
APP_PATH = "$(BUILD_PATH)/$(APP).app"
|
||||
ZIP_PATH = "$(BUILD_PATH)/$(APP).zip"
|
||||
DMG_PATH = $(PWD)/$(APP).dmg
|
||||
LOCATION=$(BUILD_PATH)/$(APP).app/Contents/Library/LoginItems/LaunchAtLoginHelper.app
|
||||
|
||||
all: clean archive notarize sign build
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ Stats is a application which allows you to monitor your macOS system.
|
||||
|
||||
- CPU Usage
|
||||
- Memory Usage
|
||||
- Sensors (Temperature/Voltage/Power)
|
||||
- Disk utilization
|
||||
- Battery level
|
||||
- Network usage
|
||||
@@ -23,6 +24,7 @@ You can download latest version [here](https://github.com/exelban/stats/releases
|
||||
| --- | --- | --- |
|
||||
| **CPU** | Percentage / Chart / Chart with value / Chart Bar | Shows CPU usage |
|
||||
| **Memory** | Percentage / Chart / Chart with value / Chart Bar | Shows RAM usage |
|
||||
| **Sensors** | Text | Shows data from internal sensors |
|
||||
| **Disk** | Percentage / Chart Bar | Shows disk utilization |
|
||||
| **Battery** | Graphic / Percentage | Shows battery level and charging status |
|
||||
| **Newtork** | Dots / Upload/Download traffic | Shows network activity |
|
||||
@@ -30,7 +32,7 @@ You can download latest version [here](https://github.com/exelban/stats/releases
|
||||
## Compatibility
|
||||
| macOS | Compatible |
|
||||
| --- | --- |
|
||||
| 10.15.2 *(Catalina)* | **true** |
|
||||
| 10.15.3 *(Catalina)* | **true** |
|
||||
| 10.14.6 *(Mojave)* | **true** |
|
||||
| 10.13.6 *(High Sierra)* | **true** |
|
||||
|
||||
|
||||
@@ -400,8 +400,8 @@
|
||||
9A1410F2229E721100D29793 /* Frameworks */,
|
||||
9A1410F3229E721100D29793 /* Resources */,
|
||||
9AB54DAE22A19F96006192E0 /* Copy Files */,
|
||||
9A6698D82326A903001D00E1 /* ShellScript */,
|
||||
9A493CE1232047F00064570C /* ShellScript */,
|
||||
9A6698D82326A903001D00E1 /* Run Script */,
|
||||
9A493CE1232047F00064570C /* Run Script */,
|
||||
9A6698E72326AB16001D00E1 /* Embed Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
@@ -470,7 +470,7 @@
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
9A493CE1232047F00064570C /* ShellScript */ = {
|
||||
9A493CE1232047F00064570C /* Run Script */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
@@ -479,6 +479,7 @@
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "Run Script";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
@@ -487,7 +488,7 @@
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PROJECT_DIR}/Carthage/Build/Mac/LaunchAtLogin.framework/Resources/copy-helper.sh\"\n";
|
||||
};
|
||||
9A6698D82326A903001D00E1 /* ShellScript */ = {
|
||||
9A6698D82326A903001D00E1 /* Run Script */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 8;
|
||||
files = (
|
||||
@@ -498,6 +499,7 @@
|
||||
"$(SRCROOT)/Carthage/Build/Mac/LaunchAtLogin.framework",
|
||||
"$(SRCROOT)/Carthage/Build/Mac/Charts.framework",
|
||||
);
|
||||
name = "Run Script";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
@@ -704,6 +706,7 @@
|
||||
CODE_SIGN_IDENTITY = "Mac Developer";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 3;
|
||||
DEVELOPMENT_TEAM = RP2S87B72W;
|
||||
ENABLE_HARDENED_RUNTIME = YES;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
@@ -717,7 +720,7 @@
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||
MARKETING_VERSION = 1.5.2;
|
||||
MARKETING_VERSION = 1.6.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = eu.exelban.Stats;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
@@ -734,6 +737,7 @@
|
||||
CODE_SIGN_IDENTITY = "Mac Developer";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 3;
|
||||
DEVELOPMENT_TEAM = RP2S87B72W;
|
||||
ENABLE_HARDENED_RUNTIME = YES;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
@@ -747,7 +751,7 @@
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||
MARKETING_VERSION = 1.5.2;
|
||||
MARKETING_VERSION = 1.6.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = eu.exelban.Stats;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
|
||||
@@ -48,7 +48,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
||||
}
|
||||
|
||||
func applicationWillTerminate(_ aNotification: Notification) {
|
||||
// SMCClose()
|
||||
_ = smc.close()
|
||||
menuBar?.destroy()
|
||||
}
|
||||
|
||||
|
||||
@@ -71,8 +71,10 @@ class Sensors: Module {
|
||||
}
|
||||
|
||||
private func update() {
|
||||
var value_1: Double = 0
|
||||
var value_2: Double = 0
|
||||
var value_1_unit: Double = 0
|
||||
var value_1_value: Double = 0
|
||||
var value_2_unit: Double = 0
|
||||
var value_2_value: Double = 0
|
||||
|
||||
var sensor_1: Sensor_t? = self.sensors.find(byKey: self.value_1)
|
||||
var sensor_2: Sensor_t? = self.sensors.find(byKey: self.value_2)
|
||||
@@ -80,18 +82,20 @@ class Sensors: Module {
|
||||
if sensor_1 != nil {
|
||||
sensor_1!.update()
|
||||
if sensor_1!.value != nil {
|
||||
value_1 = sensor_1!.value!
|
||||
value_1_value = sensor_1!.value!
|
||||
value_1_unit = Double(sensor_1!.unit[0].unicodeScalarCodePoint())
|
||||
}
|
||||
}
|
||||
if sensor_2 != nil {
|
||||
sensor_2!.update()
|
||||
if sensor_2!.value != nil {
|
||||
value_2 = sensor_2!.value!
|
||||
value_2_value = sensor_2!.value!
|
||||
value_2_unit = Double(sensor_2!.unit[0].unicodeScalarCodePoint())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DispatchQueue.main.async(execute: {
|
||||
(self.widget.view as! Widget).setValue(data: [value_1, value_2])
|
||||
(self.widget.view as! Widget).setValue(data: [value_1_value, value_1_unit, value_2_value, value_2_unit])
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ enum SensorType: SensorType_t {
|
||||
case Temperature = "Temperature"
|
||||
case Voltage = "Voltage"
|
||||
case Power = "Power"
|
||||
case Frequency = "Frequency"
|
||||
case Battery = "Battery"
|
||||
}
|
||||
|
||||
struct Sensor_t {
|
||||
@@ -27,6 +29,19 @@ struct Sensor_t {
|
||||
|
||||
var group: SensorGroup_t
|
||||
var type: SensorType_t
|
||||
var unit: String {
|
||||
get {
|
||||
switch self.type{
|
||||
case SensorType.Temperature.rawValue:
|
||||
return "°"
|
||||
case SensorType.Voltage.rawValue:
|
||||
return "V"
|
||||
case SensorType.Power.rawValue:
|
||||
return "W"
|
||||
default: return ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var value: Double? = nil
|
||||
|
||||
@@ -125,7 +140,6 @@ let SensorsDict: [String: Sensor_t] = [
|
||||
"VG0C": Sensor_t(name: "GPU", group: SensorGroup.GPU.rawValue, type: SensorType.Voltage.rawValue),
|
||||
|
||||
"VM0R": Sensor_t(name: "Memory", group: SensorGroup.System.rawValue, type: SensorType.Voltage.rawValue),
|
||||
"VBAT": Sensor_t(name: "Battery", group: SensorGroup.System.rawValue, type: SensorType.Voltage.rawValue),
|
||||
"Vb0R": Sensor_t(name: "CMOS", group: SensorGroup.System.rawValue, type: SensorType.Voltage.rawValue),
|
||||
|
||||
"VD0R": Sensor_t(name: "DC In", group: SensorGroup.Sensor.rawValue, type: SensorType.Voltage.rawValue),
|
||||
@@ -148,4 +162,22 @@ let SensorsDict: [String: Sensor_t] = [
|
||||
"PPBR": Sensor_t(name: "Battery", group: SensorGroup.Sensor.rawValue, type: SensorType.Power.rawValue),
|
||||
"PDTR": Sensor_t(name: "DC In", group: SensorGroup.Sensor.rawValue, type: SensorType.Power.rawValue),
|
||||
"PSTR": Sensor_t(name: "System total", group: SensorGroup.Sensor.rawValue, type: SensorType.Power.rawValue),
|
||||
|
||||
/// Frequency
|
||||
"FRC0": Sensor_t(name: "CPU 1", group: SensorGroup.CPU.rawValue, type: SensorType.Frequency.rawValue),
|
||||
"FRC1": Sensor_t(name: "CPU 2", group: SensorGroup.CPU.rawValue, type: SensorType.Frequency.rawValue),
|
||||
"FRC2": Sensor_t(name: "CPU 3", group: SensorGroup.CPU.rawValue, type: SensorType.Frequency.rawValue),
|
||||
"FRC3": Sensor_t(name: "CPU 4", group: SensorGroup.CPU.rawValue, type: SensorType.Frequency.rawValue),
|
||||
"FRC4": Sensor_t(name: "CPU 5", group: SensorGroup.CPU.rawValue, type: SensorType.Frequency.rawValue),
|
||||
"FRC5": Sensor_t(name: "CPU 6", group: SensorGroup.CPU.rawValue, type: SensorType.Frequency.rawValue),
|
||||
"FRC6": Sensor_t(name: "CPU 7", group: SensorGroup.CPU.rawValue, type: SensorType.Frequency.rawValue),
|
||||
"FRC7": Sensor_t(name: "CPU 8", group: SensorGroup.CPU.rawValue, type: SensorType.Frequency.rawValue),
|
||||
|
||||
"CG0C": Sensor_t(name: "GPU", group: SensorGroup.GPU.rawValue, type: SensorType.Frequency.rawValue),
|
||||
"CG0S": Sensor_t(name: "GPU shader", group: SensorGroup.GPU.rawValue, type: SensorType.Frequency.rawValue),
|
||||
"CG0M": Sensor_t(name: "GPU memory", group: SensorGroup.GPU.rawValue, type: SensorType.Frequency.rawValue),
|
||||
|
||||
/// Battery
|
||||
"B0AV": Sensor_t(name: "Voltage", group: SensorGroup.Sensor.rawValue, type: SensorType.Battery.rawValue),
|
||||
"B0AC": Sensor_t(name: "Amperage", group: SensorGroup.Sensor.rawValue, type: SensorType.Battery.rawValue),
|
||||
]
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>$(MARKETING_VERSION)</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.utilities</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
//
|
||||
|
||||
import Cocoa
|
||||
import Charts
|
||||
|
||||
class Chart: NSView, Widget {
|
||||
public var name: String = "LineChart"
|
||||
@@ -172,3 +173,9 @@ class Chart: NSView, Widget {
|
||||
self.redraw()
|
||||
}
|
||||
}
|
||||
|
||||
class ChartsNetworkAxisFormatter: IAxisValueFormatter {
|
||||
func stringForValue(_ value: Double, axis: AxisBase?) -> String {
|
||||
return Units(bytes: Int64(value)).getReadableSpeed()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,11 +82,13 @@ class SensorsWidget: NSView, Widget {
|
||||
}
|
||||
|
||||
func setValue(data: [Double]) {
|
||||
if self.value != data && data.count == 2 {
|
||||
self.value = data
|
||||
|
||||
self.topValueView.stringValue = "\(Int(self.value[0]))°"
|
||||
self.bottomValueView.stringValue = "\(Int(self.value[1]))°"
|
||||
if self.value != data && data.count == 4 {
|
||||
self.value = [data[0], data[2]]
|
||||
let unit_1: String = String(UnicodeScalar(Int(data[1]))!)
|
||||
let unit_2: String = String(UnicodeScalar(Int(data[3]))!)
|
||||
|
||||
self.topValueView.stringValue = "\(Int(self.value[0]))\(unit_1)"
|
||||
self.bottomValueView.stringValue = "\(Int(self.value[1]))\(unit_2)"
|
||||
|
||||
self.topValueView.textColor = self.value[0].temperatureColor(color: self.color)
|
||||
self.bottomValueView.textColor = self.value[1].temperatureColor(color: self.color)
|
||||
|
||||
@@ -7,7 +7,123 @@
|
||||
//
|
||||
|
||||
import Cocoa
|
||||
import Charts
|
||||
|
||||
public enum Unit : Float {
|
||||
case byte = 1
|
||||
case kilobyte = 1024
|
||||
case megabyte = 1048576
|
||||
case gigabyte = 1073741824
|
||||
}
|
||||
|
||||
public struct Units {
|
||||
public let bytes: Int64
|
||||
|
||||
public init(bytes: Int64) {
|
||||
self.bytes = bytes
|
||||
}
|
||||
|
||||
public var kilobytes: Double {
|
||||
return Double(bytes) / 1_024
|
||||
}
|
||||
public var megabytes: Double {
|
||||
return kilobytes / 1_024
|
||||
}
|
||||
public var gigabytes: Double {
|
||||
return megabytes / 1_024
|
||||
}
|
||||
|
||||
public func getReadableTuple() -> (Double, String) {
|
||||
switch bytes {
|
||||
case 0..<1_024:
|
||||
return (0, "KB/s")
|
||||
case 1_024..<(1_024 * 1_024):
|
||||
return (Double(String(format: "%.2f", kilobytes))!, "KB/s")
|
||||
case 1_024..<(1_024 * 1_024 * 1_024):
|
||||
return (Double(String(format: "%.2f", megabytes))!, "MB/s")
|
||||
case (1_024 * 1_024 * 1_024)...Int64.max:
|
||||
return (Double(String(format: "%.2f", gigabytes))!, "GB/s")
|
||||
default:
|
||||
return (Double(String(format: "%.2f", kilobytes))!, "KB/s")
|
||||
}
|
||||
}
|
||||
|
||||
public func getReadableSpeed() -> String {
|
||||
switch bytes {
|
||||
case 0..<1_024:
|
||||
return "0 KB/s"
|
||||
case 1_024..<(1_024 * 1_024):
|
||||
return String(format: "%.0f KB/s", kilobytes)
|
||||
case 1_024..<(1_024 * 1_024 * 100):
|
||||
return String(format: "%.1f MB/s", megabytes)
|
||||
case (1_024 * 1_024 * 100)..<(1_024 * 1_024 * 1_024):
|
||||
return String(format: "%.0f MB/s", megabytes)
|
||||
case (1_024 * 1_024 * 1_024)...Int64.max:
|
||||
return String(format: "%.1f GB/s", gigabytes)
|
||||
default:
|
||||
return String(format: "%.0f KB/s", kilobytes)
|
||||
}
|
||||
}
|
||||
|
||||
public func getReadableMemory() -> String {
|
||||
switch bytes {
|
||||
case 0..<1_024:
|
||||
return "0 KB/s"
|
||||
case 1_024..<(1_024 * 1_024):
|
||||
return String(format: "%.0f KB", kilobytes)
|
||||
case 1_024..<(1_024 * 1_024 * 1_024):
|
||||
return String(format: "%.0f MB", megabytes)
|
||||
case (1_024 * 1_024 * 1_024)...Int64.max:
|
||||
return String(format: "%.2f GB", gigabytes)
|
||||
default:
|
||||
return String(format: "%.0f KB", kilobytes)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension String {
|
||||
func condenseWhitespace() -> String {
|
||||
let components = self.components(separatedBy: .whitespacesAndNewlines)
|
||||
return components.filter { !$0.isEmpty }.joined(separator: " ")
|
||||
}
|
||||
|
||||
var UTF8CString: UnsafeMutablePointer<Int8> {
|
||||
return UnsafeMutablePointer(mutating: (self as NSString).utf8String!)
|
||||
}
|
||||
|
||||
mutating func findAndCrop(pattern: String) -> String {
|
||||
let regex = try! NSRegularExpression(pattern: pattern)
|
||||
let stringRange = NSRange(location: 0, length: self.utf16.count)
|
||||
var line = self
|
||||
|
||||
if let searchRange = regex.firstMatch(in: self, options: [], range: stringRange) {
|
||||
let start = self.index(self.startIndex, offsetBy: searchRange.range.lowerBound)
|
||||
let end = self.index(self.startIndex, offsetBy: searchRange.range.upperBound)
|
||||
let value = String(self[start..<end]).trimmingCharacters(in: .whitespaces)
|
||||
line = self.replacingOccurrences(
|
||||
of: value,
|
||||
with: "",
|
||||
options: .regularExpression
|
||||
)
|
||||
self = line.trimmingCharacters(in: .whitespaces)
|
||||
return value.trimmingCharacters(in: .whitespaces)
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func matches(_ regex: String) -> Bool {
|
||||
return self.range(of: regex, options: .regularExpression, range: nil, locale: nil) != nil
|
||||
}
|
||||
|
||||
func toUpperCase() -> String {
|
||||
return prefix(1).capitalized + dropFirst()
|
||||
}
|
||||
func toLowwerCase() -> String {
|
||||
return prefix(1).lowercased() + dropFirst()
|
||||
}
|
||||
|
||||
subscript(offset: Int) -> Character { self[index(startIndex, offsetBy: offset)] }
|
||||
}
|
||||
|
||||
extension Double {
|
||||
func roundTo(decimalPlaces: Int) -> String {
|
||||
@@ -85,81 +201,6 @@ extension Double {
|
||||
func splitAtDecimal() -> [Int64] {
|
||||
return "\(self)".split(separator: ".").map{Int64($0)!}
|
||||
}
|
||||
}
|
||||
|
||||
public enum Unit : Float {
|
||||
case byte = 1
|
||||
case kilobyte = 1024
|
||||
case megabyte = 1048576
|
||||
case gigabyte = 1073741824
|
||||
}
|
||||
|
||||
public struct Units {
|
||||
public let bytes: Int64
|
||||
|
||||
public init(bytes: Int64) {
|
||||
self.bytes = bytes
|
||||
}
|
||||
|
||||
public var kilobytes: Double {
|
||||
return Double(bytes) / 1_024
|
||||
}
|
||||
public var megabytes: Double {
|
||||
return kilobytes / 1_024
|
||||
}
|
||||
public var gigabytes: Double {
|
||||
return megabytes / 1_024
|
||||
}
|
||||
|
||||
public func getReadableTuple() -> (Double, String) {
|
||||
switch bytes {
|
||||
case 0..<1_024:
|
||||
return (0, "KB/s")
|
||||
case 1_024..<(1_024 * 1_024):
|
||||
return (Double(String(format: "%.2f", kilobytes))!, "KB/s")
|
||||
case 1_024..<(1_024 * 1_024 * 1_024):
|
||||
return (Double(String(format: "%.2f", megabytes))!, "MB/s")
|
||||
case (1_024 * 1_024 * 1_024)...Int64.max:
|
||||
return (Double(String(format: "%.2f", gigabytes))!, "GB/s")
|
||||
default:
|
||||
return (Double(String(format: "%.2f", kilobytes))!, "KB/s")
|
||||
}
|
||||
}
|
||||
|
||||
public func getReadableSpeed() -> String {
|
||||
switch bytes {
|
||||
case 0..<1_024:
|
||||
return "0 KB/s"
|
||||
case 1_024..<(1_024 * 1_024):
|
||||
return String(format: "%.0f KB/s", kilobytes)
|
||||
case 1_024..<(1_024 * 1_024 * 100):
|
||||
return String(format: "%.1f MB/s", megabytes)
|
||||
case (1_024 * 1_024 * 100)..<(1_024 * 1_024 * 1_024):
|
||||
return String(format: "%.0f MB/s", megabytes)
|
||||
case (1_024 * 1_024 * 1_024)...Int64.max:
|
||||
return String(format: "%.1f GB/s", gigabytes)
|
||||
default:
|
||||
return String(format: "%.0f KB/s", kilobytes)
|
||||
}
|
||||
}
|
||||
|
||||
public func getReadableMemory() -> String {
|
||||
switch bytes {
|
||||
case 0..<1_024:
|
||||
return "0 KB/s"
|
||||
case 1_024..<(1_024 * 1_024):
|
||||
return String(format: "%.0f KB", kilobytes)
|
||||
case 1_024..<(1_024 * 1_024 * 1_024):
|
||||
return String(format: "%.0f MB", megabytes)
|
||||
case (1_024 * 1_024 * 1_024)...Int64.max:
|
||||
return String(format: "%.2f GB", gigabytes)
|
||||
default:
|
||||
return String(format: "%.0f KB", kilobytes)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension Double {
|
||||
|
||||
func secondsToHoursMinutesSeconds () -> (Int?, Int?, Int?) {
|
||||
let hrs = self / 3600
|
||||
@@ -192,17 +233,6 @@ extension Double {
|
||||
}
|
||||
}
|
||||
|
||||
extension String {
|
||||
func condenseWhitespace() -> String {
|
||||
let components = self.components(separatedBy: .whitespacesAndNewlines)
|
||||
return components.filter { !$0.isEmpty }.joined(separator: " ")
|
||||
}
|
||||
|
||||
var UTF8CString: UnsafeMutablePointer<Int8> {
|
||||
return UnsafeMutablePointer(mutating: (self as NSString).utf8String!)
|
||||
}
|
||||
}
|
||||
|
||||
extension NSBezierPath {
|
||||
func addArrow(start: CGPoint, end: CGPoint, pointerLineLength: CGFloat, arrowAngle: CGFloat) {
|
||||
self.move(to: start)
|
||||
@@ -219,7 +249,6 @@ extension NSBezierPath {
|
||||
}
|
||||
|
||||
extension NSColor {
|
||||
|
||||
convenience init(hexString: String, alpha: CGFloat = 1.0) {
|
||||
let hexString: String = hexString.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
|
||||
let scanner = Scanner(string: hexString)
|
||||
@@ -249,53 +278,13 @@ extension NSColor {
|
||||
}
|
||||
}
|
||||
|
||||
extension String {
|
||||
mutating func findAndCrop(pattern: String) -> String {
|
||||
let regex = try! NSRegularExpression(pattern: pattern)
|
||||
let stringRange = NSRange(location: 0, length: self.utf16.count)
|
||||
var line = self
|
||||
|
||||
if let searchRange = regex.firstMatch(in: self, options: [], range: stringRange) {
|
||||
let start = self.index(self.startIndex, offsetBy: searchRange.range.lowerBound)
|
||||
let end = self.index(self.startIndex, offsetBy: searchRange.range.upperBound)
|
||||
let value = String(self[start..<end]).trimmingCharacters(in: .whitespaces)
|
||||
line = self.replacingOccurrences(
|
||||
of: value,
|
||||
with: "",
|
||||
options: .regularExpression
|
||||
)
|
||||
self = line.trimmingCharacters(in: .whitespaces)
|
||||
return value.trimmingCharacters(in: .whitespaces)
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func matches(_ regex: String) -> Bool {
|
||||
return self.range(of: regex, options: .regularExpression, range: nil, locale: nil) != nil
|
||||
}
|
||||
|
||||
func toUpperCase() -> String {
|
||||
return prefix(1).capitalized + dropFirst()
|
||||
}
|
||||
func toLowwerCase() -> String {
|
||||
return prefix(1).lowercased() + dropFirst()
|
||||
}
|
||||
}
|
||||
|
||||
extension URL {
|
||||
func checkFileExist() -> Bool {
|
||||
return FileManager.default.fileExists(atPath: self.path)
|
||||
}
|
||||
}
|
||||
|
||||
class ChartsNetworkAxisFormatter: IAxisValueFormatter {
|
||||
func stringForValue(_ value: Double, axis: AxisBase?) -> String {
|
||||
return Units(bytes: Int64(value)).getReadableSpeed()
|
||||
}
|
||||
}
|
||||
|
||||
public extension FourCharCode {
|
||||
extension FourCharCode {
|
||||
init(fromString str: String) {
|
||||
precondition(str.count == 4)
|
||||
|
||||
@@ -340,3 +329,12 @@ extension NSMenuItem {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension Character {
|
||||
func unicodeScalarCodePoint() -> UInt32 {
|
||||
let characterString = String(self)
|
||||
let scalars = characterString.unicodeScalars
|
||||
|
||||
return scalars[scalars.startIndex].value
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ enum SMCDataType: String {
|
||||
case SP87 = "sp87"
|
||||
case FLT = "flt "
|
||||
case FPE2 = "fpe2"
|
||||
case FP2E = "fp2e"
|
||||
}
|
||||
|
||||
enum SMCKeys: UInt8 {
|
||||
@@ -151,12 +152,8 @@ class SMCService {
|
||||
return Double(value!)
|
||||
}
|
||||
return nil
|
||||
case SMCDataType.FPE2.rawValue:
|
||||
// ntohs(*(UInt16*)val.bytes) / 4.0;
|
||||
print("FPE2")
|
||||
break
|
||||
default:
|
||||
print("unsupported data type \(val.dataType)")
|
||||
print("unsupported data type \(val.dataType) for key: \(key)")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user