Add watchOS and macOS runners
Seto Elkahfi committed
Jul 30, 2026 at 20:49 UTC
349e7c079f6105059b710ed7ca912773d538e727
26 files changed
+1067
-17
README.md
+7
-4
@@ -49,17 +49,20 @@ Runners/
49
├── Shared/ # transport + RPC server
50
├── iOS/ # iOS / iPadOS host app
51
├── tvOS/ # tvOS host app
52
-└── visionOS/ # visionOS host app
52
+├── visionOS/ # visionOS host app
53
+├── macOS/ # macOS host app
54
+└── watchOS/ # watchOS host app
55
```
56
57
Each platform gets its own application and UI-test targets and a matching
56
-scheme (`ControlKit-iOS`, `ControlKit-tvOS`, `ControlKit-visionOS`) while
57
-importing `XCRSControlKit` and sharing the transport. See `Runners/README.md`.
58
+scheme (`ControlKit-iOS`, `ControlKit-tvOS`, `ControlKit-visionOS`,
59
+`ControlKit-macOS`, `ControlKit-watchOS`) while importing `XCRSControlKit` and
60
+sharing the transport. See `Runners/README.md`.
61
62
## Status
63
64
The package provides the public cross-platform contract. Native ControlKit
62
-runners currently support iOS, iPadOS, tvOS, and visionOS.
65
+runners currently support iOS, iPadOS, tvOS, visionOS, macOS, and watchOS.
66
67
## License
68
Runners/README.md
+5
-1
@@ -15,7 +15,9 @@ Runners/
15
│ └── ControlKitRunnerUITests.swift
16
├── iOS/ # iOS / iPadOS host app + assets
17
├── tvOS/ # tvOS host app + assets
18
-└── visionOS/ # visionOS host app + assets
18
+├── visionOS/ # visionOS host app + assets
19
+├── macOS/ # macOS host app + assets
20
+└── watchOS/ # watchOS host app + assets
21
```
22
23
## Targets and schemes
@@ -25,6 +27,8 @@ Runners/
27
| `ControlKit-iOS` | `ControlKit-iOS` | `ControlKit-iOS-UITests` | iOS / iPadOS |
28
| `ControlKit-tvOS` | `ControlKit-tvOS` | `ControlKit-tvOS-UITests` | tvOS |
29
| `ControlKit-visionOS` | `ControlKit-visionOS` | `ControlKit-visionOS-UITests` | visionOS |
30
+| `ControlKit-macOS` | `ControlKit-macOS` | `ControlKit-macOS-UITests` | macOS |
31
+| `ControlKit-watchOS` | `ControlKit-watchOS` | `ControlKit-watchOS-UITests` | watchOS |
32
33
Each UI-test target compiles the shared `Shared/` sources for its platform, so
34
platform behaviour is selected at compile time via `#if os(...)` in
Runners/Shared/ControlKitRPCServer.swift
+12
-1
@@ -78,6 +78,10 @@ final class ControlKitRPCServer {
78
return .tvOS
79
#elseif os(visionOS)
80
return .visionOS
81
+ #elseif os(macOS)
82
+ return .macOS
83
+ #elseif os(watchOS)
84
+ return .watchOS
85
#else
86
return .iOS
87
#endif
@@ -104,12 +108,19 @@ final class ControlKitRPCServer {
108
XCUIApplication(bundleIdentifier: bundleIdentifier).terminate()
109
return try response(result: ["success": true], id: request.id)
110
case "device.io.tap":
107
- #if os(tvOS) || os(visionOS)
111
+ #if os(tvOS) || os(visionOS) || os(macOS)
112
throw RunnerError.unsupportedInteraction("touch")
113
#else
114
try tap(request.params)
115
return try response(result: ["success": true], id: request.id)
116
#endif
117
+ case "device.io.click":
118
+ #if os(macOS)
119
+ try tap(request.params)
120
+ return try response(result: ["success": true], id: request.id)
121
+ #else
122
+ throw RunnerError.unsupportedInteraction("pointer click")
123
+ #endif
124
case "device.io.spatial.tap":
125
#if os(visionOS)
126
try tap(request.params)
Runners/XCRSControlKitRunner.xcodeproj/project.pbxproj
+449
-11
@@ -11,21 +11,33 @@
11
0DFC449880A304B5154D7F6D /* XCRSControlKit in Frameworks */ = {isa = PBXBuildFile; productRef = BE99FEAB3F75651FC71BB9B5 /* XCRSControlKit */; };
12
100DCE12F169B8A38E219931 /* ControlKitRPCServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 976BFE251DB7DC2248C8D0E7 /* ControlKitRPCServer.swift */; };
13
25622E0215D89F31880E6356 /* ControlKitRunnerUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D582F818EB333BD812EBDAC7 /* ControlKitRunnerUITests.swift */; };
14
+ 2CE41182704301ED3E17F12A /* NIOCore in Frameworks */ = {isa = PBXBuildFile; productRef = 611C969D93EC290726A7395E /* NIOCore */; };
15
3CAE36F48F2BB14EC17B1A49 /* NIOHTTP1 in Frameworks */ = {isa = PBXBuildFile; productRef = 39DF23C6EF63909919D192E1 /* NIOHTTP1 */; };
16
+ 42F868C46B85D81A82D325F0 /* ControlKitRPCServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 976BFE251DB7DC2248C8D0E7 /* ControlKitRPCServer.swift */; };
17
+ 49C565818AD8C7C3D85C498E /* ControlKitRunnerUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D582F818EB333BD812EBDAC7 /* ControlKitRunnerUITests.swift */; };
18
4D29102252109822A895B881 /* NIOPosix in Frameworks */ = {isa = PBXBuildFile; productRef = C9A26D0E7AB404E7BE27C778 /* NIOPosix */; };
19
+ 560FDA8EB7B9DE368869D155 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FD4E3603A115950345EC4C96 /* Assets.xcassets */; };
20
+ 561834A353CBD37B8354A58E /* NIOCore in Frameworks */ = {isa = PBXBuildFile; productRef = 786AF91DEFF9CFAF6733FE5D /* NIOCore */; };
21
57C6D92B45E7092A5C2AD7D2 /* ControlKitRunnerApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FB5CFB03469D6F6B4B90338 /* ControlKitRunnerApp.swift */; };
22
57E28C91935955E0FCA55C21 /* NIOCore in Frameworks */ = {isa = PBXBuildFile; productRef = 1EEBDB1A27DC2D28A6BB1B95 /* NIOCore */; };
23
5C1F1D551479D29CA351EEF1 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E395E1A9D0B3259F9C816109 /* Assets.xcassets */; };
24
+ 607F9363076F0FE76CA24A73 /* ControlKitRunnerApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5591C7FEF7205CCA88C10507 /* ControlKitRunnerApp.swift */; };
25
673EB3CCA913F73C710B72B0 /* NIOCore in Frameworks */ = {isa = PBXBuildFile; productRef = 58494EA2BBD98AE84158250F /* NIOCore */; };
26
6D60E555ABB299495F608B27 /* NIOPosix in Frameworks */ = {isa = PBXBuildFile; productRef = 2B7D7F431DC211BEDBFC374A /* NIOPosix */; };
27
6F0CF3B6D51AEB5C4F3E1827 /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = 06ABEBF2BC26029BF199977C /* README.md */; };
28
7CAF0B42FF68BF36CAC8C8CD /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8A09FB52496A952CB13C163B /* Assets.xcassets */; };
29
7D3C77F9ABF4E0CD672DCEF5 /* NIOHTTP1 in Frameworks */ = {isa = PBXBuildFile; productRef = 84A03CA7B1A8BF405AD3F3C4 /* NIOHTTP1 */; };
30
+ 82D074F9A9D0F5FD6F00CA7B /* ControlKitRPCServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 976BFE251DB7DC2248C8D0E7 /* ControlKitRPCServer.swift */; };
31
8F79A6E8A60191E7A095D2F2 /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = 3DFF0D230E8E7D8DF4E8AF86 /* README.md */; };
32
93235E8B38222B9CC779ED84 /* XCRSControlKit in Frameworks */ = {isa = PBXBuildFile; productRef = 50AB05BF2C324210174A3476 /* XCRSControlKit */; };
33
9540EFD6CC87D6DEF2FBFC0F /* ControlKitRPCServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 976BFE251DB7DC2248C8D0E7 /* ControlKitRPCServer.swift */; };
34
986705883AA98C348CFE6E72 /* XCRSControlKit in Frameworks */ = {isa = PBXBuildFile; productRef = 17A1603CDD0A79E07FAC7D43 /* XCRSControlKit */; };
35
+ 9CC0F626565F3ADFBCAEFE1C /* XCRSControlKit in Frameworks */ = {isa = PBXBuildFile; productRef = F1634B11C3B52F3F9511DF74 /* XCRSControlKit */; };
36
+ 9DF1151412A41AC8D2EDE2D5 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 40A16F9F72DA073E165B0149 /* Assets.xcassets */; };
37
9DFD228E556F05433F75A568 /* NIOHTTP1 in Frameworks */ = {isa = PBXBuildFile; productRef = EE8C054B1BC0620402AEA51B /* NIOHTTP1 */; };
38
+ A5BD016357891BCC301E3E4E /* ControlKitRunnerApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC6FBC92946E0D2F913F6A1E /* ControlKitRunnerApp.swift */; };
39
+ AABA08D219C9E167F666E012 /* NIOHTTP1 in Frameworks */ = {isa = PBXBuildFile; productRef = 9CEC91988487EAD9E87B6D83 /* NIOHTTP1 */; };
40
+ AAED42787D0BEB5F637C9163 /* NIOPosix in Frameworks */ = {isa = PBXBuildFile; productRef = 3253817A08FC0D668A552FA6 /* NIOPosix */; };
41
B2A57E383F93751851FE880C /* NIOCore in Frameworks */ = {isa = PBXBuildFile; productRef = F83D3AB07112BE3B5C5CEEB0 /* NIOCore */; };
42
B986DCE75E07965CA4C1E7F8 /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = D11F41B613A58B56653C16C6 /* README.md */; };
43
BEFE1733DCB97BE06F428AD2 /* ControlKitRunnerApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 898E84DC2CE45F3463AA7E5D /* ControlKitRunnerApp.swift */; };
@@ -33,7 +45,11 @@
45
C552103B6652E1005DB6B8C3 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1D9522A60419FFC7F405FE88 /* Assets.xcassets */; };
46
C8B2C54C0B06115DE7F14ACE /* ControlKitRunnerApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = A32F608A3A429B81416D59FC /* ControlKitRunnerApp.swift */; };
47
D96F5E268D3AFF7DC328622A /* ControlKitRunnerUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D582F818EB333BD812EBDAC7 /* ControlKitRunnerUITests.swift */; };
48
+ E0EA8983AA28CBEFEBDFE501 /* ControlKitRunnerUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D582F818EB333BD812EBDAC7 /* ControlKitRunnerUITests.swift */; };
49
+ E2BD398ADA1021C423A4B263 /* XCRSControlKit in Frameworks */ = {isa = PBXBuildFile; productRef = A71D21E23B0941B7D7C03762 /* XCRSControlKit */; };
50
+ E73C698597C5E140B7FC84A2 /* NIOPosix in Frameworks */ = {isa = PBXBuildFile; productRef = 4DB5F4B1F3592AA72060C1FB /* NIOPosix */; };
51
E7D00D2B9B79391ABB28574C /* NIOPosix in Frameworks */ = {isa = PBXBuildFile; productRef = FFAF906BB53F58598BDAE35B /* NIOPosix */; };
52
+ EB7069C674DA185740685F87 /* NIOHTTP1 in Frameworks */ = {isa = PBXBuildFile; productRef = 3E030B34C4FDF41205C694F8 /* NIOHTTP1 */; };
53
/* End PBXBuildFile section */
54
55
/* Begin PBXContainerItemProxy section */
@@ -51,6 +67,20 @@
67
remoteGlobalIDString = 720F3EC917A0116B593FBBBB;
68
remoteInfo = "ControlKit-visionOS";
69
};
70
+ 3975F74C863C2E47636D5DAE /* PBXContainerItemProxy */ = {
71
+ isa = PBXContainerItemProxy;
72
+ containerPortal = A886E2D8FDDF1B058227A931 /* Project object */;
73
+ proxyType = 1;
74
+ remoteGlobalIDString = 5B67E51B3C9E09531D57616F;
75
+ remoteInfo = "ControlKit-macOS";
76
+ };
77
+ 5A71C8672C07A86ED68BC559 /* PBXContainerItemProxy */ = {
78
+ isa = PBXContainerItemProxy;
79
+ containerPortal = A886E2D8FDDF1B058227A931 /* Project object */;
80
+ proxyType = 1;
81
+ remoteGlobalIDString = E85C2DCD1888C5276C1F13E4;
82
+ remoteInfo = "ControlKit-watchOS";
83
+ };
84
AEE01B43669A92A0B635826C /* PBXContainerItemProxy */ = {
85
isa = PBXContainerItemProxy;
86
containerPortal = A886E2D8FDDF1B058227A931 /* Project object */;
@@ -62,26 +92,46 @@
92
93
/* Begin PBXFileReference section */
94
06ABEBF2BC26029BF199977C /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
65
- 08CFC4F37BB1C3444B435EC8 /* ControlKit-tvOS.app */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.application; name = "ControlKit-tvOS.app"; path = ControlKit.app; sourceTree = BUILT_PRODUCTS_DIR; };
66
- 0AF2C936A45BEF3E427051E8 /* ControlKit-iOS.app */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.application; name = "ControlKit-iOS.app"; path = ControlKit.app; sourceTree = BUILT_PRODUCTS_DIR; };
95
+ 08CFC4F37BB1C3444B435EC8 /* ControlKit-tvOS.app */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.application; path = "ControlKit-tvOS.app"; sourceTree = BUILT_PRODUCTS_DIR; };
96
+ 0AF2C936A45BEF3E427051E8 /* ControlKit-iOS.app */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.application; path = "ControlKit-iOS.app"; sourceTree = BUILT_PRODUCTS_DIR; };
97
1D9522A60419FFC7F405FE88 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
68
- 2A9F28238A4519F25B302BD1 /* ControlKit-visionOS.app */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.application; name = "ControlKit-visionOS.app"; path = ControlKit.app; sourceTree = BUILT_PRODUCTS_DIR; };
98
+ 2A9F28238A4519F25B302BD1 /* ControlKit-visionOS.app */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.application; path = "ControlKit-visionOS.app"; sourceTree = BUILT_PRODUCTS_DIR; };
99
+ 3686EC34042E55BB49FCE937 /* ControlKit-macOS-UITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "ControlKit-macOS-UITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
100
3DFF0D230E8E7D8DF4E8AF86 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
101
+ 40A16F9F72DA073E165B0149 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
102
+ 5591C7FEF7205CCA88C10507 /* ControlKitRunnerApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ControlKitRunnerApp.swift; sourceTree = "<group>"; };
103
+ 5A26B9285A83B3312F79B286 /* ControlKit-macOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "ControlKit-macOS.app"; sourceTree = BUILT_PRODUCTS_DIR; };
104
5A89F5048B0CAE4988FB1203 /* ControlKit-visionOS-UITests.xctest */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.cfbundle; path = "ControlKit-visionOS-UITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
105
5FB5CFB03469D6F6B4B90338 /* ControlKitRunnerApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ControlKitRunnerApp.swift; sourceTree = "<group>"; };
106
898E84DC2CE45F3463AA7E5D /* ControlKitRunnerApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ControlKitRunnerApp.swift; sourceTree = "<group>"; };
107
8A09FB52496A952CB13C163B /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
108
904DF2F8A56B8FA1C5EE1431 /* ControlKit-tvOS-UITests.xctest */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.cfbundle; path = "ControlKit-tvOS-UITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
109
976BFE251DB7DC2248C8D0E7 /* ControlKitRPCServer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ControlKitRPCServer.swift; sourceTree = "<group>"; };
110
+ 9D200812648C48867D12D43D /* ControlKit-watchOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "ControlKit-watchOS.app"; sourceTree = BUILT_PRODUCTS_DIR; };
111
A32F608A3A429B81416D59FC /* ControlKitRunnerApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ControlKitRunnerApp.swift; sourceTree = "<group>"; };
112
+ B4A7C1166461333A52056112 /* ControlKit-macOS-UITests.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "ControlKit-macOS-UITests.entitlements"; sourceTree = "<group>"; };
113
+ CD648878AF85C1F1CC002EC1 /* ControlKit-watchOS-UITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "ControlKit-watchOS-UITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
114
D11F41B613A58B56653C16C6 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
115
D1DCCDE3A93E1CF31802D658 /* xcrs-controlkit */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "xcrs-controlkit"; path = ..; sourceTree = SOURCE_ROOT; };
116
D582F818EB333BD812EBDAC7 /* ControlKitRunnerUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ControlKitRunnerUITests.swift; sourceTree = "<group>"; };
117
E395E1A9D0B3259F9C816109 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
118
+ EC6FBC92946E0D2F913F6A1E /* ControlKitRunnerApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ControlKitRunnerApp.swift; sourceTree = "<group>"; };
119
F93B11596E43814F825966AC /* ControlKit-iOS-UITests.xctest */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.cfbundle; path = "ControlKit-iOS-UITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
120
+ FD4E3603A115950345EC4C96 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
121
/* End PBXFileReference section */
122
123
/* Begin PBXFrameworksBuildPhase section */
124
+ 1BD2A5EFA635301D4165CD27 /* Frameworks */ = {
125
+ isa = PBXFrameworksBuildPhase;
126
+ buildActionMask = 2147483647;
127
+ files = (
128
+ 9CC0F626565F3ADFBCAEFE1C /* XCRSControlKit in Frameworks */,
129
+ 561834A353CBD37B8354A58E /* NIOCore in Frameworks */,
130
+ EB7069C674DA185740685F87 /* NIOHTTP1 in Frameworks */,
131
+ AAED42787D0BEB5F637C9163 /* NIOPosix in Frameworks */,
132
+ );
133
+ runOnlyForDeploymentPostprocessing = 0;
134
+ };
135
2A75581ED579005C72375AAB /* Frameworks */ = {
136
isa = PBXFrameworksBuildPhase;
137
buildActionMask = 2147483647;
@@ -115,6 +165,17 @@
165
);
166
runOnlyForDeploymentPostprocessing = 0;
167
};
168
+ F086B824B8DB8D48046D2A34 /* Frameworks */ = {
169
+ isa = PBXFrameworksBuildPhase;
170
+ buildActionMask = 2147483647;
171
+ files = (
172
+ E2BD398ADA1021C423A4B263 /* XCRSControlKit in Frameworks */,
173
+ 2CE41182704301ED3E17F12A /* NIOCore in Frameworks */,
174
+ AABA08D219C9E167F666E012 /* NIOHTTP1 in Frameworks */,
175
+ E73C698597C5E140B7FC84A2 /* NIOPosix in Frameworks */,
176
+ );
177
+ runOnlyForDeploymentPostprocessing = 0;
178
+ };
179
/* End PBXFrameworksBuildPhase section */
180
181
/* Begin PBXGroup section */
@@ -142,22 +203,47 @@
203
children = (
204
F93B11596E43814F825966AC /* ControlKit-iOS-UITests.xctest */,
205
0AF2C936A45BEF3E427051E8 /* ControlKit-iOS.app */,
206
+ 3686EC34042E55BB49FCE937 /* ControlKit-macOS-UITests.xctest */,
207
+ 5A26B9285A83B3312F79B286 /* ControlKit-macOS.app */,
208
904DF2F8A56B8FA1C5EE1431 /* ControlKit-tvOS-UITests.xctest */,
209
08CFC4F37BB1C3444B435EC8 /* ControlKit-tvOS.app */,
210
5A89F5048B0CAE4988FB1203 /* ControlKit-visionOS-UITests.xctest */,
211
2A9F28238A4519F25B302BD1 /* ControlKit-visionOS.app */,
212
+ CD648878AF85C1F1CC002EC1 /* ControlKit-watchOS-UITests.xctest */,
213
+ 9D200812648C48867D12D43D /* ControlKit-watchOS.app */,
214
);
215
name = Products;
216
sourceTree = "<group>";
217
};
218
+ 72270F7916B04830BCC2AB34 /* watchOS */ = {
219
+ isa = PBXGroup;
220
+ children = (
221
+ FD4E3603A115950345EC4C96 /* Assets.xcassets */,
222
+ EC6FBC92946E0D2F913F6A1E /* ControlKitRunnerApp.swift */,
223
+ );
224
+ path = watchOS;
225
+ sourceTree = "<group>";
226
+ };
227
+ 820ECEA915ACE527EF0CA19E /* macOS */ = {
228
+ isa = PBXGroup;
229
+ children = (
230
+ 40A16F9F72DA073E165B0149 /* Assets.xcassets */,
231
+ B4A7C1166461333A52056112 /* ControlKit-macOS-UITests.entitlements */,
232
+ 5591C7FEF7205CCA88C10507 /* ControlKitRunnerApp.swift */,
233
+ );
234
+ path = macOS;
235
+ sourceTree = "<group>";
236
+ };
237
8BF319E1B3CB4CA319D804BA = {
238
isa = PBXGroup;
239
children = (
240
CEE9E165E43396ABDCF722E3 /* iOS */,
241
+ 820ECEA915ACE527EF0CA19E /* macOS */,
242
AAF9A6C2C031D435E78F618D /* Packages */,
243
0AD16B636A496FC575FABB2F /* Shared */,
244
F3830AB6FA85799037B91E7D /* tvOS */,
245
18CD92B06EDA4B61503FE8DA /* visionOS */,
246
+ 72270F7916B04830BCC2AB34 /* watchOS */,
247
2D1B85549DE31AFEDF5D1159 /* Products */,
248
);
249
sourceTree = "<group>";
@@ -234,6 +320,24 @@
320
productReference = 5A89F5048B0CAE4988FB1203 /* ControlKit-visionOS-UITests.xctest */;
321
productType = "com.apple.product-type.bundle.ui-testing";
322
};
323
+ 5B67E51B3C9E09531D57616F /* ControlKit-macOS */ = {
324
+ isa = PBXNativeTarget;
325
+ buildConfigurationList = D6C80CE473AEC1B232446EB2 /* Build configuration list for PBXNativeTarget "ControlKit-macOS" */;
326
+ buildPhases = (
327
+ 9A9604B1CA131DA035CE57B4 /* Sources */,
328
+ F6FC78229E31A8705EA840DA /* Resources */,
329
+ );
330
+ buildRules = (
331
+ );
332
+ dependencies = (
333
+ );
334
+ name = "ControlKit-macOS";
335
+ packageProductDependencies = (
336
+ );
337
+ productName = "ControlKit-macOS";
338
+ productReference = 5A26B9285A83B3312F79B286 /* ControlKit-macOS.app */;
339
+ productType = "com.apple.product-type.application";
340
+ };
341
720F3EC917A0116B593FBBBB /* ControlKit-visionOS */ = {
342
isa = PBXNativeTarget;
343
buildConfigurationList = A3E875F2C0588D2AFB728EC8 /* Build configuration list for PBXNativeTarget "ControlKit-visionOS" */;
@@ -252,6 +356,29 @@
356
productReference = 2A9F28238A4519F25B302BD1 /* ControlKit-visionOS.app */;
357
productType = "com.apple.product-type.application";
358
};
359
+ 8A89960127FE4F8007E66449 /* ControlKit-watchOS-UITests */ = {
360
+ isa = PBXNativeTarget;
361
+ buildConfigurationList = 708FB1855395DEDE0D00C5D9 /* Build configuration list for PBXNativeTarget "ControlKit-watchOS-UITests" */;
362
+ buildPhases = (
363
+ DBDE4573C281CF3AAC9BE22F /* Sources */,
364
+ 1BD2A5EFA635301D4165CD27 /* Frameworks */,
365
+ );
366
+ buildRules = (
367
+ );
368
+ dependencies = (
369
+ E84304E076EE747D380D070C /* PBXTargetDependency */,
370
+ );
371
+ name = "ControlKit-watchOS-UITests";
372
+ packageProductDependencies = (
373
+ F1634B11C3B52F3F9511DF74 /* XCRSControlKit */,
374
+ 786AF91DEFF9CFAF6733FE5D /* NIOCore */,
375
+ 3E030B34C4FDF41205C694F8 /* NIOHTTP1 */,
376
+ 3253817A08FC0D668A552FA6 /* NIOPosix */,
377
+ );
378
+ productName = "ControlKit-watchOS-UITests";
379
+ productReference = CD648878AF85C1F1CC002EC1 /* ControlKit-watchOS-UITests.xctest */;
380
+ productType = "com.apple.product-type.bundle.ui-testing";
381
+ };
382
8B29B60E49F265583C3FB987 /* ControlKit-tvOS-UITests */ = {
383
isa = PBXNativeTarget;
384
buildConfigurationList = DC1656DA116F4F1E1E7A9039 /* Build configuration list for PBXNativeTarget "ControlKit-tvOS-UITests" */;
@@ -293,6 +420,29 @@
420
productReference = 0AF2C936A45BEF3E427051E8 /* ControlKit-iOS.app */;
421
productType = "com.apple.product-type.application";
422
};
423
+ BBEDFC1F8A411D980AF3432F /* ControlKit-macOS-UITests */ = {
424
+ isa = PBXNativeTarget;
425
+ buildConfigurationList = E61F070B23F4FAE658E19065 /* Build configuration list for PBXNativeTarget "ControlKit-macOS-UITests" */;
426
+ buildPhases = (
427
+ 0E5FA41A44AC2624E81E9974 /* Sources */,
428
+ F086B824B8DB8D48046D2A34 /* Frameworks */,
429
+ );
430
+ buildRules = (
431
+ );
432
+ dependencies = (
433
+ 071B3FE090CFAEFBE620914A /* PBXTargetDependency */,
434
+ );
435
+ name = "ControlKit-macOS-UITests";
436
+ packageProductDependencies = (
437
+ A71D21E23B0941B7D7C03762 /* XCRSControlKit */,
438
+ 611C969D93EC290726A7395E /* NIOCore */,
439
+ 9CEC91988487EAD9E87B6D83 /* NIOHTTP1 */,
440
+ 4DB5F4B1F3592AA72060C1FB /* NIOPosix */,
441
+ );
442
+ productName = "ControlKit-macOS-UITests";
443
+ productReference = 3686EC34042E55BB49FCE937 /* ControlKit-macOS-UITests.xctest */;
444
+ productType = "com.apple.product-type.bundle.ui-testing";
445
+ };
446
CD73A40CAB68D297974A7E90 /* ControlKit-iOS-UITests */ = {
447
isa = PBXNativeTarget;
448
buildConfigurationList = 83E3FC025793339356561648 /* Build configuration list for PBXNativeTarget "ControlKit-iOS-UITests" */;
@@ -316,6 +466,24 @@
466
productReference = F93B11596E43814F825966AC /* ControlKit-iOS-UITests.xctest */;
467
productType = "com.apple.product-type.bundle.ui-testing";
468
};
469
+ E85C2DCD1888C5276C1F13E4 /* ControlKit-watchOS */ = {
470
+ isa = PBXNativeTarget;
471
+ buildConfigurationList = D28A8B9028C344107343F1FB /* Build configuration list for PBXNativeTarget "ControlKit-watchOS" */;
472
+ buildPhases = (
473
+ 08F2647A4EB5883ED31CD05C /* Sources */,
474
+ 5DE56F756B7A75E80ACF62EB /* Resources */,
475
+ );
476
+ buildRules = (
477
+ );
478
+ dependencies = (
479
+ );
480
+ name = "ControlKit-watchOS";
481
+ packageProductDependencies = (
482
+ );
483
+ productName = "ControlKit-watchOS";
484
+ productReference = 9D200812648C48867D12D43D /* ControlKit-watchOS.app */;
485
+ productType = "com.apple.product-type.application";
486
+ };
487
/* End PBXNativeTarget section */
488
489
/* Begin PBXProject section */
@@ -328,9 +496,15 @@
496
09F6B446FD034D1BCF7FE56B = {
497
TestTargetID = 720F3EC917A0116B593FBBBB;
498
};
499
+ 8A89960127FE4F8007E66449 = {
500
+ TestTargetID = E85C2DCD1888C5276C1F13E4;
501
+ };
502
8B29B60E49F265583C3FB987 = {
503
TestTargetID = 029C796A915A8119077A2F2D;
504
};
505
+ BBEDFC1F8A411D980AF3432F = {
506
+ TestTargetID = 5B67E51B3C9E09531D57616F;
507
+ };
508
CD73A40CAB68D297974A7E90 = {
509
TestTargetID = 9F5E3C368E274D9C0BF1AC09;
510
};
@@ -360,6 +534,10 @@
534
8B29B60E49F265583C3FB987 /* ControlKit-tvOS-UITests */,
535
720F3EC917A0116B593FBBBB /* ControlKit-visionOS */,
536
09F6B446FD034D1BCF7FE56B /* ControlKit-visionOS-UITests */,
537
+ 5B67E51B3C9E09531D57616F /* ControlKit-macOS */,
538
+ BBEDFC1F8A411D980AF3432F /* ControlKit-macOS-UITests */,
539
+ E85C2DCD1888C5276C1F13E4 /* ControlKit-watchOS */,
540
+ 8A89960127FE4F8007E66449 /* ControlKit-watchOS-UITests */,
541
);
542
};
543
/* End PBXProject section */
@@ -374,6 +552,14 @@
552
);
553
runOnlyForDeploymentPostprocessing = 0;
554
};
555
+ 5DE56F756B7A75E80ACF62EB /* Resources */ = {
556
+ isa = PBXResourcesBuildPhase;
557
+ buildActionMask = 2147483647;
558
+ files = (
559
+ 560FDA8EB7B9DE368869D155 /* Assets.xcassets in Resources */,
560
+ );
561
+ runOnlyForDeploymentPostprocessing = 0;
562
+ };
563
A88C8E544C02C1D56E86A9C7 /* Resources */ = {
564
isa = PBXResourcesBuildPhase;
565
buildActionMask = 2147483647;
@@ -383,6 +569,14 @@
569
);
570
runOnlyForDeploymentPostprocessing = 0;
571
};
572
+ F6FC78229E31A8705EA840DA /* Resources */ = {
573
+ isa = PBXResourcesBuildPhase;
574
+ buildActionMask = 2147483647;
575
+ files = (
576
+ 9DF1151412A41AC8D2EDE2D5 /* Assets.xcassets in Resources */,
577
+ );
578
+ runOnlyForDeploymentPostprocessing = 0;
579
+ };
580
FE06AFC9AE7B730022308652 /* Resources */ = {
581
isa = PBXResourcesBuildPhase;
582
buildActionMask = 2147483647;
@@ -395,6 +589,23 @@
589
/* End PBXResourcesBuildPhase section */
590
591
/* Begin PBXSourcesBuildPhase section */
592
+ 08F2647A4EB5883ED31CD05C /* Sources */ = {
593
+ isa = PBXSourcesBuildPhase;
594
+ buildActionMask = 2147483647;
595
+ files = (
596
+ A5BD016357891BCC301E3E4E /* ControlKitRunnerApp.swift in Sources */,
597
+ );
598
+ runOnlyForDeploymentPostprocessing = 0;
599
+ };
600
+ 0E5FA41A44AC2624E81E9974 /* Sources */ = {
601
+ isa = PBXSourcesBuildPhase;
602
+ buildActionMask = 2147483647;
603
+ files = (
604
+ 82D074F9A9D0F5FD6F00CA7B /* ControlKitRPCServer.swift in Sources */,
605
+ E0EA8983AA28CBEFEBDFE501 /* ControlKitRunnerUITests.swift in Sources */,
606
+ );
607
+ runOnlyForDeploymentPostprocessing = 0;
608
+ };
609
25A5679D9AB0D84C081D9343 /* Sources */ = {
610
isa = PBXSourcesBuildPhase;
611
buildActionMask = 2147483647;
@@ -446,9 +657,31 @@
657
);
658
runOnlyForDeploymentPostprocessing = 0;
659
};
660
+ 9A9604B1CA131DA035CE57B4 /* Sources */ = {
661
+ isa = PBXSourcesBuildPhase;
662
+ buildActionMask = 2147483647;
663
+ files = (
664
+ 607F9363076F0FE76CA24A73 /* ControlKitRunnerApp.swift in Sources */,
665
+ );
666
+ runOnlyForDeploymentPostprocessing = 0;
667
+ };
668
+ DBDE4573C281CF3AAC9BE22F /* Sources */ = {
669
+ isa = PBXSourcesBuildPhase;
670
+ buildActionMask = 2147483647;
671
+ files = (
672
+ 42F868C46B85D81A82D325F0 /* ControlKitRPCServer.swift in Sources */,
673
+ 49C565818AD8C7C3D85C498E /* ControlKitRunnerUITests.swift in Sources */,
674
+ );
675
+ runOnlyForDeploymentPostprocessing = 0;
676
+ };
677
/* End PBXSourcesBuildPhase section */
678
679
/* Begin PBXTargetDependency section */
680
+ 071B3FE090CFAEFBE620914A /* PBXTargetDependency */ = {
681
+ isa = PBXTargetDependency;
682
+ target = 5B67E51B3C9E09531D57616F /* ControlKit-macOS */;
683
+ targetProxy = 3975F74C863C2E47636D5DAE /* PBXContainerItemProxy */;
684
+ };
685
55C3178DB2606813467C97CC /* PBXTargetDependency */ = {
686
isa = PBXTargetDependency;
687
target = 720F3EC917A0116B593FBBBB /* ControlKit-visionOS */;
@@ -459,6 +692,11 @@
692
target = 9F5E3C368E274D9C0BF1AC09 /* ControlKit-iOS */;
693
targetProxy = 154A64286F9DFB5C95CF695E /* PBXContainerItemProxy */;
694
};
695
+ E84304E076EE747D380D070C /* PBXTargetDependency */ = {
696
+ isa = PBXTargetDependency;
697
+ target = E85C2DCD1888C5276C1F13E4 /* ControlKit-watchOS */;
698
+ targetProxy = 5A71C8672C07A86ED68BC559 /* PBXContainerItemProxy */;
699
+ };
700
F37FD1FE4F9670C2C355615F /* PBXTargetDependency */ = {
701
isa = PBXTargetDependency;
702
target = 029C796A915A8119077A2F2D /* ControlKit-tvOS */;
@@ -485,6 +723,23 @@
723
};
724
name = Release;
725
};
726
+ 0615B9D71FCA89F904AEAB2D /* Debug */ = {
727
+ isa = XCBuildConfiguration;
728
+ buildSettings = {
729
+ BUNDLE_LOADER = "$(TEST_HOST)";
730
+ LD_RUNPATH_SEARCH_PATHS = (
731
+ "$(inherited)",
732
+ "@executable_path/Frameworks",
733
+ "@loader_path/Frameworks",
734
+ );
735
+ PRODUCT_BUNDLE_IDENTIFIER = "com.smbcloud.xcrs-controlkit.watchos.runnerUITests";
736
+ SDKROOT = watchos;
737
+ SKIP_INSTALL = YES;
738
+ TARGETED_DEVICE_FAMILY = 4;
739
+ TEST_TARGET_NAME = "ControlKit-watchOS";
740
+ };
741
+ name = Debug;
742
+ };
743
21F4165C7F57458C04C5805E /* Debug */ = {
744
isa = XCBuildConfiguration;
745
buildSettings = {
@@ -518,6 +773,41 @@
773
};
774
name = Debug;
775
};
776
+ 337182B361D51F9D6F10F5DC /* Debug */ = {
777
+ isa = XCBuildConfiguration;
778
+ buildSettings = {
779
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
780
+ CODE_SIGN_IDENTITY = "-";
781
+ COMBINE_HIDPI_IMAGES = YES;
782
+ ENABLE_HARDENED_RUNTIME = NO;
783
+ LD_RUNPATH_SEARCH_PATHS = (
784
+ "$(inherited)",
785
+ "@executable_path/../Frameworks",
786
+ );
787
+ PRODUCT_BUNDLE_IDENTIFIER = "com.smbcloud.xcrs-controlkit.macos.runner";
788
+ PRODUCT_NAME = ControlKit;
789
+ SDKROOT = macosx;
790
+ };
791
+ name = Debug;
792
+ };
793
+ 37B91A75D6E30BD6311172CE /* Release */ = {
794
+ isa = XCBuildConfiguration;
795
+ buildSettings = {
796
+ BUNDLE_LOADER = "$(TEST_HOST)";
797
+ CODE_SIGN_ENTITLEMENTS = "macOS/ControlKit-macOS-UITests.entitlements";
798
+ CODE_SIGN_IDENTITY = "-";
799
+ COMBINE_HIDPI_IMAGES = YES;
800
+ LD_RUNPATH_SEARCH_PATHS = (
801
+ "$(inherited)",
802
+ "@executable_path/Frameworks",
803
+ "@loader_path/Frameworks",
804
+ );
805
+ PRODUCT_BUNDLE_IDENTIFIER = "com.smbcloud.xcrs-controlkit.macos.runnerUITests";
806
+ SDKROOT = macosx;
807
+ TEST_TARGET_NAME = "ControlKit-macOS";
808
+ };
809
+ name = Release;
810
+ };
811
41FF10163C9AB188CF4891AF /* Debug */ = {
812
isa = XCBuildConfiguration;
813
buildSettings = {
@@ -588,10 +878,8 @@
878
GENERATE_INFOPLIST_FILE = YES;
879
INFOPLIST_KEY_CFBundleDisplayName = ControlKit;
880
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
591
- LD_RUNPATH_SEARCH_PATHS = (
592
- "$(inherited)",
593
- "@executable_path/Frameworks",
594
- );
881
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
882
+ MACOSX_DEPLOYMENT_TARGET = 13.0;
883
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
884
MTL_FAST_MATH = YES;
885
ONLY_ACTIVE_ARCH = YES;
@@ -600,6 +888,7 @@
888
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
889
SWIFT_VERSION = 5.9;
890
TVOS_DEPLOYMENT_TARGET = 16.0;
891
+ WATCHOS_DEPLOYMENT_TARGET = 9.0;
892
XROS_DEPLOYMENT_TARGET = 1.0;
893
};
894
name = Debug;
@@ -715,6 +1004,30 @@
1004
};
1005
name = Release;
1006
};
1007
+ A15E58D90454C1314DF91A79 /* Debug */ = {
1008
+ isa = XCBuildConfiguration;
1009
+ buildSettings = {
1010
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
1011
+ PRODUCT_BUNDLE_IDENTIFIER = "com.smbcloud.xcrs-controlkit.watchos.runner";
1012
+ PRODUCT_NAME = ControlKit;
1013
+ SDKROOT = watchos;
1014
+ SKIP_INSTALL = YES;
1015
+ TARGETED_DEVICE_FAMILY = 4;
1016
+ };
1017
+ name = Debug;
1018
+ };
1019
+ A24720312170C6FC3A02C248 /* Release */ = {
1020
+ isa = XCBuildConfiguration;
1021
+ buildSettings = {
1022
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
1023
+ PRODUCT_BUNDLE_IDENTIFIER = "com.smbcloud.xcrs-controlkit.watchos.runner";
1024
+ PRODUCT_NAME = ControlKit;
1025
+ SDKROOT = watchos;
1026
+ SKIP_INSTALL = YES;
1027
+ TARGETED_DEVICE_FAMILY = 4;
1028
+ };
1029
+ name = Release;
1030
+ };
1031
AE247B8CB1FB1A6E8E8B8696 /* Release */ = {
1032
isa = XCBuildConfiguration;
1033
buildSettings = {
@@ -731,6 +1044,41 @@
1044
};
1045
name = Release;
1046
};
1047
+ B656C0A63029764B760E4397 /* Debug */ = {
1048
+ isa = XCBuildConfiguration;
1049
+ buildSettings = {
1050
+ BUNDLE_LOADER = "$(TEST_HOST)";
1051
+ CODE_SIGN_ENTITLEMENTS = "macOS/ControlKit-macOS-UITests.entitlements";
1052
+ CODE_SIGN_IDENTITY = "-";
1053
+ COMBINE_HIDPI_IMAGES = YES;
1054
+ LD_RUNPATH_SEARCH_PATHS = (
1055
+ "$(inherited)",
1056
+ "@executable_path/Frameworks",
1057
+ "@loader_path/Frameworks",
1058
+ );
1059
+ PRODUCT_BUNDLE_IDENTIFIER = "com.smbcloud.xcrs-controlkit.macos.runnerUITests";
1060
+ SDKROOT = macosx;
1061
+ TEST_TARGET_NAME = "ControlKit-macOS";
1062
+ };
1063
+ name = Debug;
1064
+ };
1065
+ D749370E86B8B19A96D7BC0E /* Release */ = {
1066
+ isa = XCBuildConfiguration;
1067
+ buildSettings = {
1068
+ BUNDLE_LOADER = "$(TEST_HOST)";
1069
+ LD_RUNPATH_SEARCH_PATHS = (
1070
+ "$(inherited)",
1071
+ "@executable_path/Frameworks",
1072
+ "@loader_path/Frameworks",
1073
+ );
1074
+ PRODUCT_BUNDLE_IDENTIFIER = "com.smbcloud.xcrs-controlkit.watchos.runnerUITests";
1075
+ SDKROOT = watchos;
1076
+ SKIP_INSTALL = YES;
1077
+ TARGETED_DEVICE_FAMILY = 4;
1078
+ TEST_TARGET_NAME = "ControlKit-watchOS";
1079
+ };
1080
+ name = Release;
1081
+ };
1082
E4C3287EEC34289D60AD8369 /* Release */ = {
1083
isa = XCBuildConfiguration;
1084
buildSettings = {
@@ -779,10 +1127,8 @@
1127
GENERATE_INFOPLIST_FILE = YES;
1128
INFOPLIST_KEY_CFBundleDisplayName = ControlKit;
1129
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
782
- LD_RUNPATH_SEARCH_PATHS = (
783
- "$(inherited)",
784
- "@executable_path/Frameworks",
785
- );
1130
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
1131
+ MACOSX_DEPLOYMENT_TARGET = 13.0;
1132
MTL_ENABLE_DEBUG_INFO = NO;
1133
MTL_FAST_MATH = YES;
1134
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -790,10 +1136,28 @@
1136
SWIFT_OPTIMIZATION_LEVEL = "-O";
1137
SWIFT_VERSION = 5.9;
1138
TVOS_DEPLOYMENT_TARGET = 16.0;
1139
+ WATCHOS_DEPLOYMENT_TARGET = 9.0;
1140
XROS_DEPLOYMENT_TARGET = 1.0;
1141
};
1142
name = Release;
1143
};
1144
+ F39E0821F2FA6F20D59DF041 /* Release */ = {
1145
+ isa = XCBuildConfiguration;
1146
+ buildSettings = {
1147
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
1148
+ CODE_SIGN_IDENTITY = "-";
1149
+ COMBINE_HIDPI_IMAGES = YES;
1150
+ ENABLE_HARDENED_RUNTIME = NO;
1151
+ LD_RUNPATH_SEARCH_PATHS = (
1152
+ "$(inherited)",
1153
+ "@executable_path/../Frameworks",
1154
+ );
1155
+ PRODUCT_BUNDLE_IDENTIFIER = "com.smbcloud.xcrs-controlkit.macos.runner";
1156
+ PRODUCT_NAME = ControlKit;
1157
+ SDKROOT = macosx;
1158
+ };
1159
+ name = Release;
1160
+ };
1161
/* End XCBuildConfiguration section */
1162
1163
/* Begin XCConfigurationList section */
@@ -815,6 +1179,15 @@
1179
defaultConfigurationIsVisible = 0;
1180
defaultConfigurationName = Debug;
1181
};
1182
+ 708FB1855395DEDE0D00C5D9 /* Build configuration list for PBXNativeTarget "ControlKit-watchOS-UITests" */ = {
1183
+ isa = XCConfigurationList;
1184
+ buildConfigurations = (
1185
+ 0615B9D71FCA89F904AEAB2D /* Debug */,
1186
+ D749370E86B8B19A96D7BC0E /* Release */,
1187
+ );
1188
+ defaultConfigurationIsVisible = 0;
1189
+ defaultConfigurationName = Debug;
1190
+ };
1191
83E3FC025793339356561648 /* Build configuration list for PBXNativeTarget "ControlKit-iOS-UITests" */ = {
1192
isa = XCConfigurationList;
1193
buildConfigurations = (
@@ -842,6 +1215,24 @@
1215
defaultConfigurationIsVisible = 0;
1216
defaultConfigurationName = Debug;
1217
};
1218
+ D28A8B9028C344107343F1FB /* Build configuration list for PBXNativeTarget "ControlKit-watchOS" */ = {
1219
+ isa = XCConfigurationList;
1220
+ buildConfigurations = (
1221
+ A15E58D90454C1314DF91A79 /* Debug */,
1222
+ A24720312170C6FC3A02C248 /* Release */,
1223
+ );
1224
+ defaultConfigurationIsVisible = 0;
1225
+ defaultConfigurationName = Debug;
1226
+ };
1227
+ D6C80CE473AEC1B232446EB2 /* Build configuration list for PBXNativeTarget "ControlKit-macOS" */ = {
1228
+ isa = XCConfigurationList;
1229
+ buildConfigurations = (
1230
+ 337182B361D51F9D6F10F5DC /* Debug */,
1231
+ F39E0821F2FA6F20D59DF041 /* Release */,
1232
+ );
1233
+ defaultConfigurationIsVisible = 0;
1234
+ defaultConfigurationName = Debug;
1235
+ };
1236
DC1656DA116F4F1E1E7A9039 /* Build configuration list for PBXNativeTarget "ControlKit-tvOS-UITests" */ = {
1237
isa = XCConfigurationList;
1238
buildConfigurations = (
@@ -851,6 +1242,15 @@
1242
defaultConfigurationIsVisible = 0;
1243
defaultConfigurationName = Debug;
1244
};
1245
+ E61F070B23F4FAE658E19065 /* Build configuration list for PBXNativeTarget "ControlKit-macOS-UITests" */ = {
1246
+ isa = XCConfigurationList;
1247
+ buildConfigurations = (
1248
+ B656C0A63029764B760E4397 /* Debug */,
1249
+ 37B91A75D6E30BD6311172CE /* Release */,
1250
+ );
1251
+ defaultConfigurationIsVisible = 0;
1252
+ defaultConfigurationName = Debug;
1253
+ };
1254
F90CA1FF8DF178C6B4D2D56F /* Build configuration list for PBXNativeTarget "ControlKit-tvOS" */ = {
1255
isa = XCConfigurationList;
1256
buildConfigurations = (
@@ -895,11 +1295,26 @@
1295
package = 097CD02F3C7519204C9CDC73 /* XCRemoteSwiftPackageReference "swift-nio" */;
1296
productName = NIOPosix;
1297
};
1298
+ 3253817A08FC0D668A552FA6 /* NIOPosix */ = {
1299
+ isa = XCSwiftPackageProductDependency;
1300
+ package = 097CD02F3C7519204C9CDC73 /* XCRemoteSwiftPackageReference "swift-nio" */;
1301
+ productName = NIOPosix;
1302
+ };
1303
39DF23C6EF63909919D192E1 /* NIOHTTP1 */ = {
1304
isa = XCSwiftPackageProductDependency;
1305
package = 097CD02F3C7519204C9CDC73 /* XCRemoteSwiftPackageReference "swift-nio" */;
1306
productName = NIOHTTP1;
1307
};
1308
+ 3E030B34C4FDF41205C694F8 /* NIOHTTP1 */ = {
1309
+ isa = XCSwiftPackageProductDependency;
1310
+ package = 097CD02F3C7519204C9CDC73 /* XCRemoteSwiftPackageReference "swift-nio" */;
1311
+ productName = NIOHTTP1;
1312
+ };
1313
+ 4DB5F4B1F3592AA72060C1FB /* NIOPosix */ = {
1314
+ isa = XCSwiftPackageProductDependency;
1315
+ package = 097CD02F3C7519204C9CDC73 /* XCRemoteSwiftPackageReference "swift-nio" */;
1316
+ productName = NIOPosix;
1317
+ };
1318
50AB05BF2C324210174A3476 /* XCRSControlKit */ = {
1319
isa = XCSwiftPackageProductDependency;
1320
productName = XCRSControlKit;
@@ -909,11 +1324,30 @@
1324
package = 097CD02F3C7519204C9CDC73 /* XCRemoteSwiftPackageReference "swift-nio" */;
1325
productName = NIOCore;
1326
};
1327
+ 611C969D93EC290726A7395E /* NIOCore */ = {
1328
+ isa = XCSwiftPackageProductDependency;
1329
+ package = 097CD02F3C7519204C9CDC73 /* XCRemoteSwiftPackageReference "swift-nio" */;
1330
+ productName = NIOCore;
1331
+ };
1332
+ 786AF91DEFF9CFAF6733FE5D /* NIOCore */ = {
1333
+ isa = XCSwiftPackageProductDependency;
1334
+ package = 097CD02F3C7519204C9CDC73 /* XCRemoteSwiftPackageReference "swift-nio" */;
1335
+ productName = NIOCore;
1336
+ };
1337
84A03CA7B1A8BF405AD3F3C4 /* NIOHTTP1 */ = {
1338
isa = XCSwiftPackageProductDependency;
1339
package = 097CD02F3C7519204C9CDC73 /* XCRemoteSwiftPackageReference "swift-nio" */;
1340
productName = NIOHTTP1;
1341
};
1342
+ 9CEC91988487EAD9E87B6D83 /* NIOHTTP1 */ = {
1343
+ isa = XCSwiftPackageProductDependency;
1344
+ package = 097CD02F3C7519204C9CDC73 /* XCRemoteSwiftPackageReference "swift-nio" */;
1345
+ productName = NIOHTTP1;
1346
+ };
1347
+ A71D21E23B0941B7D7C03762 /* XCRSControlKit */ = {
1348
+ isa = XCSwiftPackageProductDependency;
1349
+ productName = XCRSControlKit;
1350
+ };
1351
BE99FEAB3F75651FC71BB9B5 /* XCRSControlKit */ = {
1352
isa = XCSwiftPackageProductDependency;
1353
productName = XCRSControlKit;
@@ -928,6 +1362,10 @@
1362
package = 097CD02F3C7519204C9CDC73 /* XCRemoteSwiftPackageReference "swift-nio" */;
1363
productName = NIOHTTP1;
1364
};
1365
+ F1634B11C3B52F3F9511DF74 /* XCRSControlKit */ = {
1366
+ isa = XCSwiftPackageProductDependency;
1367
+ productName = XCRSControlKit;
1368
+ };
1369
F83D3AB07112BE3B5C5CEEB0 /* NIOCore */ = {
1370
isa = XCSwiftPackageProductDependency;
1371
package = 097CD02F3C7519204C9CDC73 /* XCRemoteSwiftPackageReference "swift-nio" */;
Runners/XCRSControlKitRunner.xcodeproj/xcshareddata/xcschemes/ControlKit-macOS.xcscheme
new
+111
@@ -0,0 +1,111 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<Scheme
3
+ LastUpgradeVersion = "1430"
4
+ version = "1.3">
5
+ <BuildAction
6
+ parallelizeBuildables = "YES"
7
+ buildImplicitDependencies = "YES">
8
+ <BuildActionEntries>
9
+ <BuildActionEntry
10
+ buildForTesting = "YES"
11
+ buildForRunning = "YES"
12
+ buildForProfiling = "YES"
13
+ buildForArchiving = "YES"
14
+ buildForAnalyzing = "YES">
15
+ <BuildableReference
16
+ BuildableIdentifier = "primary"
17
+ BlueprintIdentifier = "5B67E51B3C9E09531D57616F"
18
+ BuildableName = "ControlKit.app"
19
+ BlueprintName = "ControlKit-macOS"
20
+ ReferencedContainer = "container:XCRSControlKitRunner.xcodeproj">
21
+ </BuildableReference>
22
+ </BuildActionEntry>
23
+ <BuildActionEntry
24
+ buildForTesting = "YES"
25
+ buildForRunning = "NO"
26
+ buildForProfiling = "NO"
27
+ buildForArchiving = "NO"
28
+ buildForAnalyzing = "NO">
29
+ <BuildableReference
30
+ BuildableIdentifier = "primary"
31
+ BlueprintIdentifier = "BBEDFC1F8A411D980AF3432F"
32
+ BuildableName = "ControlKit-macOS-UITests.xctest"
33
+ BlueprintName = "ControlKit-macOS-UITests"
34
+ ReferencedContainer = "container:XCRSControlKitRunner.xcodeproj">
35
+ </BuildableReference>
36
+ </BuildActionEntry>
37
+ </BuildActionEntries>
38
+ </BuildAction>
39
+ <TestAction
40
+ buildConfiguration = "Debug"
41
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
42
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
43
+ shouldUseLaunchSchemeArgsEnv = "YES">
44
+ <MacroExpansion>
45
+ <BuildableReference
46
+ BuildableIdentifier = "primary"
47
+ BlueprintIdentifier = "5B67E51B3C9E09531D57616F"
48
+ BuildableName = "ControlKit.app"
49
+ BlueprintName = "ControlKit-macOS"
50
+ ReferencedContainer = "container:XCRSControlKitRunner.xcodeproj">
51
+ </BuildableReference>
52
+ </MacroExpansion>
53
+ <Testables>
54
+ <TestableReference
55
+ skipped = "NO">
56
+ <BuildableReference
57
+ BuildableIdentifier = "primary"
58
+ BlueprintIdentifier = "BBEDFC1F8A411D980AF3432F"
59
+ BuildableName = "ControlKit-macOS-UITests.xctest"
60
+ BlueprintName = "ControlKit-macOS-UITests"
61
+ ReferencedContainer = "container:XCRSControlKitRunner.xcodeproj">
62
+ </BuildableReference>
63
+ </TestableReference>
64
+ </Testables>
65
+ </TestAction>
66
+ <LaunchAction
67
+ buildConfiguration = "Debug"
68
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
69
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
70
+ launchStyle = "0"
71
+ useCustomWorkingDirectory = "NO"
72
+ ignoresPersistentStateOnLaunch = "NO"
73
+ debugDocumentVersioning = "YES"
74
+ debugServiceExtension = "internal"
75
+ allowLocationSimulation = "YES">
76
+ <BuildableProductRunnable
77
+ runnableDebuggingMode = "0">
78
+ <BuildableReference
79
+ BuildableIdentifier = "primary"
80
+ BlueprintIdentifier = "5B67E51B3C9E09531D57616F"
81
+ BuildableName = "ControlKit.app"
82
+ BlueprintName = "ControlKit-macOS"
83
+ ReferencedContainer = "container:XCRSControlKitRunner.xcodeproj">
84
+ </BuildableReference>
85
+ </BuildableProductRunnable>
86
+ </LaunchAction>
87
+ <ProfileAction
88
+ buildConfiguration = "Release"
89
+ shouldUseLaunchSchemeArgsEnv = "YES"
90
+ savedToolIdentifier = ""
91
+ useCustomWorkingDirectory = "NO"
92
+ debugDocumentVersioning = "YES">
93
+ <BuildableProductRunnable
94
+ runnableDebuggingMode = "0">
95
+ <BuildableReference
96
+ BuildableIdentifier = "primary"
97
+ BlueprintIdentifier = "5B67E51B3C9E09531D57616F"
98
+ BuildableName = "ControlKit.app"
99
+ BlueprintName = "ControlKit-macOS"
100
+ ReferencedContainer = "container:XCRSControlKitRunner.xcodeproj">
101
+ </BuildableReference>
102
+ </BuildableProductRunnable>
103
+ </ProfileAction>
104
+ <AnalyzeAction
105
+ buildConfiguration = "Debug">
106
+ </AnalyzeAction>
107
+ <ArchiveAction
108
+ buildConfiguration = "Release"
109
+ revealArchiveInOrganizer = "YES">
110
+ </ArchiveAction>
111
+</Scheme>
Runners/XCRSControlKitRunner.xcodeproj/xcshareddata/xcschemes/ControlKit-watchOS.xcscheme
new
+111
@@ -0,0 +1,111 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<Scheme
3
+ LastUpgradeVersion = "1430"
4
+ version = "1.3">
5
+ <BuildAction
6
+ parallelizeBuildables = "YES"
7
+ buildImplicitDependencies = "YES">
8
+ <BuildActionEntries>
9
+ <BuildActionEntry
10
+ buildForTesting = "YES"
11
+ buildForRunning = "YES"
12
+ buildForProfiling = "YES"
13
+ buildForArchiving = "YES"
14
+ buildForAnalyzing = "YES">
15
+ <BuildableReference
16
+ BuildableIdentifier = "primary"
17
+ BlueprintIdentifier = "E85C2DCD1888C5276C1F13E4"
18
+ BuildableName = "ControlKit.app"
19
+ BlueprintName = "ControlKit-watchOS"
20
+ ReferencedContainer = "container:XCRSControlKitRunner.xcodeproj">
21
+ </BuildableReference>
22
+ </BuildActionEntry>
23
+ <BuildActionEntry
24
+ buildForTesting = "YES"
25
+ buildForRunning = "NO"
26
+ buildForProfiling = "NO"
27
+ buildForArchiving = "NO"
28
+ buildForAnalyzing = "NO">
29
+ <BuildableReference
30
+ BuildableIdentifier = "primary"
31
+ BlueprintIdentifier = "8A89960127FE4F8007E66449"
32
+ BuildableName = "ControlKit-watchOS-UITests.xctest"
33
+ BlueprintName = "ControlKit-watchOS-UITests"
34
+ ReferencedContainer = "container:XCRSControlKitRunner.xcodeproj">
35
+ </BuildableReference>
36
+ </BuildActionEntry>
37
+ </BuildActionEntries>
38
+ </BuildAction>
39
+ <TestAction
40
+ buildConfiguration = "Debug"
41
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
42
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
43
+ shouldUseLaunchSchemeArgsEnv = "YES">
44
+ <MacroExpansion>
45
+ <BuildableReference
46
+ BuildableIdentifier = "primary"
47
+ BlueprintIdentifier = "E85C2DCD1888C5276C1F13E4"
48
+ BuildableName = "ControlKit.app"
49
+ BlueprintName = "ControlKit-watchOS"
50
+ ReferencedContainer = "container:XCRSControlKitRunner.xcodeproj">
51
+ </BuildableReference>
52
+ </MacroExpansion>
53
+ <Testables>
54
+ <TestableReference
55
+ skipped = "NO">
56
+ <BuildableReference
57
+ BuildableIdentifier = "primary"
58
+ BlueprintIdentifier = "8A89960127FE4F8007E66449"
59
+ BuildableName = "ControlKit-watchOS-UITests.xctest"
60
+ BlueprintName = "ControlKit-watchOS-UITests"
61
+ ReferencedContainer = "container:XCRSControlKitRunner.xcodeproj">
62
+ </BuildableReference>
63
+ </TestableReference>
64
+ </Testables>
65
+ </TestAction>
66
+ <LaunchAction
67
+ buildConfiguration = "Debug"
68
+ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
69
+ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
70
+ launchStyle = "0"
71
+ useCustomWorkingDirectory = "NO"
72
+ ignoresPersistentStateOnLaunch = "NO"
73
+ debugDocumentVersioning = "YES"
74
+ debugServiceExtension = "internal"
75
+ allowLocationSimulation = "YES">
76
+ <BuildableProductRunnable
77
+ runnableDebuggingMode = "0">
78
+ <BuildableReference
79
+ BuildableIdentifier = "primary"
80
+ BlueprintIdentifier = "E85C2DCD1888C5276C1F13E4"
81
+ BuildableName = "ControlKit.app"
82
+ BlueprintName = "ControlKit-watchOS"
83
+ ReferencedContainer = "container:XCRSControlKitRunner.xcodeproj">
84
+ </BuildableReference>
85
+ </BuildableProductRunnable>
86
+ </LaunchAction>
87
+ <ProfileAction
88
+ buildConfiguration = "Release"
89
+ shouldUseLaunchSchemeArgsEnv = "YES"
90
+ savedToolIdentifier = ""
91
+ useCustomWorkingDirectory = "NO"
92
+ debugDocumentVersioning = "YES">
93
+ <BuildableProductRunnable
94
+ runnableDebuggingMode = "0">
95
+ <BuildableReference
96
+ BuildableIdentifier = "primary"
97
+ BlueprintIdentifier = "E85C2DCD1888C5276C1F13E4"
98
+ BuildableName = "ControlKit.app"
99
+ BlueprintName = "ControlKit-watchOS"
100
+ ReferencedContainer = "container:XCRSControlKitRunner.xcodeproj">
101
+ </BuildableReference>
102
+ </BuildableProductRunnable>
103
+ </ProfileAction>
104
+ <AnalyzeAction
105
+ buildConfiguration = "Debug">
106
+ </AnalyzeAction>
107
+ <ArchiveAction
108
+ buildConfiguration = "Release"
109
+ revealArchiveInOrganizer = "YES">
110
+ </ArchiveAction>
111
+</Scheme>
Runners/macOS/Assets.xcassets/AppIcon.appiconset/AppIcon-128x128.png
Binary files /dev/null and b/Runners/macOS/Assets.xcassets/AppIcon.appiconset/AppIcon-128x128.png differ
Runners/macOS/Assets.xcassets/AppIcon.appiconset/AppIcon-128x128@2x.png
Binary files /dev/null and b/Runners/macOS/Assets.xcassets/AppIcon.appiconset/AppIcon-128x128@2x.png differ
Runners/macOS/Assets.xcassets/AppIcon.appiconset/AppIcon-16x16.png
Binary files /dev/null and b/Runners/macOS/Assets.xcassets/AppIcon.appiconset/AppIcon-16x16.png differ
Runners/macOS/Assets.xcassets/AppIcon.appiconset/AppIcon-16x16@2x.png
Binary files /dev/null and b/Runners/macOS/Assets.xcassets/AppIcon.appiconset/AppIcon-16x16@2x.png differ
Runners/macOS/Assets.xcassets/AppIcon.appiconset/AppIcon-256x256.png
Binary files /dev/null and b/Runners/macOS/Assets.xcassets/AppIcon.appiconset/AppIcon-256x256.png differ
Runners/macOS/Assets.xcassets/AppIcon.appiconset/AppIcon-256x256@2x.png
Binary files /dev/null and b/Runners/macOS/Assets.xcassets/AppIcon.appiconset/AppIcon-256x256@2x.png differ
Runners/macOS/Assets.xcassets/AppIcon.appiconset/AppIcon-32x32.png
Binary files /dev/null and b/Runners/macOS/Assets.xcassets/AppIcon.appiconset/AppIcon-32x32.png differ
Runners/macOS/Assets.xcassets/AppIcon.appiconset/AppIcon-32x32@2x.png
Binary files /dev/null and b/Runners/macOS/Assets.xcassets/AppIcon.appiconset/AppIcon-32x32@2x.png differ
Runners/macOS/Assets.xcassets/AppIcon.appiconset/AppIcon-512x512.png
Binary files /dev/null and b/Runners/macOS/Assets.xcassets/AppIcon.appiconset/AppIcon-512x512.png differ
Runners/macOS/Assets.xcassets/AppIcon.appiconset/AppIcon-512x512@2x.png
Binary files /dev/null and b/Runners/macOS/Assets.xcassets/AppIcon.appiconset/AppIcon-512x512@2x.png differ
Runners/macOS/Assets.xcassets/AppIcon.appiconset/Contents.json
new
+68
@@ -0,0 +1,68 @@
1
+{
2
+ "images": [
3
+ {
4
+ "size": "16x16",
5
+ "idiom": "mac",
6
+ "filename": "AppIcon-16x16.png",
7
+ "scale": "1x"
8
+ },
9
+ {
10
+ "size": "16x16",
11
+ "idiom": "mac",
12
+ "filename": "AppIcon-16x16@2x.png",
13
+ "scale": "2x"
14
+ },
15
+ {
16
+ "size": "32x32",
17
+ "idiom": "mac",
18
+ "filename": "AppIcon-32x32.png",
19
+ "scale": "1x"
20
+ },
21
+ {
22
+ "size": "32x32",
23
+ "idiom": "mac",
24
+ "filename": "AppIcon-32x32@2x.png",
25
+ "scale": "2x"
26
+ },
27
+ {
28
+ "size": "128x128",
29
+ "idiom": "mac",
30
+ "filename": "AppIcon-128x128.png",
31
+ "scale": "1x"
32
+ },
33
+ {
34
+ "size": "128x128",
35
+ "idiom": "mac",
36
+ "filename": "AppIcon-128x128@2x.png",
37
+ "scale": "2x"
38
+ },
39
+ {
40
+ "size": "256x256",
41
+ "idiom": "mac",
42
+ "filename": "AppIcon-256x256.png",
43
+ "scale": "1x"
44
+ },
45
+ {
46
+ "size": "256x256",
47
+ "idiom": "mac",
48
+ "filename": "AppIcon-256x256@2x.png",
49
+ "scale": "2x"
50
+ },
51
+ {
52
+ "size": "512x512",
53
+ "idiom": "mac",
54
+ "filename": "AppIcon-512x512.png",
55
+ "scale": "1x"
56
+ },
57
+ {
58
+ "size": "512x512",
59
+ "idiom": "mac",
60
+ "filename": "AppIcon-512x512@2x.png",
61
+ "scale": "2x"
62
+ }
63
+ ],
64
+ "info": {
65
+ "author": "xcode",
66
+ "version": 1
67
+ }
68
+}
\ No newline at end of file
Runners/macOS/ControlKit-macOS-UITests.entitlements
new
+12
@@ -0,0 +1,12 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+<plist version="1.0">
4
+<dict>
5
+ <key>com.apple.security.app-sandbox</key>
6
+ <true/>
7
+ <key>com.apple.security.network.server</key>
8
+ <true/>
9
+ <key>com.apple.security.network.client</key>
10
+ <true/>
11
+</dict>
12
+</plist>
Runners/macOS/ControlKitRunnerApp.swift
new
+99
@@ -0,0 +1,99 @@
1
+import SwiftUI
2
+
3
+@main
4
+struct ControlKitRunnerApp: App {
5
+ var body: some Scene {
6
+ WindowGroup {
7
+ ControlKitShowcaseView()
8
+ }
9
+ .defaultSize(width: 820, height: 620)
10
+ }
11
+}
12
+
13
+private struct ControlKitShowcaseView: View {
14
+ private let repositoryURL = URL(string: "https://github.com/ondeinference/xcrs-controlkit")!
15
+
16
+ var body: some View {
17
+ ScrollView {
18
+ VStack(alignment: .leading, spacing: 28) {
19
+ HStack(spacing: 18) {
20
+ logo
21
+ VStack(alignment: .leading, spacing: 4) {
22
+ Text("ControlKit")
23
+ .font(.system(size: 40, weight: .bold, design: .rounded))
24
+ Text("Apple platform automation")
25
+ .font(.title3)
26
+ .foregroundStyle(.secondary)
27
+ }
28
+ }
29
+
30
+ Text("A clean-room runner for reliable black-box testing across Apple platforms.")
31
+ .font(.title2.weight(.medium))
32
+ .fixedSize(horizontal: false, vertical: true)
33
+
34
+ statusCard
35
+ informationCard
36
+
37
+ Link(destination: repositoryURL) {
38
+ Label("View project on GitHub", systemImage: "arrow.up.right")
39
+ .font(.headline)
40
+ .frame(maxWidth: .infinity)
41
+ }
42
+ .buttonStyle(.borderedProminent)
43
+ }
44
+ .padding(40)
45
+ .frame(maxWidth: 760, alignment: .leading)
46
+ }
47
+ .frame(minWidth: 640, minHeight: 480)
48
+ }
49
+
50
+ private var logo: some View {
51
+ Text("XC\nRS")
52
+ .font(.system(size: 30, weight: .black, design: .rounded))
53
+ .multilineTextAlignment(.center)
54
+ .lineSpacing(-8)
55
+ .foregroundStyle(Color.controlKitGreen)
56
+ .frame(width: 96, height: 96)
57
+ .background(Color.controlKitCream, in: RoundedRectangle(cornerRadius: 24))
58
+ }
59
+
60
+ private var statusCard: some View {
61
+ VStack(alignment: .leading, spacing: 14) {
62
+ Label("Runner online", systemImage: "checkmark.circle.fill")
63
+ .font(.headline)
64
+ .foregroundStyle(.green)
65
+ Text("The XCTest host is ready to receive ControlKit automation requests.")
66
+ .foregroundStyle(.secondary)
67
+ }
68
+ .padding(22)
69
+ .frame(maxWidth: .infinity, alignment: .leading)
70
+ .background(.thinMaterial, in: RoundedRectangle(cornerRadius: 20))
71
+ }
72
+
73
+ private var informationCard: some View {
74
+ VStack(alignment: .leading, spacing: 16) {
75
+ infoRow(title: "Project", value: "XCRSControlKit")
76
+ infoRow(title: "Creator", value: "smbCloud")
77
+ infoRow(title: "Platform", value: "macOS")
78
+ infoRow(title: "Purpose", value: "Native pointer and keyboard automation runner")
79
+ }
80
+ .padding(22)
81
+ .frame(maxWidth: .infinity, alignment: .leading)
82
+ .background(.thinMaterial, in: RoundedRectangle(cornerRadius: 20))
83
+ }
84
+
85
+ private func infoRow(title: String, value: String) -> some View {
86
+ HStack {
87
+ Text(title)
88
+ .foregroundStyle(.secondary)
89
+ Spacer()
90
+ Text(value)
91
+ .fontWeight(.semibold)
92
+ }
93
+ }
94
+}
95
+
96
+private extension Color {
97
+ static let controlKitGreen = Color(red: 0.106, green: 0.263, blue: 0.196)
98
+ static let controlKitCream = Color(red: 0.961, green: 0.953, blue: 0.925)
99
+}
Runners/macOS/README.md
new
+17
@@ -0,0 +1,17 @@
1
+# ControlKit macOS host app
2
+
3
+This folder holds the macOS host application (`ControlKitRunnerApp.swift` and
4
+`Assets.xcassets`) for the `ControlKit-macOS` target in the shared
5
+`XCRSControlKitRunner.xcodeproj`.
6
+
7
+macOS is pointer-driven: `device.io.click` performs an `XCUICoordinate` click and
8
+`device.io.text` types through the keyboard, while raw `device.io.tap` (touch),
9
+`home`, and orientation controls are intentionally unsupported. The JSON-RPC
10
+transport and server live in `../Shared` and are compiled into the
11
+`ControlKit-macOS-UITests` target.
12
+
13
+The generated XCUITest runner ships sandboxed with only the network *client*
14
+entitlement, so `ControlKit-macOS-UITests.entitlements` additionally grants
15
+`com.apple.security.network.server`, allowing the runner to bind its local RPC
16
+port. The targets sign locally (`CODE_SIGN_IDENTITY = "-"`), so no team or
17
+provisioning profile is required to build and test.
Runners/project.yml
+57
@@ -6,6 +6,8 @@ options:
6
iOS: "16.0"
7
tvOS: "16.0"
8
visionOS: "1.0"
9
+ macOS: "13.0"
10
+ watchOS: "9.0"
11
12
settings:
13
base:
@@ -103,6 +105,45 @@ targets:
105
platformName: visionOS
106
platformId: visionos
107
108
+ ControlKit-macOS:
109
+ templates: [Runner]
110
+ platform: macOS
111
+ templateAttributes:
112
+ platformDir: macOS
113
+ platformId: macos
114
+ settings:
115
+ base:
116
+ ASSETCATALOG_COMPILER_APPICON_NAME: AppIcon
117
+ CODE_SIGN_IDENTITY: "-"
118
+ ENABLE_HARDENED_RUNTIME: NO
119
+ ControlKit-macOS-UITests:
120
+ templates: [UITests]
121
+ platform: macOS
122
+ templateAttributes:
123
+ platformName: macOS
124
+ platformId: macos
125
+ settings:
126
+ base:
127
+ CODE_SIGN_IDENTITY: "-"
128
+ CODE_SIGN_ENTITLEMENTS: macOS/ControlKit-macOS-UITests.entitlements
129
+
130
+ ControlKit-watchOS:
131
+ templates: [Runner]
132
+ platform: watchOS
133
+ templateAttributes:
134
+ platformDir: watchOS
135
+ platformId: watchos
136
+ settings:
137
+ base:
138
+ TARGETED_DEVICE_FAMILY: "4"
139
+ ASSETCATALOG_COMPILER_APPICON_NAME: AppIcon
140
+ ControlKit-watchOS-UITests:
141
+ templates: [UITests]
142
+ platform: watchOS
143
+ templateAttributes:
144
+ platformName: watchOS
145
+ platformId: watchos
146
+
147
schemes:
148
ControlKit-iOS:
149
build:
@@ -128,3 +169,19 @@ schemes:
169
test:
170
targets:
171
- ControlKit-visionOS-UITests
172
+ ControlKit-macOS:
173
+ build:
174
+ targets:
175
+ ControlKit-macOS: all
176
+ ControlKit-macOS-UITests: [test]
177
+ test:
178
+ targets:
179
+ - ControlKit-macOS-UITests
180
+ ControlKit-watchOS:
181
+ build:
182
+ targets:
183
+ ControlKit-watchOS: all
184
+ ControlKit-watchOS-UITests: [test]
185
+ test:
186
+ targets:
187
+ - ControlKit-watchOS-UITests
Runners/watchOS/Assets.xcassets/AppIcon.appiconset/AppIcon-1024.png
Binary files /dev/null and b/Runners/watchOS/Assets.xcassets/AppIcon.appiconset/AppIcon-1024.png differ
Runners/watchOS/Assets.xcassets/AppIcon.appiconset/Contents.json
new
+14
@@ -0,0 +1,14 @@
1
+{
2
+ "images": [
3
+ {
4
+ "filename": "AppIcon-1024.png",
5
+ "idiom": "universal",
6
+ "platform": "watchos",
7
+ "size": "1024x1024"
8
+ }
9
+ ],
10
+ "info": {
11
+ "author": "xcode",
12
+ "version": 1
13
+ }
14
+}
\ No newline at end of file
Runners/watchOS/Assets.xcassets/Contents.json
new
+6
@@ -0,0 +1,6 @@
1
+{
2
+ "info": {
3
+ "author": "xcode",
4
+ "version": 1
5
+ }
6
+}
\ No newline at end of file
Runners/watchOS/ControlKitRunnerApp.swift
new
+86
@@ -0,0 +1,86 @@
1
+import SwiftUI
2
+
3
+@main
4
+struct ControlKitRunnerApp: App {
5
+ var body: some Scene {
6
+ WindowGroup {
7
+ ControlKitShowcaseView()
8
+ }
9
+ }
10
+}
11
+
12
+private struct ControlKitShowcaseView: View {
13
+ var body: some View {
14
+ ScrollView {
15
+ VStack(alignment: .leading, spacing: 12) {
16
+ HStack(spacing: 10) {
17
+ logo
18
+ VStack(alignment: .leading, spacing: 2) {
19
+ Text("ControlKit")
20
+ .font(.headline)
21
+ Text("watchOS")
22
+ .font(.caption2)
23
+ .foregroundStyle(.secondary)
24
+ }
25
+ }
26
+
27
+ statusCard
28
+ informationCard
29
+ }
30
+ .padding(12)
31
+ }
32
+ .background(Color.controlKitGreen.ignoresSafeArea())
33
+ .foregroundStyle(Color.controlKitCream)
34
+ }
35
+
36
+ private var logo: some View {
37
+ Text("XC\nRS")
38
+ .font(.system(size: 14, weight: .black, design: .rounded))
39
+ .multilineTextAlignment(.center)
40
+ .lineSpacing(-3)
41
+ .foregroundStyle(Color.controlKitGreen)
42
+ .frame(width: 40, height: 40)
43
+ .background(Color.controlKitCream, in: RoundedRectangle(cornerRadius: 10))
44
+ }
45
+
46
+ private var statusCard: some View {
47
+ VStack(alignment: .leading, spacing: 6) {
48
+ Label("Runner online", systemImage: "checkmark.circle.fill")
49
+ .font(.footnote)
50
+ .foregroundStyle(.green)
51
+ Text("Ready for ControlKit automation requests.")
52
+ .font(.caption2)
53
+ .foregroundStyle(Color.controlKitCream.opacity(0.78))
54
+ }
55
+ .padding(12)
56
+ .frame(maxWidth: .infinity, alignment: .leading)
57
+ .background(.white.opacity(0.1), in: RoundedRectangle(cornerRadius: 14))
58
+ }
59
+
60
+ private var informationCard: some View {
61
+ VStack(alignment: .leading, spacing: 8) {
62
+ infoRow(title: "Project", value: "XCRSControlKit")
63
+ infoRow(title: "Creator", value: "smbCloud")
64
+ infoRow(title: "Purpose", value: "Companion automation runner")
65
+ }
66
+ .padding(12)
67
+ .frame(maxWidth: .infinity, alignment: .leading)
68
+ .background(.white.opacity(0.08), in: RoundedRectangle(cornerRadius: 14))
69
+ }
70
+
71
+ private func infoRow(title: String, value: String) -> some View {
72
+ VStack(alignment: .leading, spacing: 1) {
73
+ Text(title)
74
+ .font(.caption2)
75
+ .foregroundStyle(Color.controlKitCream.opacity(0.62))
76
+ Text(value)
77
+ .font(.caption)
78
+ .fontWeight(.semibold)
79
+ }
80
+ }
81
+}
82
+
83
+private extension Color {
84
+ static let controlKitGreen = Color(red: 0.106, green: 0.263, blue: 0.196)
85
+ static let controlKitCream = Color(red: 0.961, green: 0.953, blue: 0.925)
86
+}
Runners/watchOS/README.md
new
+13
@@ -0,0 +1,13 @@
1
+# ControlKit watchOS host app
2
+
3
+This folder holds the watchOS host application (`ControlKitRunnerApp.swift` and
4
+`Assets.xcassets`) for the `ControlKit-watchOS` target in the shared
5
+`XCRSControlKitRunner.xcodeproj`.
6
+
7
+watchOS UI testing is supported from Xcode 26 onward (the platform ships
8
+`XCUIAutomation.framework`). Touch input is delivered through `XCUICoordinate`
9
+taps; `device.capabilities` reports the paired-device profile
10
+(`accessibility`, `appLifecycle`, `pairedDevice`, `screenshot`), and pointer,
11
+spatial, `home`, and remote-button interactions are intentionally unsupported.
12
+The JSON-RPC transport and server live in `../Shared` and are compiled into the
13
+`ControlKit-watchOS-UITests` target.