├── SystemStats
├── Assets.xcassets
│ ├── Contents.json
│ ├── AppIcon.appiconset
│ │ ├── logo-1024.png
│ │ └── Contents.json
│ └── AccentColor.colorset
│ │ └── Contents.json
├── Preview Content
│ └── Preview Assets.xcassets
│ │ └── Contents.json
├── Item.swift
├── SystemStats.entitlements
├── SystemStatsApp.swift
├── ContentView.swift
└── StatisticsView.swift
├── WatchStats Watch App
├── Assets.xcassets
│ ├── Contents.json
│ ├── AppIcon.appiconset
│ │ ├── logo-watch.png
│ │ └── Contents.json
│ └── AccentColor.colorset
│ │ └── Contents.json
├── Preview Content
│ └── Preview Assets.xcassets
│ │ └── Contents.json
├── WatchStatsApp.swift
└── ContentView.swift
├── README.md
├── SystemStats.xcodeproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── xcuserdata
│ └── zachnagengast.xcuserdatad
│ │ ├── xcschemes
│ │ └── xcschememanagement.plist
│ │ └── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
├── xcshareddata
│ └── xcschemes
│ │ ├── SystemStats.xcscheme
│ │ └── WatchStats Watch App.xcscheme
└── project.pbxproj
├── SystemStatsUITests
├── DiagnosticsUITestsLaunchTests.swift
└── DiagnosticsUITests.swift
├── watchstats Watch AppUITests
├── WatchStats_Watch_AppUITestsLaunchTests.swift
└── WatchStats_Watch_AppUITests.swift
├── LICENSE
├── SystemStatsTests
└── DiagnosticsTests.swift
├── watchstats Watch AppTests
└── WatchStats_Watch_AppTests.swift
└── .gitignore
/SystemStats/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/WatchStats Watch App/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/SystemStats/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/WatchStats Watch App/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/SystemStats/Assets.xcassets/AppIcon.appiconset/logo-1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/argmaxinc/swift-system-stats/HEAD/SystemStats/Assets.xcassets/AppIcon.appiconset/logo-1024.png
--------------------------------------------------------------------------------
/WatchStats Watch App/Assets.xcassets/AppIcon.appiconset/logo-watch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/argmaxinc/swift-system-stats/HEAD/WatchStats Watch App/Assets.xcassets/AppIcon.appiconset/logo-watch.png
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # SystemStats
2 |
3 | Monitor your iPhone's memory, compute, and more.
4 |
5 |
6 | 
7 |
--------------------------------------------------------------------------------
/SystemStats/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/WatchStats Watch App/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/SystemStats.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/SystemStats.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/SystemStats/Item.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Item.swift
3 | // SystemStats
4 | //
5 | // Created by Zach Nagengast on 11/9/23.
6 | //
7 |
8 | import Foundation
9 | import SwiftData
10 |
11 | @Model
12 | final class Item {
13 | var timestamp: Date
14 |
15 | init(timestamp: Date) {
16 | self.timestamp = timestamp
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/WatchStats Watch App/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "logo-watch.png",
5 | "idiom" : "universal",
6 | "platform" : "watchos",
7 | "size" : "1024x1024"
8 | }
9 | ],
10 | "info" : {
11 | "author" : "xcode",
12 | "version" : 1
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/WatchStats Watch App/WatchStatsApp.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WatchStatsApp.swift
3 | // WatchStats Watch App
4 | //
5 | // Created by Zach Nagengast on 12/8/23.
6 | //
7 |
8 | import SwiftUI
9 |
10 | @main
11 | struct WatchStats_Watch_AppApp: App {
12 | var body: some Scene {
13 | WindowGroup {
14 | ContentView()
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/SystemStats/SystemStats.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 | com.apple.security.files.user-selected.read-only
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/SystemStats/SystemStatsApp.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SystemStatsApp.swift
3 | // SystemStats
4 | //
5 | // Created by Zach Nagengast on 11/9/23.
6 | //
7 |
8 | import SwiftUI
9 | import SwiftData
10 |
11 | @main
12 | struct SystemStatsApp: App {
13 | var sharedModelContainer: ModelContainer = {
14 | let schema = Schema([
15 | Item.self,
16 | ])
17 | let modelConfiguration = ModelConfiguration(schema: schema, isStoredInMemoryOnly: false)
18 |
19 | do {
20 | return try ModelContainer(for: schema, configurations: [modelConfiguration])
21 | } catch {
22 | fatalError("Could not create ModelContainer: \(error)")
23 | }
24 | }()
25 |
26 | var body: some Scene {
27 | WindowGroup {
28 | StatisticsView()
29 | }
30 | .modelContainer(sharedModelContainer)
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/SystemStatsUITests/DiagnosticsUITestsLaunchTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SystemStatsUITestsLaunchTests.swift
3 | // SystemStatsUITests
4 | //
5 | // Created by Zach Nagengast on 11/9/23.
6 | //
7 |
8 | import XCTest
9 |
10 | final class SystemStatsUITestsLaunchTests: XCTestCase {
11 |
12 | override class var runsForEachTargetApplicationUIConfiguration: Bool {
13 | true
14 | }
15 |
16 | override func setUpWithError() throws {
17 | continueAfterFailure = false
18 | }
19 |
20 | func testLaunch() throws {
21 | let app = XCUIApplication()
22 | app.launch()
23 |
24 | // Insert steps here to perform after app launch but before taking a screenshot,
25 | // such as logging into a test account or navigating somewhere in the app
26 |
27 | let attachment = XCTAttachment(screenshot: app.screenshot())
28 | attachment.name = "Launch Screen"
29 | attachment.lifetime = .keepAlways
30 | add(attachment)
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/watchstats Watch AppUITests/WatchStats_Watch_AppUITestsLaunchTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WatchStats_Watch_AppUITestsLaunchTests.swift
3 | // WatchStats Watch AppUITests
4 | //
5 | // Created by Zach Nagengast on 12/8/23.
6 | //
7 |
8 | import XCTest
9 |
10 | final class WatchStats_Watch_AppUITestsLaunchTests: XCTestCase {
11 |
12 | override class var runsForEachTargetApplicationUIConfiguration: Bool {
13 | true
14 | }
15 |
16 | override func setUpWithError() throws {
17 | continueAfterFailure = false
18 | }
19 |
20 | func testLaunch() throws {
21 | let app = XCUIApplication()
22 | app.launch()
23 |
24 | // Insert steps here to perform after app launch but before taking a screenshot,
25 | // such as logging into a test account or navigating somewhere in the app
26 |
27 | let attachment = XCTAttachment(screenshot: app.screenshot())
28 | attachment.name = "Launch Screen"
29 | attachment.lifetime = .keepAlways
30 | add(attachment)
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 argmax, inc.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/SystemStats/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "logo-1024.png",
5 | "idiom" : "universal",
6 | "platform" : "ios",
7 | "size" : "1024x1024"
8 | },
9 | {
10 | "idiom" : "mac",
11 | "scale" : "1x",
12 | "size" : "16x16"
13 | },
14 | {
15 | "idiom" : "mac",
16 | "scale" : "2x",
17 | "size" : "16x16"
18 | },
19 | {
20 | "idiom" : "mac",
21 | "scale" : "1x",
22 | "size" : "32x32"
23 | },
24 | {
25 | "idiom" : "mac",
26 | "scale" : "2x",
27 | "size" : "32x32"
28 | },
29 | {
30 | "idiom" : "mac",
31 | "scale" : "1x",
32 | "size" : "128x128"
33 | },
34 | {
35 | "idiom" : "mac",
36 | "scale" : "2x",
37 | "size" : "128x128"
38 | },
39 | {
40 | "idiom" : "mac",
41 | "scale" : "1x",
42 | "size" : "256x256"
43 | },
44 | {
45 | "idiom" : "mac",
46 | "scale" : "2x",
47 | "size" : "256x256"
48 | },
49 | {
50 | "idiom" : "mac",
51 | "scale" : "1x",
52 | "size" : "512x512"
53 | },
54 | {
55 | "idiom" : "mac",
56 | "scale" : "2x",
57 | "size" : "512x512"
58 | }
59 | ],
60 | "info" : {
61 | "author" : "xcode",
62 | "version" : 1
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/SystemStatsTests/DiagnosticsTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SystemStatsTests.swift
3 | // SystemStatsTests
4 | //
5 | // Created by Zach Nagengast on 11/9/23.
6 | //
7 |
8 | import XCTest
9 |
10 | final class SystemStatsTests: XCTestCase {
11 |
12 | override func setUpWithError() throws {
13 | // Put setup code here. This method is called before the invocation of each test method in the class.
14 | }
15 |
16 | override func tearDownWithError() throws {
17 | // Put teardown code here. This method is called after the invocation of each test method in the class.
18 | }
19 |
20 | func testExample() throws {
21 | // This is an example of a functional test case.
22 | // Use XCTAssert and related functions to verify your tests produce the correct results.
23 | // Any test you write for XCTest can be annotated as throws and async.
24 | // Mark your test throws to produce an unexpected failure when your test encounters an uncaught error.
25 | // Mark your test async to allow awaiting for asynchronous code to complete. Check the results with assertions afterwards.
26 | }
27 |
28 | func testPerformanceExample() throws {
29 | // This is an example of a performance test case.
30 | measure {
31 | // Put the code you want to measure the time of here.
32 | }
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/watchstats Watch AppTests/WatchStats_Watch_AppTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WatchStats_Watch_AppTests.swift
3 | // WatchStats Watch AppTests
4 | //
5 | // Created by Zach Nagengast on 12/8/23.
6 | //
7 |
8 | import XCTest
9 | @testable import WatchStats_Watch_App
10 |
11 | final class WatchStats_Watch_AppTests: XCTestCase {
12 |
13 | override func setUpWithError() throws {
14 | // Put setup code here. This method is called before the invocation of each test method in the class.
15 | }
16 |
17 | override func tearDownWithError() throws {
18 | // Put teardown code here. This method is called after the invocation of each test method in the class.
19 | }
20 |
21 | func testExample() throws {
22 | // This is an example of a functional test case.
23 | // Use XCTAssert and related functions to verify your tests produce the correct results.
24 | // Any test you write for XCTest can be annotated as throws and async.
25 | // Mark your test throws to produce an unexpected failure when your test encounters an uncaught error.
26 | // Tests marked async will run the test method on an arbitrary thread managed by the Swift runtime.
27 | }
28 |
29 | func testPerformanceExample() throws {
30 | // This is an example of a performance test case.
31 | self.measure {
32 | // Put the code you want to measure the time of here.
33 | }
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/SystemStats.xcodeproj/xcuserdata/zachnagengast.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | SystemStats.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 | WatchStats Watch App.xcscheme_^#shared#^_
13 |
14 | orderHint
15 | 1
16 |
17 | watchstats Watch App.xcscheme_^#shared#^_
18 |
19 | orderHint
20 | 1
21 |
22 |
23 | SuppressBuildableAutocreation
24 |
25 | 160B440F2AFD965B00D478A8
26 |
27 | primary
28 |
29 |
30 | 160B44222AFD965D00D478A8
31 |
32 | primary
33 |
34 |
35 | 160B442C2AFD965D00D478A8
36 |
37 | primary
38 |
39 |
40 | 167124132B23C47600CC0F3D
41 |
42 | primary
43 |
44 |
45 | 167124222B23C47700CC0F3D
46 |
47 | primary
48 |
49 |
50 | 1671242C2B23C47800CC0F3D
51 |
52 | primary
53 |
54 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/SystemStatsUITests/DiagnosticsUITests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SystemStatsUITests.swift
3 | // SystemStatsUITests
4 | //
5 | // Created by Zach Nagengast on 11/9/23.
6 | //
7 |
8 | import XCTest
9 |
10 | final class SystemStatsUITests: XCTestCase {
11 |
12 | override func setUpWithError() throws {
13 | // Put setup code here. This method is called before the invocation of each test method in the class.
14 |
15 | // In UI tests it is usually best to stop immediately when a failure occurs.
16 | continueAfterFailure = false
17 |
18 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
19 | }
20 |
21 | override func tearDownWithError() throws {
22 | // Put teardown code here. This method is called after the invocation of each test method in the class.
23 | }
24 |
25 | func testExample() throws {
26 | // UI tests must launch the application that they test.
27 | let app = XCUIApplication()
28 | app.launch()
29 |
30 | // Use XCTAssert and related functions to verify your tests produce the correct results.
31 | }
32 |
33 | func testLaunchPerformance() throws {
34 | if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 7.0, *) {
35 | // This measures how long it takes to launch your application.
36 | measure(metrics: [XCTApplicationLaunchMetric()]) {
37 | XCUIApplication().launch()
38 | }
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/watchstats Watch AppUITests/WatchStats_Watch_AppUITests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WatchStats_Watch_AppUITests.swift
3 | // WatchStats Watch AppUITests
4 | //
5 | // Created by Zach Nagengast on 12/8/23.
6 | //
7 |
8 | import XCTest
9 |
10 | final class WatchStats_Watch_AppUITests: XCTestCase {
11 |
12 | override func setUpWithError() throws {
13 | // Put setup code here. This method is called before the invocation of each test method in the class.
14 |
15 | // In UI tests it is usually best to stop immediately when a failure occurs.
16 | continueAfterFailure = false
17 |
18 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
19 | }
20 |
21 | override func tearDownWithError() throws {
22 | // Put teardown code here. This method is called after the invocation of each test method in the class.
23 | }
24 |
25 | func testExample() throws {
26 | // UI tests must launch the application that they test.
27 | let app = XCUIApplication()
28 | app.launch()
29 |
30 | // Use XCTAssert and related functions to verify your tests produce the correct results.
31 | }
32 |
33 | func testLaunchPerformance() throws {
34 | if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 7.0, *) {
35 | // This measures how long it takes to launch your application.
36 | measure(metrics: [XCTApplicationLaunchMetric()]) {
37 | XCUIApplication().launch()
38 | }
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/SystemStats.xcodeproj/xcuserdata/zachnagengast.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
9 |
21 |
22 |
23 |
25 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/SystemStats/ContentView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ContentView.swift
3 | // SystemStats
4 | //
5 | // Created by Zach Nagengast on 11/9/23.
6 | //
7 |
8 | import SwiftUI
9 | import SwiftData
10 |
11 | struct ContentView: View {
12 | @Environment(\.modelContext) private var modelContext
13 | @Query private var items: [Item]
14 |
15 | var body: some View {
16 | NavigationSplitView {
17 | List {
18 | ForEach(items) { item in
19 | NavigationLink {
20 | Text("Item at \(item.timestamp, format: Date.FormatStyle(date: .numeric, time: .standard))")
21 | } label: {
22 | Text(item.timestamp, format: Date.FormatStyle(date: .numeric, time: .standard))
23 | }
24 | }
25 | .onDelete(perform: deleteItems)
26 | }
27 | #if os(macOS)
28 | .navigationSplitViewColumnWidth(min: 180, ideal: 200)
29 | #endif
30 | .toolbar {
31 | #if os(iOS)
32 | ToolbarItem(placement: .navigationBarTrailing) {
33 | EditButton()
34 | }
35 | #endif
36 | ToolbarItem {
37 | Button(action: addItem) {
38 | Label("Add Item", systemImage: "plus")
39 | }
40 | }
41 | }
42 | } detail: {
43 | Text("Select an item")
44 | }
45 | }
46 |
47 | private func addItem() {
48 | withAnimation {
49 | let newItem = Item(timestamp: Date())
50 | modelContext.insert(newItem)
51 | }
52 | }
53 |
54 | private func deleteItems(offsets: IndexSet) {
55 | withAnimation {
56 | for index in offsets {
57 | modelContext.delete(items[index])
58 | }
59 | }
60 | }
61 | }
62 |
63 | #Preview {
64 | ContentView()
65 | .modelContainer(for: Item.self, inMemory: true)
66 | }
67 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
4 |
5 | ## User settings
6 | xcuserdata/
7 |
8 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
9 | *.xcscmblueprint
10 | *.xccheckout
11 |
12 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
13 | build/
14 | DerivedData/
15 | *.moved-aside
16 | *.pbxuser
17 | !default.pbxuser
18 | *.mode1v3
19 | !default.mode1v3
20 | *.mode2v3
21 | !default.mode2v3
22 | *.perspectivev3
23 | !default.perspectivev3
24 |
25 | ## Obj-C/Swift specific
26 | *.hmap
27 |
28 | ## App packaging
29 | *.ipa
30 | *.dSYM.zip
31 | *.dSYM
32 |
33 | ## Playgrounds
34 | timeline.xctimeline
35 | playground.xcworkspace
36 |
37 | # Swift Package Manager
38 | #
39 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
40 | # Packages/
41 | # Package.pins
42 | # Package.resolved
43 | # *.xcodeproj
44 | #
45 | # Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata
46 | # hence it is not needed unless you have added a package configuration file to your project
47 | # .swiftpm
48 |
49 | .build/
50 |
51 | # CocoaPods
52 | #
53 | # We recommend against adding the Pods directory to your .gitignore. However
54 | # you should judge for yourself, the pros and cons are mentioned at:
55 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
56 | #
57 | # Pods/
58 | #
59 | # Add this line if you want to avoid checking in source code from the Xcode workspace
60 | # *.xcworkspace
61 |
62 | # Carthage
63 | #
64 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
65 | # Carthage/Checkouts
66 |
67 | Carthage/Build/
68 |
69 | # Accio dependency management
70 | Dependencies/
71 | .accio/
72 |
73 | # fastlane
74 | #
75 | # It is recommended to not store the screenshots in the git repo.
76 | # Instead, use fastlane to re-generate the screenshots whenever they are needed.
77 | # For more information about the recommended setup visit:
78 | # https://docs.fastlane.tools/best-practices/source-control/#source-control
79 |
80 | fastlane/report.xml
81 | fastlane/Preview.html
82 | fastlane/screenshots/**/*.png
83 | fastlane/test_output
84 |
85 | # Code Injection
86 | #
87 | # After new code Injection tools there's a generated folder /iOSInjectionProject
88 | # https://github.com/johnno1962/injectionforxcode
89 |
90 | iOSInjectionProject/
91 |
--------------------------------------------------------------------------------
/SystemStats.xcodeproj/xcshareddata/xcschemes/SystemStats.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
31 |
32 |
35 |
41 |
42 |
43 |
46 |
52 |
53 |
54 |
55 |
56 |
66 |
68 |
74 |
75 |
76 |
77 |
83 |
85 |
91 |
92 |
93 |
94 |
96 |
97 |
100 |
101 |
102 |
--------------------------------------------------------------------------------
/WatchStats Watch App/ContentView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ContentView.swift
3 | // WatchStats Watch App
4 | //
5 | // Created by Zach Nagengast on 12/8/23.
6 | //
7 |
8 | import SwiftUI
9 |
10 | struct ContentView: View {
11 | @State var output: (free: UInt64, active: UInt64, inactive: UInt64, wired: UInt64, compressed: UInt64, totalUsed: UInt64, totalPhysical: UInt64, totalAvailable: UInt64) = (0, 0, 0, 0, 0, 0, 0, 0)
12 | let timer = Timer.publish(every: 1.00001, on: .main, in: .common).autoconnect()
13 |
14 | var body: some View {
15 | VStack {
16 |
17 | Section(header:
18 | HStack {
19 | Image(systemName: "memorychip")
20 | .imageScale(.large)
21 | .foregroundStyle(.tint)}
22 | ) {
23 | HStack {
24 | Text("Free")
25 | Spacer()
26 | Text(formattedBytes(output.free))
27 | }
28 | HStack {
29 | Text("Active")
30 | Spacer()
31 | Text(formattedBytes(output.active))
32 | }
33 | HStack {
34 | Text("Inactive")
35 | Spacer()
36 | Text(formattedBytes(output.inactive))
37 | }
38 | HStack {
39 | Text("Wired")
40 | Spacer()
41 | Text(formattedBytes(output.wired))
42 | }
43 | HStack {
44 | Text("Compressed")
45 | Spacer()
46 | Text(formattedBytes(output.compressed))
47 | }
48 | HStack {
49 | Text("Total Used")
50 | Spacer()
51 | Text(formattedBytes(output.totalUsed))
52 | }
53 |
54 | HStack {
55 | Text("Total Physical")
56 | Spacer()
57 | Text(formattedBytes(output.totalPhysical))
58 | }
59 |
60 | HStack {
61 | Text("Available to App")
62 | Spacer()
63 | Text(formattedBytes(output.totalAvailable))
64 | }
65 | }
66 | }
67 | .padding()
68 | .onAppear {
69 | output = getMemoryInfo()
70 | }
71 | .onReceive(timer) { _ in
72 | output = getMemoryInfo()
73 | }
74 | }
75 |
76 | private func formattedBytes(_ bytes: UInt64) -> String {
77 | let bytes = Double(bytes)
78 | let formatter = ByteCountFormatter()
79 | formatter.allowedUnits = [.useGB]
80 | formatter.countStyle = .memory
81 | formatter.includesUnit = true
82 | formatter.isAdaptive = true
83 | formatter.zeroPadsFractionDigits = true
84 |
85 | return formatter.string(fromByteCount: Int64(bytes))
86 | }
87 |
88 |
89 | }
90 |
91 | func getMemoryInfo() -> (free: UInt64, active: UInt64, inactive: UInt64, wired: UInt64, compressed: UInt64, totalUsed: UInt64, totalPhysical: UInt64, totalAvailable: UInt64) {
92 | let processInfo = ProcessInfo.processInfo
93 | let totalPhysicalMemory = processInfo.physicalMemory
94 |
95 | let availableBytes = UInt64(os_proc_available_memory())
96 |
97 | var host_size = mach_msg_type_number_t(MemoryLayout.size / MemoryLayout.stride)
98 | var host_info = vm_statistics64_data_t()
99 | let result = withUnsafeMutablePointer(to: &host_info) {
100 | $0.withMemoryRebound(to: integer_t.self, capacity: Int(host_size)) {
101 | host_statistics64(mach_host_self(), HOST_VM_INFO64, $0, &host_size)
102 | }
103 | }
104 |
105 | if result == KERN_SUCCESS {
106 | let pageSize = vm_kernel_page_size
107 |
108 | // Calculate the basic memory statistics
109 | let free = UInt64(host_info.free_count) * UInt64(pageSize)
110 | let active = UInt64(host_info.active_count) * UInt64(pageSize)
111 | let inactive = UInt64(host_info.inactive_count) * UInt64(pageSize)
112 | let wired = UInt64(host_info.wire_count) * UInt64(pageSize)
113 | let compressed = UInt64(host_info.compressor_page_count) * UInt64(pageSize)
114 | let totalUsed = active + inactive + wired + compressed
115 |
116 | return (free, active, inactive, wired, compressed, totalUsed, totalPhysicalMemory, availableBytes)
117 | } else {
118 | return (0, 0, 0, 0, 0, 0, 0, 0)
119 | }
120 | }
121 |
122 | #Preview {
123 | ContentView()
124 | }
125 |
--------------------------------------------------------------------------------
/SystemStats.xcodeproj/xcshareddata/xcschemes/WatchStats Watch App.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
29 |
35 |
36 |
37 |
38 |
39 |
45 |
46 |
49 |
55 |
56 |
57 |
60 |
66 |
67 |
68 |
69 |
70 |
80 |
82 |
88 |
89 |
90 |
91 |
97 |
99 |
105 |
106 |
107 |
108 |
110 |
111 |
114 |
115 |
116 |
--------------------------------------------------------------------------------
/SystemStats/StatisticsView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // StatisticsView.swift
3 | // SystemStats
4 | //
5 | // Created by Zach Nagengast on 11/9/23.
6 | //
7 |
8 | import SwiftUI
9 | import MachO
10 | import Combine
11 | import os
12 | import Charts
13 |
14 | struct MemoryStat: Identifiable {
15 | let id = UUID()
16 | let category: String
17 | let value: Double
18 | let timestamp: Date
19 | }
20 |
21 | struct StatisticsView: View {
22 | @State private var memoryStats: [MemoryStat] = []
23 |
24 | @State private var totalDeviceMemoryBytes: Double = 0.0
25 | @State private var physicalMemoryBytes: Double = 0.0
26 | @State private var wiredBytes: Double = 0.0
27 | @State private var freeBytes: Double = 0.0
28 | @State private var activeBytes: Double = 0.0
29 | @State private var inactiveBytes: Double = 0.0
30 | @State private var compressedBytes: Double = 0.0
31 | @State private var sumBytes: Double = 0.0
32 | @State private var appAvailableBytes: Double = 0.0
33 | @State private var appUnavailableBytes: Double = 0.0
34 |
35 | @State private var batteryLevel: Float = 0.0
36 | @State private var batteryState: UIDevice.BatteryState = .unknown
37 |
38 | @State private var cpuUsage: Double = 0.0
39 | @State private var userCPUUsage: Double = 0.0
40 | @State private var systemCPUUsage: Double = 0.0
41 | @State private var idleCPUUsage: Double = 0.0
42 | @State private var niceCPUUsage: Double = 0.0
43 | @State private var lastCPUInfo: host_cpu_load_info?
44 |
45 | @State private var activeProcessors: Int = 0
46 | @State private var totalProcessors: Int = 0
47 |
48 | @State private var totalDiskSpace: Double = 0.0
49 | @State private var usedDiskSpace: Double = 0.0
50 | @State private var freeDiskSpace: Double = 0.0
51 |
52 | @State private var thermalState: String = "Calculating..."
53 | @State private var totalUptime: String = "Calculating..."
54 | @State private var osVersion: String = "Calculating..."
55 | @State private var phoneModel: String = "Calculating..."
56 | @State private var uniqueString: String = "Calculating..."
57 | @State private var deviceType: String = "Calculating..."
58 |
59 | @State private var showTotalMemory = false
60 |
61 | let timer = Timer.publish(every: 1.00001, on: .main, in: .common).autoconnect()
62 |
63 | var body: some View {
64 | NavigationView {
65 | List {
66 | Section(header: Text("Memory Chart")) {
67 | Chart {
68 | ForEach(memoryStats, id: \.timestamp) { stat in
69 | LineMark(
70 | x: .value("Timestamp", stat.timestamp, unit: .second),
71 | y: .value("Bytes", stat.value)
72 | )
73 | .foregroundStyle(by: .value("Type", stat.category))
74 | .interpolationMethod(.cardinal)
75 | }
76 | if showTotalMemory {
77 | RuleMark(
78 | y: .value("Total", totalDeviceMemoryBytes)
79 | )
80 | .lineStyle(StrokeStyle(lineWidth: 2))
81 | .foregroundStyle(.red)
82 | }
83 | }
84 | .chartForegroundStyleScale([
85 | "Free": .green, "Active": .blue, "Inactive": .orange, "Wired": .purple, "Compressed": .red
86 | ])
87 | .chartXAxis {
88 | AxisMarks(preset: .aligned, position: .bottom)
89 | }
90 | .chartYAxis {
91 | AxisMarks(preset: .aligned, position: .trailing) { value in
92 | AxisGridLine()
93 |
94 | let bytesValue = value.as(Double.self) ?? 0.0
95 | let formattedValue = formattedBytes(bytesValue)
96 | AxisValueLabel(formattedValue)
97 | }
98 | }
99 | .frame(height: 300)
100 |
101 | Toggle("Show Total", isOn: $showTotalMemory.animation())
102 | }
103 |
104 |
105 | Section(header: Text("Memory Information")) {
106 | HStack {
107 | Text("Free")
108 | Spacer()
109 | Text(formattedBytes(freeBytes))
110 | }
111 | HStack {
112 | Text("Active")
113 | Spacer()
114 | Text(formattedBytes(activeBytes))
115 | }
116 | HStack {
117 | Text("Inactive")
118 | Spacer()
119 | Text(formattedBytes(inactiveBytes))
120 | }
121 | HStack {
122 | Text("Wired")
123 | Spacer()
124 | Text(formattedBytes(wiredBytes))
125 | }
126 | HStack {
127 | Text("Compressed")
128 | Spacer()
129 | Text(formattedBytes(compressedBytes))
130 | }
131 | HStack {
132 | Text("Sum")
133 | Spacer()
134 | Text(formattedBytes(sumBytes))
135 | }
136 | HStack {
137 | Text("Total Physical")
138 | Spacer()
139 | Text(formattedBytes(totalDeviceMemoryBytes))
140 | }
141 |
142 | HStack {
143 | Text("Available to App")
144 | Spacer()
145 | Text(formattedBytes(appAvailableBytes))
146 | }
147 |
148 | HStack {
149 | Text("Unavailable Remainder")
150 | Spacer()
151 | Text(formattedBytes(appUnavailableBytes))
152 | }
153 | }
154 |
155 | Section(header: Text("Processor Information")) {
156 | HStack {
157 | Text("CPU Usage")
158 | Spacer()
159 | Text("\(cpuUsage, specifier: "%.2f")%")
160 | }
161 |
162 | HStack {
163 | Text("- User")
164 | Spacer()
165 | Text("\(userCPUUsage, specifier: "%.2f")%")
166 | }
167 |
168 | HStack {
169 | Text("- System")
170 | Spacer()
171 | Text("\(systemCPUUsage, specifier: "%.2f")%")
172 | }
173 | HStack {
174 | Text("- Idle")
175 | Spacer()
176 | Text("\(idleCPUUsage, specifier: "%.2f")%")
177 | }
178 | HStack {
179 | Text("- Nice")
180 | Spacer()
181 | Text("\(niceCPUUsage, specifier: "%.2f")%")
182 | }
183 | HStack {
184 | Text("Active Processors")
185 | Spacer()
186 | Text("\(activeProcessors)")
187 | }
188 | }
189 |
190 | Section(header: Text("Thermal State")) {
191 | HStack {
192 | Text("Thermal State")
193 | Spacer()
194 | Text(thermalState)
195 | }
196 | }
197 |
198 | Section(header: Text("Disk Space Information")) {
199 | HStack {
200 | Text("Total Disk")
201 | Spacer()
202 | Text(formattedBytes(totalDiskSpace))
203 | }
204 |
205 | HStack {
206 | Text("Used Disk")
207 | Spacer()
208 | Text(formattedBytes(usedDiskSpace))
209 | }
210 |
211 | HStack {
212 | Text("Free Disk")
213 | Spacer()
214 | Text(formattedBytes(freeDiskSpace))
215 | }
216 | }
217 |
218 | Section(header: Text("Device Information")) {
219 | HStack {
220 | Text("Uptime")
221 | Spacer()
222 | Text(totalUptime)
223 | .scaledToFit()
224 | .minimumScaleFactor(0.5)
225 | }
226 |
227 | HStack {
228 | Text("OS")
229 | Spacer()
230 | Text(osVersion)
231 | }
232 |
233 | HStack {
234 | Text("Device Type")
235 | Spacer()
236 | Text(deviceType)
237 | }
238 |
239 | HStack {
240 | Text(uniqueString)
241 | .scaledToFit()
242 | .minimumScaleFactor(0.5)
243 | }
244 | }
245 |
246 | }
247 | .navigationTitle("System Statistics")
248 | .onAppear {
249 | updateDeviceStats()
250 | updateMemoryStats()
251 | updateCPUUsage()
252 | updateDiskUsage()
253 | updateThermalState()
254 | }
255 | .onReceive(timer) { _ in
256 | updateDeviceStats()
257 | updateMemoryStats()
258 | updateCPUUsage()
259 | updateDiskUsage()
260 | updateThermalState()
261 | }
262 | }
263 | }
264 |
265 | private func formattedBytes(_ bytes: Double) -> String {
266 | let formatter = ByteCountFormatter()
267 | formatter.allowedUnits = [.useGB]
268 | formatter.countStyle = .memory
269 | formatter.includesUnit = true
270 | formatter.isAdaptive = true
271 | formatter.zeroPadsFractionDigits = true
272 |
273 | return formatter.string(fromByteCount: Int64(bytes))
274 | }
275 |
276 |
277 | private func color(fromCategory: String) -> Color {
278 | var colorForCategory = Color.black
279 |
280 | switch fromCategory {
281 | case "Free":
282 | colorForCategory = .green
283 | case "Compressed":
284 | colorForCategory = .red
285 | case "Inactive":
286 | colorForCategory = .purple
287 | case "Wired":
288 | colorForCategory = .blue
289 | case "Active":
290 | colorForCategory = .teal
291 | default:
292 | colorForCategory = .green
293 | }
294 |
295 | // return Gradient(colors: [colorForCategory, colorForCategory.opacity(0.2)])
296 | return colorForCategory
297 | }
298 |
299 | func updateDeviceStats() {
300 | // Use the host_basic_info data
301 | let hostInfo = getHostBasicInfo()
302 | totalDeviceMemoryBytes = Double(hostInfo.max_mem)
303 |
304 | // Fetch memory pressure info
305 | let memoryInfo = getMemoryInfo()
306 | freeBytes = Double(memoryInfo.free)
307 | activeBytes = Double(memoryInfo.active)
308 | inactiveBytes = Double(memoryInfo.inactive)
309 | wiredBytes = Double(memoryInfo.wired)
310 | compressedBytes = Double(memoryInfo.compressed)
311 | sumBytes = Double(memoryInfo.totalUsed)
312 |
313 | memoryStats.append(MemoryStat(category: "Free", value: freeBytes, timestamp: Date()))
314 | memoryStats.append(MemoryStat(category: "Active", value: activeBytes, timestamp: Date()))
315 | memoryStats.append(MemoryStat(category: "Inactive", value: inactiveBytes, timestamp: Date()))
316 | memoryStats.append(MemoryStat(category: "Wired", value: wiredBytes, timestamp: Date()))
317 | memoryStats.append(MemoryStat(category: "Compressed", value: compressedBytes, timestamp: Date()))
318 |
319 | UIDevice.current.isBatteryMonitoringEnabled = true
320 | batteryLevel = UIDevice.current.batteryLevel
321 | batteryState = UIDevice.current.batteryState
322 |
323 | let uptime = ProcessInfo.processInfo.systemUptime
324 | let formatter = DateComponentsFormatter()
325 | formatter.unitsStyle = .abbreviated
326 | formatter.allowedUnits = [.day, .hour, .minute, .second]
327 |
328 | let uptimeDate = Date(timeIntervalSinceNow: -uptime)
329 | let formattedUptime = formatter.string(from: uptimeDate, to: Date()) ?? "Calculating..."
330 | totalUptime = "\(formattedUptime)"
331 |
332 | let model = UIDevice.current.localizedModel
333 | phoneModel = model
334 |
335 | let version = ProcessInfo.processInfo.operatingSystemVersionString
336 | osVersion = "\(version)"
337 |
338 | let uuid = UIDevice.current.identifierForVendor?.uuidString ?? "Unavailable"
339 | uniqueString = "\(uuid)"
340 |
341 | switch UIDevice.current.userInterfaceIdiom {
342 | case .unspecified:
343 | deviceType = "Unspecified"
344 | case .phone:
345 | deviceType = "iPhone" // iPhone and iPod touch style UI
346 | case .pad:
347 | deviceType = "iPad" // iPad style UI
348 | case .tv:
349 | deviceType = "Apple TV" // Apple TV style UI
350 | case .carPlay:
351 | deviceType = "CarPlay" // CarPlay style UI
352 | case .mac:
353 | deviceType = "Mac" // Optimized for Mac UI (e.g., Mac Catalyst)
354 | default:
355 | deviceType = "Vision"
356 | }
357 | }
358 |
359 | func batteryStateDescription(_ state: UIDevice.BatteryState) -> String {
360 | switch state {
361 | case .unplugged:
362 | return "Unplugged"
363 | case .charging:
364 | return "Charging"
365 | case .full:
366 | return "Full"
367 | case .unknown:
368 | return "Unknown"
369 | @unknown default:
370 | return "Not Available"
371 | }
372 | }
373 |
374 | private func updateMemoryStats() {
375 | let totalPhysicalMemory = ProcessInfo.processInfo.physicalMemory
376 | physicalMemoryBytes = Double(totalPhysicalMemory)
377 |
378 | let availableBytes = os_proc_available_memory()
379 | appAvailableBytes = Double(availableBytes)
380 |
381 | appUnavailableBytes = physicalMemoryBytes - appAvailableBytes
382 | }
383 |
384 | private func updateCPUUsage() {
385 | guard let newInfo = hostCPULoadInfo() else {
386 | cpuUsage = 0
387 | userCPUUsage = 0
388 | systemCPUUsage = 0
389 | idleCPUUsage = 0
390 | niceCPUUsage = 0
391 | return
392 | }
393 |
394 | if let lastInfo = lastCPUInfo {
395 | let userDiff = Double(newInfo.cpu_ticks.0 - lastInfo.cpu_ticks.0)
396 | let systemDiff = Double(newInfo.cpu_ticks.1 - lastInfo.cpu_ticks.1)
397 | let idleDiff = Double(newInfo.cpu_ticks.2 - lastInfo.cpu_ticks.2)
398 | let niceDiff = Double(newInfo.cpu_ticks.3 - lastInfo.cpu_ticks.3)
399 |
400 | let totalDiff = userDiff + systemDiff + idleDiff + niceDiff
401 | let nonIdleTicks = totalDiff - idleDiff
402 |
403 | if totalDiff > 0 {
404 | cpuUsage = (nonIdleTicks / totalDiff) * 100
405 | userCPUUsage = (userDiff / totalDiff) * 100
406 | systemCPUUsage = (systemDiff / totalDiff) * 100
407 | idleCPUUsage = (idleDiff / totalDiff) * 100
408 | niceCPUUsage = (niceDiff / totalDiff) * 100
409 | }
410 | }
411 |
412 | // Update last info for the next calculation
413 | lastCPUInfo = newInfo
414 |
415 | // Get active processor count
416 | activeProcessors = ProcessInfo.processInfo.activeProcessorCount
417 | totalProcessors = ProcessInfo.processInfo.processorCount
418 | }
419 |
420 | func hostCPULoadInfo() -> host_cpu_load_info? {
421 | let HOST_CPU_LOAD_INFO_COUNT = MemoryLayout.stride/MemoryLayout.stride
422 | var size = mach_msg_type_number_t(HOST_CPU_LOAD_INFO_COUNT)
423 | var cpuLoadInfo = host_cpu_load_info()
424 |
425 | let result = withUnsafeMutablePointer(to: &cpuLoadInfo) {
426 | $0.withMemoryRebound(to: integer_t.self, capacity: HOST_CPU_LOAD_INFO_COUNT) {
427 | host_statistics(mach_host_self(), HOST_CPU_LOAD_INFO, $0, &size)
428 | }
429 | }
430 | if result != KERN_SUCCESS{
431 | print("Error - \(#file): \(#function) - kern_result_t = \(result)")
432 | return nil
433 | }
434 | return cpuLoadInfo
435 | }
436 |
437 | func getMemoryInfo() -> (free: UInt64, active: UInt64, inactive: UInt64, wired: UInt64, compressed: UInt64, totalUsed: UInt64, physicalMemory: UInt64) {
438 | var host_size = mach_msg_type_number_t(MemoryLayout.size / MemoryLayout.stride)
439 | var host_info = vm_statistics64_data_t()
440 | let result = withUnsafeMutablePointer(to: &host_info) {
441 | $0.withMemoryRebound(to: integer_t.self, capacity: Int(host_size)) {
442 | host_statistics64(mach_host_self(), HOST_VM_INFO64, $0, &host_size)
443 | }
444 | }
445 |
446 | if result == KERN_SUCCESS {
447 | let pageSize = vm_kernel_page_size
448 |
449 | // Calculate the basic memory statistics
450 | let free = UInt64(host_info.free_count) * UInt64(pageSize)
451 | let active = UInt64(host_info.active_count) * UInt64(pageSize)
452 | let inactive = UInt64(host_info.inactive_count) * UInt64(pageSize)
453 | let wired = UInt64(host_info.wire_count) * UInt64(pageSize)
454 | let compressed = UInt64(host_info.compressor_page_count) * UInt64(pageSize)
455 | let totalUsed = active + inactive + wired + compressed
456 |
457 | // Use host_info to get physical memory size for pressure calculation
458 | let hostInfo = getHostBasicInfo() // Assume this function is implemented to fetch host_basic_info
459 | let physicalMemory = hostInfo.max_mem
460 |
461 | return (free, active, inactive, wired, compressed, totalUsed, physicalMemory)
462 | } else {
463 | return (0, 0, 0, 0, 0, 0, 0)
464 | }
465 | }
466 |
467 | func getHostBasicInfo() -> host_basic_info {
468 | var size = mach_msg_type_number_t(MemoryLayout.size / MemoryLayout.size)
469 | let hostInfo = host_basic_info_t.allocate(capacity: 1)
470 |
471 | defer {
472 | hostInfo.deallocate()
473 | }
474 |
475 | var hostInfoData = host_basic_info()
476 |
477 | let result = withUnsafeMutablePointer(to: &hostInfoData) {
478 | $0.withMemoryRebound(to: integer_t.self, capacity: Int(size)) {
479 | host_info(mach_host_self(), HOST_BASIC_INFO, $0, &size)
480 | }
481 | }
482 |
483 | if result == KERN_SUCCESS {
484 | return hostInfoData
485 | } else {
486 | // Handle error - perhaps return a default struct with zeros or nil
487 | return host_basic_info()
488 | }
489 | }
490 |
491 | private func updateDiskUsage() {
492 | let fileManager = FileManager.default
493 | do {
494 | let attributes = try fileManager.attributesOfFileSystem(forPath: NSHomeDirectory() as String)
495 | let freeSpace = attributes[.systemFreeSize] as? NSNumber
496 | let totalSpace = attributes[.systemSize] as? NSNumber
497 |
498 | if let freeSpace = freeSpace, let totalSpace = totalSpace {
499 | let freeSpaceBytes = Double(truncating: freeSpace)
500 | let totalSpaceBytes = Double(truncating: totalSpace)
501 | let usedSpaceBytes = totalSpaceBytes - freeSpaceBytes
502 |
503 | freeDiskSpace = freeSpaceBytes
504 | totalDiskSpace = totalSpaceBytes
505 | usedDiskSpace = usedSpaceBytes
506 | }
507 | } catch {
508 | freeDiskSpace = 0
509 | totalDiskSpace = 0
510 | usedDiskSpace = 0
511 | }
512 | }
513 |
514 | private func updateThermalState() {
515 | let thermalStatus = ProcessInfo.processInfo.thermalState
516 | switch thermalStatus {
517 | case .nominal:
518 | thermalState = "Nominal"
519 | case .fair:
520 | thermalState = "Fair"
521 | case .serious:
522 | thermalState = "Serious"
523 | case .critical:
524 | thermalState = "Critical"
525 | default:
526 | thermalState = "Unknown"
527 | }
528 | }
529 | }
530 |
531 |
532 | #Preview {
533 | StatisticsView()
534 | }
535 |
--------------------------------------------------------------------------------
/SystemStats.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 56;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 160B44142AFD965B00D478A8 /* SystemStatsApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 160B44132AFD965B00D478A8 /* SystemStatsApp.swift */; };
11 | 160B44162AFD965B00D478A8 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 160B44152AFD965B00D478A8 /* ContentView.swift */; };
12 | 160B44182AFD965B00D478A8 /* Item.swift in Sources */ = {isa = PBXBuildFile; fileRef = 160B44172AFD965B00D478A8 /* Item.swift */; };
13 | 160B441A2AFD965D00D478A8 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 160B44192AFD965D00D478A8 /* Assets.xcassets */; };
14 | 160B441E2AFD965D00D478A8 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 160B441D2AFD965D00D478A8 /* Preview Assets.xcassets */; };
15 | 160B44282AFD965D00D478A8 /* SystemStatsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 160B44272AFD965D00D478A8 /* SystemStatsTests.swift */; };
16 | 160B44322AFD965D00D478A8 /* SystemStatsUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 160B44312AFD965D00D478A8 /* SystemStatsUITests.swift */; };
17 | 160B44342AFD965D00D478A8 /* SystemStatsUITestsLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 160B44332AFD965D00D478A8 /* SystemStatsUITestsLaunchTests.swift */; };
18 | 160B44412AFD970B00D478A8 /* StatisticsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 160B44402AFD970B00D478A8 /* StatisticsView.swift */; };
19 | 16DEA6AD2B23EEBC009BC775 /* WatchStats Watch App.app in Embed Watch Content */ = {isa = PBXBuildFile; fileRef = 16DEA6AC2B23EEBC009BC775 /* WatchStats Watch App.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
20 | 16DEA6B22B23EEBC009BC775 /* WatchStatsApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 16DEA6B12B23EEBC009BC775 /* WatchStatsApp.swift */; };
21 | 16DEA6B42B23EEBC009BC775 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 16DEA6B32B23EEBC009BC775 /* ContentView.swift */; };
22 | 16DEA6B62B23EEBD009BC775 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 16DEA6B52B23EEBD009BC775 /* Assets.xcassets */; };
23 | 16DEA6B92B23EEBD009BC775 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 16DEA6B82B23EEBD009BC775 /* Preview Assets.xcassets */; };
24 | 16DEA6C32B23EEBE009BC775 /* WatchStats_Watch_AppTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 16DEA6C22B23EEBE009BC775 /* WatchStats_Watch_AppTests.swift */; };
25 | 16DEA6CD2B23EEBF009BC775 /* WatchStats_Watch_AppUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 16DEA6CC2B23EEBF009BC775 /* WatchStats_Watch_AppUITests.swift */; };
26 | 16DEA6CF2B23EEBF009BC775 /* WatchStats_Watch_AppUITestsLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 16DEA6CE2B23EEBF009BC775 /* WatchStats_Watch_AppUITestsLaunchTests.swift */; };
27 | /* End PBXBuildFile section */
28 |
29 | /* Begin PBXContainerItemProxy section */
30 | 160B44242AFD965D00D478A8 /* PBXContainerItemProxy */ = {
31 | isa = PBXContainerItemProxy;
32 | containerPortal = 160B44082AFD965B00D478A8 /* Project object */;
33 | proxyType = 1;
34 | remoteGlobalIDString = 160B440F2AFD965B00D478A8;
35 | remoteInfo = SystemStats;
36 | };
37 | 160B442E2AFD965D00D478A8 /* PBXContainerItemProxy */ = {
38 | isa = PBXContainerItemProxy;
39 | containerPortal = 160B44082AFD965B00D478A8 /* Project object */;
40 | proxyType = 1;
41 | remoteGlobalIDString = 160B440F2AFD965B00D478A8;
42 | remoteInfo = SystemStats;
43 | };
44 | 16DEA6AE2B23EEBC009BC775 /* PBXContainerItemProxy */ = {
45 | isa = PBXContainerItemProxy;
46 | containerPortal = 160B44082AFD965B00D478A8 /* Project object */;
47 | proxyType = 1;
48 | remoteGlobalIDString = 16DEA6AB2B23EEBC009BC775;
49 | remoteInfo = "WatchStats Watch App";
50 | };
51 | 16DEA6BF2B23EEBE009BC775 /* PBXContainerItemProxy */ = {
52 | isa = PBXContainerItemProxy;
53 | containerPortal = 160B44082AFD965B00D478A8 /* Project object */;
54 | proxyType = 1;
55 | remoteGlobalIDString = 16DEA6AB2B23EEBC009BC775;
56 | remoteInfo = "WatchStats Watch App";
57 | };
58 | 16DEA6C92B23EEBF009BC775 /* PBXContainerItemProxy */ = {
59 | isa = PBXContainerItemProxy;
60 | containerPortal = 160B44082AFD965B00D478A8 /* Project object */;
61 | proxyType = 1;
62 | remoteGlobalIDString = 16DEA6AB2B23EEBC009BC775;
63 | remoteInfo = "WatchStats Watch App";
64 | };
65 | /* End PBXContainerItemProxy section */
66 |
67 | /* Begin PBXCopyFilesBuildPhase section */
68 | 167124062B23C43400CC0F3D /* Embed Watch Content */ = {
69 | isa = PBXCopyFilesBuildPhase;
70 | buildActionMask = 2147483647;
71 | dstPath = "$(CONTENTS_FOLDER_PATH)/Watch";
72 | dstSubfolderSpec = 16;
73 | files = (
74 | );
75 | name = "Embed Watch Content";
76 | runOnlyForDeploymentPostprocessing = 0;
77 | };
78 | 16DEA6D32B23EEBF009BC775 /* Embed Watch Content */ = {
79 | isa = PBXCopyFilesBuildPhase;
80 | buildActionMask = 2147483647;
81 | dstPath = "$(CONTENTS_FOLDER_PATH)/Watch";
82 | dstSubfolderSpec = 16;
83 | files = (
84 | 16DEA6AD2B23EEBC009BC775 /* WatchStats Watch App.app in Embed Watch Content */,
85 | );
86 | name = "Embed Watch Content";
87 | runOnlyForDeploymentPostprocessing = 0;
88 | };
89 | /* End PBXCopyFilesBuildPhase section */
90 |
91 | /* Begin PBXFileReference section */
92 | 160B44102AFD965B00D478A8 /* SystemStats.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SystemStats.app; sourceTree = BUILT_PRODUCTS_DIR; };
93 | 160B44132AFD965B00D478A8 /* SystemStatsApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SystemStatsApp.swift; sourceTree = ""; };
94 | 160B44152AFD965B00D478A8 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; };
95 | 160B44172AFD965B00D478A8 /* Item.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Item.swift; sourceTree = ""; };
96 | 160B44192AFD965D00D478A8 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
97 | 160B441B2AFD965D00D478A8 /* SystemStats.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = SystemStats.entitlements; sourceTree = ""; };
98 | 160B441D2AFD965D00D478A8 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; };
99 | 160B44232AFD965D00D478A8 /* SystemStatsTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SystemStatsTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
100 | 160B44272AFD965D00D478A8 /* SystemStatsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SystemStatsTests.swift; sourceTree = ""; };
101 | 160B442D2AFD965D00D478A8 /* SystemStatsUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SystemStatsUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
102 | 160B44312AFD965D00D478A8 /* SystemStatsUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SystemStatsUITests.swift; sourceTree = ""; };
103 | 160B44332AFD965D00D478A8 /* SystemStatsUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SystemStatsUITestsLaunchTests.swift; sourceTree = ""; };
104 | 160B44402AFD970B00D478A8 /* StatisticsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatisticsView.swift; sourceTree = ""; };
105 | 16DEA6A72B23EEBB009BC775 /* WatchStats.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WatchStats.app; sourceTree = BUILT_PRODUCTS_DIR; };
106 | 16DEA6AC2B23EEBC009BC775 /* WatchStats Watch App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "WatchStats Watch App.app"; sourceTree = BUILT_PRODUCTS_DIR; };
107 | 16DEA6B12B23EEBC009BC775 /* WatchStatsApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchStatsApp.swift; sourceTree = ""; };
108 | 16DEA6B32B23EEBC009BC775 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; };
109 | 16DEA6B52B23EEBD009BC775 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
110 | 16DEA6B82B23EEBD009BC775 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; };
111 | 16DEA6BE2B23EEBE009BC775 /* WatchStats Watch AppTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "WatchStats Watch AppTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
112 | 16DEA6C22B23EEBE009BC775 /* WatchStats_Watch_AppTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchStats_Watch_AppTests.swift; sourceTree = ""; };
113 | 16DEA6C82B23EEBE009BC775 /* WatchStats Watch AppUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "WatchStats Watch AppUITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
114 | 16DEA6CC2B23EEBF009BC775 /* WatchStats_Watch_AppUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchStats_Watch_AppUITests.swift; sourceTree = ""; };
115 | 16DEA6CE2B23EEBF009BC775 /* WatchStats_Watch_AppUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchStats_Watch_AppUITestsLaunchTests.swift; sourceTree = ""; };
116 | /* End PBXFileReference section */
117 |
118 | /* Begin PBXFrameworksBuildPhase section */
119 | 160B440D2AFD965B00D478A8 /* Frameworks */ = {
120 | isa = PBXFrameworksBuildPhase;
121 | buildActionMask = 2147483647;
122 | files = (
123 | );
124 | runOnlyForDeploymentPostprocessing = 0;
125 | };
126 | 160B44202AFD965D00D478A8 /* Frameworks */ = {
127 | isa = PBXFrameworksBuildPhase;
128 | buildActionMask = 2147483647;
129 | files = (
130 | );
131 | runOnlyForDeploymentPostprocessing = 0;
132 | };
133 | 160B442A2AFD965D00D478A8 /* Frameworks */ = {
134 | isa = PBXFrameworksBuildPhase;
135 | buildActionMask = 2147483647;
136 | files = (
137 | );
138 | runOnlyForDeploymentPostprocessing = 0;
139 | };
140 | 16DEA6A92B23EEBC009BC775 /* Frameworks */ = {
141 | isa = PBXFrameworksBuildPhase;
142 | buildActionMask = 2147483647;
143 | files = (
144 | );
145 | runOnlyForDeploymentPostprocessing = 0;
146 | };
147 | 16DEA6BB2B23EEBD009BC775 /* Frameworks */ = {
148 | isa = PBXFrameworksBuildPhase;
149 | buildActionMask = 2147483647;
150 | files = (
151 | );
152 | runOnlyForDeploymentPostprocessing = 0;
153 | };
154 | 16DEA6C52B23EEBE009BC775 /* Frameworks */ = {
155 | isa = PBXFrameworksBuildPhase;
156 | buildActionMask = 2147483647;
157 | files = (
158 | );
159 | runOnlyForDeploymentPostprocessing = 0;
160 | };
161 | /* End PBXFrameworksBuildPhase section */
162 |
163 | /* Begin PBXGroup section */
164 | 160B44072AFD965B00D478A8 = {
165 | isa = PBXGroup;
166 | children = (
167 | 160B44122AFD965B00D478A8 /* SystemStats */,
168 | 160B44262AFD965D00D478A8 /* SystemStatsTests */,
169 | 160B44302AFD965D00D478A8 /* SystemStatsUITests */,
170 | 16DEA6B02B23EEBC009BC775 /* WatchStats Watch App */,
171 | 16DEA6C12B23EEBE009BC775 /* WatchStats Watch AppTests */,
172 | 16DEA6CB2B23EEBF009BC775 /* WatchStats Watch AppUITests */,
173 | 160B44112AFD965B00D478A8 /* Products */,
174 | );
175 | sourceTree = "";
176 | };
177 | 160B44112AFD965B00D478A8 /* Products */ = {
178 | isa = PBXGroup;
179 | children = (
180 | 160B44102AFD965B00D478A8 /* SystemStats.app */,
181 | 160B44232AFD965D00D478A8 /* SystemStatsTests.xctest */,
182 | 160B442D2AFD965D00D478A8 /* SystemStatsUITests.xctest */,
183 | 16DEA6A72B23EEBB009BC775 /* WatchStats.app */,
184 | 16DEA6AC2B23EEBC009BC775 /* WatchStats Watch App.app */,
185 | 16DEA6BE2B23EEBE009BC775 /* WatchStats Watch AppTests.xctest */,
186 | 16DEA6C82B23EEBE009BC775 /* WatchStats Watch AppUITests.xctest */,
187 | );
188 | name = Products;
189 | sourceTree = "";
190 | };
191 | 160B44122AFD965B00D478A8 /* SystemStats */ = {
192 | isa = PBXGroup;
193 | children = (
194 | 160B44132AFD965B00D478A8 /* SystemStatsApp.swift */,
195 | 160B44152AFD965B00D478A8 /* ContentView.swift */,
196 | 160B44402AFD970B00D478A8 /* StatisticsView.swift */,
197 | 160B44172AFD965B00D478A8 /* Item.swift */,
198 | 160B44192AFD965D00D478A8 /* Assets.xcassets */,
199 | 160B441B2AFD965D00D478A8 /* SystemStats.entitlements */,
200 | 160B441C2AFD965D00D478A8 /* Preview Content */,
201 | );
202 | path = SystemStats;
203 | sourceTree = "";
204 | };
205 | 160B441C2AFD965D00D478A8 /* Preview Content */ = {
206 | isa = PBXGroup;
207 | children = (
208 | 160B441D2AFD965D00D478A8 /* Preview Assets.xcassets */,
209 | );
210 | path = "Preview Content";
211 | sourceTree = "";
212 | };
213 | 160B44262AFD965D00D478A8 /* SystemStatsTests */ = {
214 | isa = PBXGroup;
215 | children = (
216 | 160B44272AFD965D00D478A8 /* SystemStatsTests.swift */,
217 | );
218 | path = SystemStatsTests;
219 | sourceTree = "";
220 | };
221 | 160B44302AFD965D00D478A8 /* SystemStatsUITests */ = {
222 | isa = PBXGroup;
223 | children = (
224 | 160B44312AFD965D00D478A8 /* SystemStatsUITests.swift */,
225 | 160B44332AFD965D00D478A8 /* SystemStatsUITestsLaunchTests.swift */,
226 | );
227 | path = SystemStatsUITests;
228 | sourceTree = "";
229 | };
230 | 16DEA6B02B23EEBC009BC775 /* WatchStats Watch App */ = {
231 | isa = PBXGroup;
232 | children = (
233 | 16DEA6B12B23EEBC009BC775 /* WatchStatsApp.swift */,
234 | 16DEA6B32B23EEBC009BC775 /* ContentView.swift */,
235 | 16DEA6B52B23EEBD009BC775 /* Assets.xcassets */,
236 | 16DEA6B72B23EEBD009BC775 /* Preview Content */,
237 | );
238 | path = "WatchStats Watch App";
239 | sourceTree = "";
240 | };
241 | 16DEA6B72B23EEBD009BC775 /* Preview Content */ = {
242 | isa = PBXGroup;
243 | children = (
244 | 16DEA6B82B23EEBD009BC775 /* Preview Assets.xcassets */,
245 | );
246 | path = "Preview Content";
247 | sourceTree = "";
248 | };
249 | 16DEA6C12B23EEBE009BC775 /* WatchStats Watch AppTests */ = {
250 | isa = PBXGroup;
251 | children = (
252 | 16DEA6C22B23EEBE009BC775 /* WatchStats_Watch_AppTests.swift */,
253 | );
254 | path = "WatchStats Watch AppTests";
255 | sourceTree = "";
256 | };
257 | 16DEA6CB2B23EEBF009BC775 /* WatchStats Watch AppUITests */ = {
258 | isa = PBXGroup;
259 | children = (
260 | 16DEA6CC2B23EEBF009BC775 /* WatchStats_Watch_AppUITests.swift */,
261 | 16DEA6CE2B23EEBF009BC775 /* WatchStats_Watch_AppUITestsLaunchTests.swift */,
262 | );
263 | path = "WatchStats Watch AppUITests";
264 | sourceTree = "";
265 | };
266 | /* End PBXGroup section */
267 |
268 | /* Begin PBXNativeTarget section */
269 | 160B440F2AFD965B00D478A8 /* SystemStats */ = {
270 | isa = PBXNativeTarget;
271 | buildConfigurationList = 160B44372AFD965D00D478A8 /* Build configuration list for PBXNativeTarget "SystemStats" */;
272 | buildPhases = (
273 | 160B440C2AFD965B00D478A8 /* Sources */,
274 | 160B440D2AFD965B00D478A8 /* Frameworks */,
275 | 160B440E2AFD965B00D478A8 /* Resources */,
276 | 167124062B23C43400CC0F3D /* Embed Watch Content */,
277 | );
278 | buildRules = (
279 | );
280 | dependencies = (
281 | );
282 | name = SystemStats;
283 | productName = SystemStats;
284 | productReference = 160B44102AFD965B00D478A8 /* SystemStats.app */;
285 | productType = "com.apple.product-type.application";
286 | };
287 | 160B44222AFD965D00D478A8 /* SystemStatsTests */ = {
288 | isa = PBXNativeTarget;
289 | buildConfigurationList = 160B443A2AFD965D00D478A8 /* Build configuration list for PBXNativeTarget "SystemStatsTests" */;
290 | buildPhases = (
291 | 160B441F2AFD965D00D478A8 /* Sources */,
292 | 160B44202AFD965D00D478A8 /* Frameworks */,
293 | 160B44212AFD965D00D478A8 /* Resources */,
294 | );
295 | buildRules = (
296 | );
297 | dependencies = (
298 | 160B44252AFD965D00D478A8 /* PBXTargetDependency */,
299 | );
300 | name = SystemStatsTests;
301 | productName = SystemStatsTests;
302 | productReference = 160B44232AFD965D00D478A8 /* SystemStatsTests.xctest */;
303 | productType = "com.apple.product-type.bundle.unit-test";
304 | };
305 | 160B442C2AFD965D00D478A8 /* SystemStatsUITests */ = {
306 | isa = PBXNativeTarget;
307 | buildConfigurationList = 160B443D2AFD965D00D478A8 /* Build configuration list for PBXNativeTarget "SystemStatsUITests" */;
308 | buildPhases = (
309 | 160B44292AFD965D00D478A8 /* Sources */,
310 | 160B442A2AFD965D00D478A8 /* Frameworks */,
311 | 160B442B2AFD965D00D478A8 /* Resources */,
312 | );
313 | buildRules = (
314 | );
315 | dependencies = (
316 | 160B442F2AFD965D00D478A8 /* PBXTargetDependency */,
317 | );
318 | name = SystemStatsUITests;
319 | productName = SystemStatsUITests;
320 | productReference = 160B442D2AFD965D00D478A8 /* SystemStatsUITests.xctest */;
321 | productType = "com.apple.product-type.bundle.ui-testing";
322 | };
323 | 16DEA6A62B23EEBB009BC775 /* WatchStats */ = {
324 | isa = PBXNativeTarget;
325 | buildConfigurationList = 16DEA6D42B23EEBF009BC775 /* Build configuration list for PBXNativeTarget "WatchStats" */;
326 | buildPhases = (
327 | 16DEA6A52B23EEBB009BC775 /* Resources */,
328 | 16DEA6D32B23EEBF009BC775 /* Embed Watch Content */,
329 | );
330 | buildRules = (
331 | );
332 | dependencies = (
333 | 16DEA6AF2B23EEBC009BC775 /* PBXTargetDependency */,
334 | );
335 | name = WatchStats;
336 | productName = WatchStats;
337 | productReference = 16DEA6A72B23EEBB009BC775 /* WatchStats.app */;
338 | productType = "com.apple.product-type.application.watchapp2-container";
339 | };
340 | 16DEA6AB2B23EEBC009BC775 /* WatchStats Watch App */ = {
341 | isa = PBXNativeTarget;
342 | buildConfigurationList = 16DEA6D02B23EEBF009BC775 /* Build configuration list for PBXNativeTarget "WatchStats Watch App" */;
343 | buildPhases = (
344 | 16DEA6A82B23EEBC009BC775 /* Sources */,
345 | 16DEA6A92B23EEBC009BC775 /* Frameworks */,
346 | 16DEA6AA2B23EEBC009BC775 /* Resources */,
347 | );
348 | buildRules = (
349 | );
350 | dependencies = (
351 | );
352 | name = "WatchStats Watch App";
353 | productName = "WatchStats Watch App";
354 | productReference = 16DEA6AC2B23EEBC009BC775 /* WatchStats Watch App.app */;
355 | productType = "com.apple.product-type.application";
356 | };
357 | 16DEA6BD2B23EEBD009BC775 /* WatchStats Watch AppTests */ = {
358 | isa = PBXNativeTarget;
359 | buildConfigurationList = 16DEA6D72B23EEBF009BC775 /* Build configuration list for PBXNativeTarget "WatchStats Watch AppTests" */;
360 | buildPhases = (
361 | 16DEA6BA2B23EEBD009BC775 /* Sources */,
362 | 16DEA6BB2B23EEBD009BC775 /* Frameworks */,
363 | 16DEA6BC2B23EEBD009BC775 /* Resources */,
364 | );
365 | buildRules = (
366 | );
367 | dependencies = (
368 | 16DEA6C02B23EEBE009BC775 /* PBXTargetDependency */,
369 | );
370 | name = "WatchStats Watch AppTests";
371 | productName = "WatchStats Watch AppTests";
372 | productReference = 16DEA6BE2B23EEBE009BC775 /* WatchStats Watch AppTests.xctest */;
373 | productType = "com.apple.product-type.bundle.unit-test";
374 | };
375 | 16DEA6C72B23EEBE009BC775 /* WatchStats Watch AppUITests */ = {
376 | isa = PBXNativeTarget;
377 | buildConfigurationList = 16DEA6DA2B23EEBF009BC775 /* Build configuration list for PBXNativeTarget "WatchStats Watch AppUITests" */;
378 | buildPhases = (
379 | 16DEA6C42B23EEBE009BC775 /* Sources */,
380 | 16DEA6C52B23EEBE009BC775 /* Frameworks */,
381 | 16DEA6C62B23EEBE009BC775 /* Resources */,
382 | );
383 | buildRules = (
384 | );
385 | dependencies = (
386 | 16DEA6CA2B23EEBF009BC775 /* PBXTargetDependency */,
387 | );
388 | name = "WatchStats Watch AppUITests";
389 | productName = "WatchStats Watch AppUITests";
390 | productReference = 16DEA6C82B23EEBE009BC775 /* WatchStats Watch AppUITests.xctest */;
391 | productType = "com.apple.product-type.bundle.ui-testing";
392 | };
393 | /* End PBXNativeTarget section */
394 |
395 | /* Begin PBXProject section */
396 | 160B44082AFD965B00D478A8 /* Project object */ = {
397 | isa = PBXProject;
398 | attributes = {
399 | BuildIndependentTargetsInParallel = 1;
400 | LastSwiftUpdateCheck = 1500;
401 | LastUpgradeCheck = 1500;
402 | TargetAttributes = {
403 | 160B440F2AFD965B00D478A8 = {
404 | CreatedOnToolsVersion = 15.0.1;
405 | };
406 | 160B44222AFD965D00D478A8 = {
407 | CreatedOnToolsVersion = 15.0.1;
408 | TestTargetID = 160B440F2AFD965B00D478A8;
409 | };
410 | 160B442C2AFD965D00D478A8 = {
411 | CreatedOnToolsVersion = 15.0.1;
412 | TestTargetID = 160B440F2AFD965B00D478A8;
413 | };
414 | 16DEA6A62B23EEBB009BC775 = {
415 | CreatedOnToolsVersion = 15.0.1;
416 | };
417 | 16DEA6AB2B23EEBC009BC775 = {
418 | CreatedOnToolsVersion = 15.0.1;
419 | };
420 | 16DEA6BD2B23EEBD009BC775 = {
421 | CreatedOnToolsVersion = 15.0.1;
422 | TestTargetID = 16DEA6AB2B23EEBC009BC775;
423 | };
424 | 16DEA6C72B23EEBE009BC775 = {
425 | CreatedOnToolsVersion = 15.0.1;
426 | TestTargetID = 16DEA6AB2B23EEBC009BC775;
427 | };
428 | };
429 | };
430 | buildConfigurationList = 160B440B2AFD965B00D478A8 /* Build configuration list for PBXProject "SystemStats" */;
431 | compatibilityVersion = "Xcode 14.0";
432 | developmentRegion = en;
433 | hasScannedForEncodings = 0;
434 | knownRegions = (
435 | en,
436 | Base,
437 | );
438 | mainGroup = 160B44072AFD965B00D478A8;
439 | productRefGroup = 160B44112AFD965B00D478A8 /* Products */;
440 | projectDirPath = "";
441 | projectRoot = "";
442 | targets = (
443 | 160B440F2AFD965B00D478A8 /* SystemStats */,
444 | 160B44222AFD965D00D478A8 /* SystemStatsTests */,
445 | 160B442C2AFD965D00D478A8 /* SystemStatsUITests */,
446 | 16DEA6A62B23EEBB009BC775 /* WatchStats */,
447 | 16DEA6AB2B23EEBC009BC775 /* WatchStats Watch App */,
448 | 16DEA6BD2B23EEBD009BC775 /* WatchStats Watch AppTests */,
449 | 16DEA6C72B23EEBE009BC775 /* WatchStats Watch AppUITests */,
450 | );
451 | };
452 | /* End PBXProject section */
453 |
454 | /* Begin PBXResourcesBuildPhase section */
455 | 160B440E2AFD965B00D478A8 /* Resources */ = {
456 | isa = PBXResourcesBuildPhase;
457 | buildActionMask = 2147483647;
458 | files = (
459 | 160B441E2AFD965D00D478A8 /* Preview Assets.xcassets in Resources */,
460 | 160B441A2AFD965D00D478A8 /* Assets.xcassets in Resources */,
461 | );
462 | runOnlyForDeploymentPostprocessing = 0;
463 | };
464 | 160B44212AFD965D00D478A8 /* Resources */ = {
465 | isa = PBXResourcesBuildPhase;
466 | buildActionMask = 2147483647;
467 | files = (
468 | );
469 | runOnlyForDeploymentPostprocessing = 0;
470 | };
471 | 160B442B2AFD965D00D478A8 /* Resources */ = {
472 | isa = PBXResourcesBuildPhase;
473 | buildActionMask = 2147483647;
474 | files = (
475 | );
476 | runOnlyForDeploymentPostprocessing = 0;
477 | };
478 | 16DEA6A52B23EEBB009BC775 /* Resources */ = {
479 | isa = PBXResourcesBuildPhase;
480 | buildActionMask = 2147483647;
481 | files = (
482 | );
483 | runOnlyForDeploymentPostprocessing = 0;
484 | };
485 | 16DEA6AA2B23EEBC009BC775 /* Resources */ = {
486 | isa = PBXResourcesBuildPhase;
487 | buildActionMask = 2147483647;
488 | files = (
489 | 16DEA6B92B23EEBD009BC775 /* Preview Assets.xcassets in Resources */,
490 | 16DEA6B62B23EEBD009BC775 /* Assets.xcassets in Resources */,
491 | );
492 | runOnlyForDeploymentPostprocessing = 0;
493 | };
494 | 16DEA6BC2B23EEBD009BC775 /* Resources */ = {
495 | isa = PBXResourcesBuildPhase;
496 | buildActionMask = 2147483647;
497 | files = (
498 | );
499 | runOnlyForDeploymentPostprocessing = 0;
500 | };
501 | 16DEA6C62B23EEBE009BC775 /* Resources */ = {
502 | isa = PBXResourcesBuildPhase;
503 | buildActionMask = 2147483647;
504 | files = (
505 | );
506 | runOnlyForDeploymentPostprocessing = 0;
507 | };
508 | /* End PBXResourcesBuildPhase section */
509 |
510 | /* Begin PBXSourcesBuildPhase section */
511 | 160B440C2AFD965B00D478A8 /* Sources */ = {
512 | isa = PBXSourcesBuildPhase;
513 | buildActionMask = 2147483647;
514 | files = (
515 | 160B44162AFD965B00D478A8 /* ContentView.swift in Sources */,
516 | 160B44182AFD965B00D478A8 /* Item.swift in Sources */,
517 | 160B44142AFD965B00D478A8 /* SystemStatsApp.swift in Sources */,
518 | 160B44412AFD970B00D478A8 /* StatisticsView.swift in Sources */,
519 | );
520 | runOnlyForDeploymentPostprocessing = 0;
521 | };
522 | 160B441F2AFD965D00D478A8 /* Sources */ = {
523 | isa = PBXSourcesBuildPhase;
524 | buildActionMask = 2147483647;
525 | files = (
526 | 160B44282AFD965D00D478A8 /* SystemStatsTests.swift in Sources */,
527 | );
528 | runOnlyForDeploymentPostprocessing = 0;
529 | };
530 | 160B44292AFD965D00D478A8 /* Sources */ = {
531 | isa = PBXSourcesBuildPhase;
532 | buildActionMask = 2147483647;
533 | files = (
534 | 160B44322AFD965D00D478A8 /* SystemStatsUITests.swift in Sources */,
535 | 160B44342AFD965D00D478A8 /* SystemStatsUITestsLaunchTests.swift in Sources */,
536 | );
537 | runOnlyForDeploymentPostprocessing = 0;
538 | };
539 | 16DEA6A82B23EEBC009BC775 /* Sources */ = {
540 | isa = PBXSourcesBuildPhase;
541 | buildActionMask = 2147483647;
542 | files = (
543 | 16DEA6B42B23EEBC009BC775 /* ContentView.swift in Sources */,
544 | 16DEA6B22B23EEBC009BC775 /* WatchStatsApp.swift in Sources */,
545 | );
546 | runOnlyForDeploymentPostprocessing = 0;
547 | };
548 | 16DEA6BA2B23EEBD009BC775 /* Sources */ = {
549 | isa = PBXSourcesBuildPhase;
550 | buildActionMask = 2147483647;
551 | files = (
552 | 16DEA6C32B23EEBE009BC775 /* WatchStats_Watch_AppTests.swift in Sources */,
553 | );
554 | runOnlyForDeploymentPostprocessing = 0;
555 | };
556 | 16DEA6C42B23EEBE009BC775 /* Sources */ = {
557 | isa = PBXSourcesBuildPhase;
558 | buildActionMask = 2147483647;
559 | files = (
560 | 16DEA6CF2B23EEBF009BC775 /* WatchStats_Watch_AppUITestsLaunchTests.swift in Sources */,
561 | 16DEA6CD2B23EEBF009BC775 /* WatchStats_Watch_AppUITests.swift in Sources */,
562 | );
563 | runOnlyForDeploymentPostprocessing = 0;
564 | };
565 | /* End PBXSourcesBuildPhase section */
566 |
567 | /* Begin PBXTargetDependency section */
568 | 160B44252AFD965D00D478A8 /* PBXTargetDependency */ = {
569 | isa = PBXTargetDependency;
570 | target = 160B440F2AFD965B00D478A8 /* SystemStats */;
571 | targetProxy = 160B44242AFD965D00D478A8 /* PBXContainerItemProxy */;
572 | };
573 | 160B442F2AFD965D00D478A8 /* PBXTargetDependency */ = {
574 | isa = PBXTargetDependency;
575 | target = 160B440F2AFD965B00D478A8 /* SystemStats */;
576 | targetProxy = 160B442E2AFD965D00D478A8 /* PBXContainerItemProxy */;
577 | };
578 | 16DEA6AF2B23EEBC009BC775 /* PBXTargetDependency */ = {
579 | isa = PBXTargetDependency;
580 | target = 16DEA6AB2B23EEBC009BC775 /* WatchStats Watch App */;
581 | targetProxy = 16DEA6AE2B23EEBC009BC775 /* PBXContainerItemProxy */;
582 | };
583 | 16DEA6C02B23EEBE009BC775 /* PBXTargetDependency */ = {
584 | isa = PBXTargetDependency;
585 | target = 16DEA6AB2B23EEBC009BC775 /* WatchStats Watch App */;
586 | targetProxy = 16DEA6BF2B23EEBE009BC775 /* PBXContainerItemProxy */;
587 | };
588 | 16DEA6CA2B23EEBF009BC775 /* PBXTargetDependency */ = {
589 | isa = PBXTargetDependency;
590 | target = 16DEA6AB2B23EEBC009BC775 /* WatchStats Watch App */;
591 | targetProxy = 16DEA6C92B23EEBF009BC775 /* PBXContainerItemProxy */;
592 | };
593 | /* End PBXTargetDependency section */
594 |
595 | /* Begin XCBuildConfiguration section */
596 | 160B44352AFD965D00D478A8 /* Debug */ = {
597 | isa = XCBuildConfiguration;
598 | buildSettings = {
599 | ALWAYS_SEARCH_USER_PATHS = NO;
600 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
601 | CLANG_ANALYZER_NONNULL = YES;
602 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
603 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
604 | CLANG_ENABLE_MODULES = YES;
605 | CLANG_ENABLE_OBJC_ARC = YES;
606 | CLANG_ENABLE_OBJC_WEAK = YES;
607 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
608 | CLANG_WARN_BOOL_CONVERSION = YES;
609 | CLANG_WARN_COMMA = YES;
610 | CLANG_WARN_CONSTANT_CONVERSION = YES;
611 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
612 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
613 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
614 | CLANG_WARN_EMPTY_BODY = YES;
615 | CLANG_WARN_ENUM_CONVERSION = YES;
616 | CLANG_WARN_INFINITE_RECURSION = YES;
617 | CLANG_WARN_INT_CONVERSION = YES;
618 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
619 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
620 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
621 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
622 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
623 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
624 | CLANG_WARN_STRICT_PROTOTYPES = YES;
625 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
626 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
627 | CLANG_WARN_UNREACHABLE_CODE = YES;
628 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
629 | COPY_PHASE_STRIP = NO;
630 | DEBUG_INFORMATION_FORMAT = dwarf;
631 | ENABLE_STRICT_OBJC_MSGSEND = YES;
632 | ENABLE_TESTABILITY = YES;
633 | ENABLE_USER_SCRIPT_SANDBOXING = YES;
634 | GCC_C_LANGUAGE_STANDARD = gnu17;
635 | GCC_DYNAMIC_NO_PIC = NO;
636 | GCC_NO_COMMON_BLOCKS = YES;
637 | GCC_OPTIMIZATION_LEVEL = 0;
638 | GCC_PREPROCESSOR_DEFINITIONS = (
639 | "DEBUG=1",
640 | "$(inherited)",
641 | );
642 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
643 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
644 | GCC_WARN_UNDECLARED_SELECTOR = YES;
645 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
646 | GCC_WARN_UNUSED_FUNCTION = YES;
647 | GCC_WARN_UNUSED_VARIABLE = YES;
648 | LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
649 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
650 | MTL_FAST_MATH = YES;
651 | ONLY_ACTIVE_ARCH = YES;
652 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
653 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
654 | };
655 | name = Debug;
656 | };
657 | 160B44362AFD965D00D478A8 /* Release */ = {
658 | isa = XCBuildConfiguration;
659 | buildSettings = {
660 | ALWAYS_SEARCH_USER_PATHS = NO;
661 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
662 | CLANG_ANALYZER_NONNULL = YES;
663 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
664 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
665 | CLANG_ENABLE_MODULES = YES;
666 | CLANG_ENABLE_OBJC_ARC = YES;
667 | CLANG_ENABLE_OBJC_WEAK = YES;
668 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
669 | CLANG_WARN_BOOL_CONVERSION = YES;
670 | CLANG_WARN_COMMA = YES;
671 | CLANG_WARN_CONSTANT_CONVERSION = YES;
672 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
673 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
674 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
675 | CLANG_WARN_EMPTY_BODY = YES;
676 | CLANG_WARN_ENUM_CONVERSION = YES;
677 | CLANG_WARN_INFINITE_RECURSION = YES;
678 | CLANG_WARN_INT_CONVERSION = YES;
679 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
680 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
681 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
682 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
683 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
684 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
685 | CLANG_WARN_STRICT_PROTOTYPES = YES;
686 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
687 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
688 | CLANG_WARN_UNREACHABLE_CODE = YES;
689 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
690 | COPY_PHASE_STRIP = NO;
691 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
692 | ENABLE_NS_ASSERTIONS = NO;
693 | ENABLE_STRICT_OBJC_MSGSEND = YES;
694 | ENABLE_USER_SCRIPT_SANDBOXING = YES;
695 | GCC_C_LANGUAGE_STANDARD = gnu17;
696 | GCC_NO_COMMON_BLOCKS = YES;
697 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
698 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
699 | GCC_WARN_UNDECLARED_SELECTOR = YES;
700 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
701 | GCC_WARN_UNUSED_FUNCTION = YES;
702 | GCC_WARN_UNUSED_VARIABLE = YES;
703 | LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
704 | MTL_ENABLE_DEBUG_INFO = NO;
705 | MTL_FAST_MATH = YES;
706 | SWIFT_COMPILATION_MODE = wholemodule;
707 | };
708 | name = Release;
709 | };
710 | 160B44382AFD965D00D478A8 /* Debug */ = {
711 | isa = XCBuildConfiguration;
712 | buildSettings = {
713 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
714 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
715 | CODE_SIGN_ENTITLEMENTS = SystemStats/SystemStats.entitlements;
716 | CODE_SIGN_STYLE = Automatic;
717 | CURRENT_PROJECT_VERSION = 1;
718 | DEVELOPMENT_ASSET_PATHS = "\"SystemStats/Preview Content\"";
719 | DEVELOPMENT_TEAM = JSGZDY54HP;
720 | ENABLE_HARDENED_RUNTIME = YES;
721 | ENABLE_PREVIEWS = YES;
722 | GENERATE_INFOPLIST_FILE = YES;
723 | INFOPLIST_KEY_CFBundleDisplayName = "System Stats";
724 | "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
725 | "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES;
726 | "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES;
727 | "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphonesimulator*]" = YES;
728 | "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphoneos*]" = YES;
729 | "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphonesimulator*]" = YES;
730 | "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphoneos*]" = UIStatusBarStyleDefault;
731 | "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphonesimulator*]" = UIStatusBarStyleDefault;
732 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
733 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
734 | IPHONEOS_DEPLOYMENT_TARGET = 17.0;
735 | LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
736 | "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
737 | MACOSX_DEPLOYMENT_TARGET = 14.0;
738 | MARKETING_VERSION = 1.0;
739 | PRODUCT_BUNDLE_IDENTIFIER = com.argmax.systemstats;
740 | PRODUCT_NAME = "$(TARGET_NAME)";
741 | SDKROOT = auto;
742 | SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx";
743 | SWIFT_EMIT_LOC_STRINGS = YES;
744 | SWIFT_VERSION = 5.0;
745 | TARGETED_DEVICE_FAMILY = "1,2";
746 | };
747 | name = Debug;
748 | };
749 | 160B44392AFD965D00D478A8 /* Release */ = {
750 | isa = XCBuildConfiguration;
751 | buildSettings = {
752 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
753 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
754 | CODE_SIGN_ENTITLEMENTS = SystemStats/SystemStats.entitlements;
755 | CODE_SIGN_STYLE = Automatic;
756 | CURRENT_PROJECT_VERSION = 1;
757 | DEVELOPMENT_ASSET_PATHS = "\"SystemStats/Preview Content\"";
758 | DEVELOPMENT_TEAM = JSGZDY54HP;
759 | ENABLE_HARDENED_RUNTIME = YES;
760 | ENABLE_PREVIEWS = YES;
761 | GENERATE_INFOPLIST_FILE = YES;
762 | INFOPLIST_KEY_CFBundleDisplayName = "System Stats";
763 | "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
764 | "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES;
765 | "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES;
766 | "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphonesimulator*]" = YES;
767 | "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphoneos*]" = YES;
768 | "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphonesimulator*]" = YES;
769 | "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphoneos*]" = UIStatusBarStyleDefault;
770 | "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphonesimulator*]" = UIStatusBarStyleDefault;
771 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
772 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
773 | IPHONEOS_DEPLOYMENT_TARGET = 17.0;
774 | LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
775 | "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
776 | MACOSX_DEPLOYMENT_TARGET = 14.0;
777 | MARKETING_VERSION = 1.0;
778 | PRODUCT_BUNDLE_IDENTIFIER = com.argmax.systemstats;
779 | PRODUCT_NAME = "$(TARGET_NAME)";
780 | SDKROOT = auto;
781 | SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx";
782 | SWIFT_EMIT_LOC_STRINGS = YES;
783 | SWIFT_VERSION = 5.0;
784 | TARGETED_DEVICE_FAMILY = "1,2";
785 | };
786 | name = Release;
787 | };
788 | 160B443B2AFD965D00D478A8 /* Debug */ = {
789 | isa = XCBuildConfiguration;
790 | buildSettings = {
791 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
792 | BUNDLE_LOADER = "$(TEST_HOST)";
793 | CODE_SIGN_STYLE = Automatic;
794 | CURRENT_PROJECT_VERSION = 1;
795 | DEVELOPMENT_TEAM = JSGZDY54HP;
796 | GENERATE_INFOPLIST_FILE = YES;
797 | IPHONEOS_DEPLOYMENT_TARGET = 17.0;
798 | MACOSX_DEPLOYMENT_TARGET = 14.0;
799 | MARKETING_VERSION = 1.0;
800 | PRODUCT_BUNDLE_IDENTIFIER = com.argmax.SystemStatsTests;
801 | PRODUCT_NAME = "$(TARGET_NAME)";
802 | SDKROOT = auto;
803 | SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx";
804 | SWIFT_EMIT_LOC_STRINGS = NO;
805 | SWIFT_VERSION = 5.0;
806 | TARGETED_DEVICE_FAMILY = "1,2";
807 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SystemStats.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/SystemStats";
808 | };
809 | name = Debug;
810 | };
811 | 160B443C2AFD965D00D478A8 /* Release */ = {
812 | isa = XCBuildConfiguration;
813 | buildSettings = {
814 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
815 | BUNDLE_LOADER = "$(TEST_HOST)";
816 | CODE_SIGN_STYLE = Automatic;
817 | CURRENT_PROJECT_VERSION = 1;
818 | DEVELOPMENT_TEAM = JSGZDY54HP;
819 | GENERATE_INFOPLIST_FILE = YES;
820 | IPHONEOS_DEPLOYMENT_TARGET = 17.0;
821 | MACOSX_DEPLOYMENT_TARGET = 14.0;
822 | MARKETING_VERSION = 1.0;
823 | PRODUCT_BUNDLE_IDENTIFIER = com.argmax.SystemStatsTests;
824 | PRODUCT_NAME = "$(TARGET_NAME)";
825 | SDKROOT = auto;
826 | SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx";
827 | SWIFT_EMIT_LOC_STRINGS = NO;
828 | SWIFT_VERSION = 5.0;
829 | TARGETED_DEVICE_FAMILY = "1,2";
830 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SystemStats.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/SystemStats";
831 | };
832 | name = Release;
833 | };
834 | 160B443E2AFD965D00D478A8 /* Debug */ = {
835 | isa = XCBuildConfiguration;
836 | buildSettings = {
837 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
838 | CODE_SIGN_STYLE = Automatic;
839 | CURRENT_PROJECT_VERSION = 1;
840 | DEVELOPMENT_TEAM = JSGZDY54HP;
841 | GENERATE_INFOPLIST_FILE = YES;
842 | IPHONEOS_DEPLOYMENT_TARGET = 17.0;
843 | MACOSX_DEPLOYMENT_TARGET = 14.0;
844 | MARKETING_VERSION = 1.0;
845 | PRODUCT_BUNDLE_IDENTIFIER = com.argmax.SystemStatsUITests;
846 | PRODUCT_NAME = "$(TARGET_NAME)";
847 | SDKROOT = auto;
848 | SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx";
849 | SWIFT_EMIT_LOC_STRINGS = NO;
850 | SWIFT_VERSION = 5.0;
851 | TARGETED_DEVICE_FAMILY = "1,2";
852 | TEST_TARGET_NAME = SystemStats;
853 | };
854 | name = Debug;
855 | };
856 | 160B443F2AFD965D00D478A8 /* Release */ = {
857 | isa = XCBuildConfiguration;
858 | buildSettings = {
859 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
860 | CODE_SIGN_STYLE = Automatic;
861 | CURRENT_PROJECT_VERSION = 1;
862 | DEVELOPMENT_TEAM = JSGZDY54HP;
863 | GENERATE_INFOPLIST_FILE = YES;
864 | IPHONEOS_DEPLOYMENT_TARGET = 17.0;
865 | MACOSX_DEPLOYMENT_TARGET = 14.0;
866 | MARKETING_VERSION = 1.0;
867 | PRODUCT_BUNDLE_IDENTIFIER = com.argmax.SystemStatsUITests;
868 | PRODUCT_NAME = "$(TARGET_NAME)";
869 | SDKROOT = auto;
870 | SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx";
871 | SWIFT_EMIT_LOC_STRINGS = NO;
872 | SWIFT_VERSION = 5.0;
873 | TARGETED_DEVICE_FAMILY = "1,2";
874 | TEST_TARGET_NAME = SystemStats;
875 | };
876 | name = Release;
877 | };
878 | 16DEA6D12B23EEBF009BC775 /* Debug */ = {
879 | isa = XCBuildConfiguration;
880 | buildSettings = {
881 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
882 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
883 | CODE_SIGN_STYLE = Automatic;
884 | CURRENT_PROJECT_VERSION = 1;
885 | DEVELOPMENT_ASSET_PATHS = "\"WatchStats Watch App/Preview Content\"";
886 | DEVELOPMENT_TEAM = JSGZDY54HP;
887 | ENABLE_PREVIEWS = YES;
888 | GENERATE_INFOPLIST_FILE = YES;
889 | INFOPLIST_KEY_CFBundleDisplayName = WatchStats;
890 | INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
891 | INFOPLIST_KEY_WKWatchOnly = YES;
892 | LD_RUNPATH_SEARCH_PATHS = (
893 | "$(inherited)",
894 | "@executable_path/Frameworks",
895 | );
896 | MARKETING_VERSION = 1.0;
897 | PRODUCT_BUNDLE_IDENTIFIER = com.argmax.systemstats.WatchStats.watchkitapp;
898 | PRODUCT_NAME = "$(TARGET_NAME)";
899 | SDKROOT = watchos;
900 | SKIP_INSTALL = YES;
901 | SWIFT_EMIT_LOC_STRINGS = YES;
902 | SWIFT_VERSION = 5.0;
903 | TARGETED_DEVICE_FAMILY = 4;
904 | WATCHOS_DEPLOYMENT_TARGET = 10.0;
905 | };
906 | name = Debug;
907 | };
908 | 16DEA6D22B23EEBF009BC775 /* Release */ = {
909 | isa = XCBuildConfiguration;
910 | buildSettings = {
911 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
912 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
913 | CODE_SIGN_STYLE = Automatic;
914 | CURRENT_PROJECT_VERSION = 1;
915 | DEVELOPMENT_ASSET_PATHS = "\"WatchStats Watch App/Preview Content\"";
916 | DEVELOPMENT_TEAM = JSGZDY54HP;
917 | ENABLE_PREVIEWS = YES;
918 | GENERATE_INFOPLIST_FILE = YES;
919 | INFOPLIST_KEY_CFBundleDisplayName = WatchStats;
920 | INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
921 | INFOPLIST_KEY_WKWatchOnly = YES;
922 | LD_RUNPATH_SEARCH_PATHS = (
923 | "$(inherited)",
924 | "@executable_path/Frameworks",
925 | );
926 | MARKETING_VERSION = 1.0;
927 | PRODUCT_BUNDLE_IDENTIFIER = com.argmax.systemstats.WatchStats.watchkitapp;
928 | PRODUCT_NAME = "$(TARGET_NAME)";
929 | SDKROOT = watchos;
930 | SKIP_INSTALL = YES;
931 | SWIFT_EMIT_LOC_STRINGS = YES;
932 | SWIFT_VERSION = 5.0;
933 | TARGETED_DEVICE_FAMILY = 4;
934 | VALIDATE_PRODUCT = YES;
935 | WATCHOS_DEPLOYMENT_TARGET = 10.0;
936 | };
937 | name = Release;
938 | };
939 | 16DEA6D52B23EEBF009BC775 /* Debug */ = {
940 | isa = XCBuildConfiguration;
941 | buildSettings = {
942 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
943 | CODE_SIGN_STYLE = Automatic;
944 | CURRENT_PROJECT_VERSION = 1;
945 | DEVELOPMENT_TEAM = JSGZDY54HP;
946 | INFOPLIST_KEY_CFBundleDisplayName = WatchStats;
947 | MARKETING_VERSION = 1.0;
948 | PRODUCT_BUNDLE_IDENTIFIER = com.argmax.systemstats.WatchStats;
949 | PRODUCT_NAME = "$(TARGET_NAME)";
950 | SDKROOT = iphoneos;
951 | SWIFT_VERSION = 5.0;
952 | };
953 | name = Debug;
954 | };
955 | 16DEA6D62B23EEBF009BC775 /* Release */ = {
956 | isa = XCBuildConfiguration;
957 | buildSettings = {
958 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
959 | CODE_SIGN_STYLE = Automatic;
960 | CURRENT_PROJECT_VERSION = 1;
961 | DEVELOPMENT_TEAM = JSGZDY54HP;
962 | INFOPLIST_KEY_CFBundleDisplayName = WatchStats;
963 | MARKETING_VERSION = 1.0;
964 | PRODUCT_BUNDLE_IDENTIFIER = com.argmax.systemstats.WatchStats;
965 | PRODUCT_NAME = "$(TARGET_NAME)";
966 | SDKROOT = iphoneos;
967 | SWIFT_VERSION = 5.0;
968 | VALIDATE_PRODUCT = YES;
969 | };
970 | name = Release;
971 | };
972 | 16DEA6D82B23EEBF009BC775 /* Debug */ = {
973 | isa = XCBuildConfiguration;
974 | buildSettings = {
975 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
976 | BUNDLE_LOADER = "$(TEST_HOST)";
977 | CODE_SIGN_STYLE = Automatic;
978 | CURRENT_PROJECT_VERSION = 1;
979 | DEVELOPMENT_TEAM = JSGZDY54HP;
980 | GENERATE_INFOPLIST_FILE = YES;
981 | MARKETING_VERSION = 1.0;
982 | PRODUCT_BUNDLE_IDENTIFIER = "com.argmax.systemstats.WatchStats-Watch-AppTests";
983 | PRODUCT_NAME = "$(TARGET_NAME)";
984 | SDKROOT = watchos;
985 | SWIFT_EMIT_LOC_STRINGS = NO;
986 | SWIFT_VERSION = 5.0;
987 | TARGETED_DEVICE_FAMILY = 4;
988 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/WatchStats Watch App.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/WatchStats Watch App";
989 | WATCHOS_DEPLOYMENT_TARGET = 10.0;
990 | };
991 | name = Debug;
992 | };
993 | 16DEA6D92B23EEBF009BC775 /* Release */ = {
994 | isa = XCBuildConfiguration;
995 | buildSettings = {
996 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
997 | BUNDLE_LOADER = "$(TEST_HOST)";
998 | CODE_SIGN_STYLE = Automatic;
999 | CURRENT_PROJECT_VERSION = 1;
1000 | DEVELOPMENT_TEAM = JSGZDY54HP;
1001 | GENERATE_INFOPLIST_FILE = YES;
1002 | MARKETING_VERSION = 1.0;
1003 | PRODUCT_BUNDLE_IDENTIFIER = "com.argmax.systemstats.WatchStats-Watch-AppTests";
1004 | PRODUCT_NAME = "$(TARGET_NAME)";
1005 | SDKROOT = watchos;
1006 | SWIFT_EMIT_LOC_STRINGS = NO;
1007 | SWIFT_VERSION = 5.0;
1008 | TARGETED_DEVICE_FAMILY = 4;
1009 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/WatchStats Watch App.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/WatchStats Watch App";
1010 | VALIDATE_PRODUCT = YES;
1011 | WATCHOS_DEPLOYMENT_TARGET = 10.0;
1012 | };
1013 | name = Release;
1014 | };
1015 | 16DEA6DB2B23EEBF009BC775 /* Debug */ = {
1016 | isa = XCBuildConfiguration;
1017 | buildSettings = {
1018 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
1019 | CODE_SIGN_STYLE = Automatic;
1020 | CURRENT_PROJECT_VERSION = 1;
1021 | DEVELOPMENT_TEAM = JSGZDY54HP;
1022 | GENERATE_INFOPLIST_FILE = YES;
1023 | MARKETING_VERSION = 1.0;
1024 | PRODUCT_BUNDLE_IDENTIFIER = "com.argmax.systemstats.WatchStats-Watch-AppUITests";
1025 | PRODUCT_NAME = "$(TARGET_NAME)";
1026 | SDKROOT = watchos;
1027 | SWIFT_EMIT_LOC_STRINGS = NO;
1028 | SWIFT_VERSION = 5.0;
1029 | TARGETED_DEVICE_FAMILY = 4;
1030 | TEST_TARGET_NAME = "WatchStats Watch App";
1031 | WATCHOS_DEPLOYMENT_TARGET = 10.0;
1032 | };
1033 | name = Debug;
1034 | };
1035 | 16DEA6DC2B23EEBF009BC775 /* Release */ = {
1036 | isa = XCBuildConfiguration;
1037 | buildSettings = {
1038 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
1039 | CODE_SIGN_STYLE = Automatic;
1040 | CURRENT_PROJECT_VERSION = 1;
1041 | DEVELOPMENT_TEAM = JSGZDY54HP;
1042 | GENERATE_INFOPLIST_FILE = YES;
1043 | MARKETING_VERSION = 1.0;
1044 | PRODUCT_BUNDLE_IDENTIFIER = "com.argmax.systemstats.WatchStats-Watch-AppUITests";
1045 | PRODUCT_NAME = "$(TARGET_NAME)";
1046 | SDKROOT = watchos;
1047 | SWIFT_EMIT_LOC_STRINGS = NO;
1048 | SWIFT_VERSION = 5.0;
1049 | TARGETED_DEVICE_FAMILY = 4;
1050 | TEST_TARGET_NAME = "WatchStats Watch App";
1051 | VALIDATE_PRODUCT = YES;
1052 | WATCHOS_DEPLOYMENT_TARGET = 10.0;
1053 | };
1054 | name = Release;
1055 | };
1056 | /* End XCBuildConfiguration section */
1057 |
1058 | /* Begin XCConfigurationList section */
1059 | 160B440B2AFD965B00D478A8 /* Build configuration list for PBXProject "SystemStats" */ = {
1060 | isa = XCConfigurationList;
1061 | buildConfigurations = (
1062 | 160B44352AFD965D00D478A8 /* Debug */,
1063 | 160B44362AFD965D00D478A8 /* Release */,
1064 | );
1065 | defaultConfigurationIsVisible = 0;
1066 | defaultConfigurationName = Release;
1067 | };
1068 | 160B44372AFD965D00D478A8 /* Build configuration list for PBXNativeTarget "SystemStats" */ = {
1069 | isa = XCConfigurationList;
1070 | buildConfigurations = (
1071 | 160B44382AFD965D00D478A8 /* Debug */,
1072 | 160B44392AFD965D00D478A8 /* Release */,
1073 | );
1074 | defaultConfigurationIsVisible = 0;
1075 | defaultConfigurationName = Release;
1076 | };
1077 | 160B443A2AFD965D00D478A8 /* Build configuration list for PBXNativeTarget "SystemStatsTests" */ = {
1078 | isa = XCConfigurationList;
1079 | buildConfigurations = (
1080 | 160B443B2AFD965D00D478A8 /* Debug */,
1081 | 160B443C2AFD965D00D478A8 /* Release */,
1082 | );
1083 | defaultConfigurationIsVisible = 0;
1084 | defaultConfigurationName = Release;
1085 | };
1086 | 160B443D2AFD965D00D478A8 /* Build configuration list for PBXNativeTarget "SystemStatsUITests" */ = {
1087 | isa = XCConfigurationList;
1088 | buildConfigurations = (
1089 | 160B443E2AFD965D00D478A8 /* Debug */,
1090 | 160B443F2AFD965D00D478A8 /* Release */,
1091 | );
1092 | defaultConfigurationIsVisible = 0;
1093 | defaultConfigurationName = Release;
1094 | };
1095 | 16DEA6D02B23EEBF009BC775 /* Build configuration list for PBXNativeTarget "WatchStats Watch App" */ = {
1096 | isa = XCConfigurationList;
1097 | buildConfigurations = (
1098 | 16DEA6D12B23EEBF009BC775 /* Debug */,
1099 | 16DEA6D22B23EEBF009BC775 /* Release */,
1100 | );
1101 | defaultConfigurationIsVisible = 0;
1102 | defaultConfigurationName = Release;
1103 | };
1104 | 16DEA6D42B23EEBF009BC775 /* Build configuration list for PBXNativeTarget "WatchStats" */ = {
1105 | isa = XCConfigurationList;
1106 | buildConfigurations = (
1107 | 16DEA6D52B23EEBF009BC775 /* Debug */,
1108 | 16DEA6D62B23EEBF009BC775 /* Release */,
1109 | );
1110 | defaultConfigurationIsVisible = 0;
1111 | defaultConfigurationName = Release;
1112 | };
1113 | 16DEA6D72B23EEBF009BC775 /* Build configuration list for PBXNativeTarget "WatchStats Watch AppTests" */ = {
1114 | isa = XCConfigurationList;
1115 | buildConfigurations = (
1116 | 16DEA6D82B23EEBF009BC775 /* Debug */,
1117 | 16DEA6D92B23EEBF009BC775 /* Release */,
1118 | );
1119 | defaultConfigurationIsVisible = 0;
1120 | defaultConfigurationName = Release;
1121 | };
1122 | 16DEA6DA2B23EEBF009BC775 /* Build configuration list for PBXNativeTarget "WatchStats Watch AppUITests" */ = {
1123 | isa = XCConfigurationList;
1124 | buildConfigurations = (
1125 | 16DEA6DB2B23EEBF009BC775 /* Debug */,
1126 | 16DEA6DC2B23EEBF009BC775 /* Release */,
1127 | );
1128 | defaultConfigurationIsVisible = 0;
1129 | defaultConfigurationName = Release;
1130 | };
1131 | /* End XCConfigurationList section */
1132 | };
1133 | rootObject = 160B44082AFD965B00D478A8 /* Project object */;
1134 | }
1135 |
--------------------------------------------------------------------------------