Skip to content

Commit 07e7008

Browse files
authored
Support Xcode 15's separate runtime bundles (#115)
* Enable tabs in the Xcode project file * Support Xcode 15's separate runtime bundles Added a runtimeBundleURL parameter to +[SimUtils launchDaemonPlistURLForDaemon:] to pass the simulator runtime URL dynamically rather than assuming the runtime is within Xcode
1 parent ce3b921 commit 07e7008

File tree

10 files changed

+60
-51
lines changed

10 files changed

+60
-51
lines changed

applesimutils/applesimutils.xcodeproj/project.pbxproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@
164164
391EBF361E91212B0009AACD /* Frameworks */,
165165
);
166166
sourceTree = "<group>";
167+
usesTabs = 1;
167168
};
168169
391596DD1E8CBAA900FDD6F5 /* Products */ = {
169170
isa = PBXGroup;

applesimutils/applesimutils/ClearKeychain.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@
88

99
#import <Foundation/Foundation.h>
1010

11-
extern NSURL* securitydURL(void);
11+
extern NSURL* securitydURL(NSURL* runtimeBundleURL);
1212

13-
extern void performClearKeychainPass(NSString* simulatorIdentifier);
13+
extern void performClearKeychainPass(NSString* simulatorIdentifier, NSURL* runtimeBundleURL);

applesimutils/applesimutils/ClearKeychain.m

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,19 @@
99
#import "ClearKeychain.h"
1010
#import "SimUtils.h"
1111

12-
extern NSURL* securitydURL(void)
12+
extern NSURL* securitydURL(NSURL* runtimeBundleURL)
1313
{
1414
static NSURL *securitydDaemonURL;
1515
static dispatch_once_t onceToken;
1616
dispatch_once(&onceToken, ^{
17-
securitydDaemonURL = [SimUtils launchDaemonPlistURLForDaemon:@"com.apple.securityd"];
17+
securitydDaemonURL = [SimUtils launchDaemonPlistURLForDaemon:@"com.apple.securityd" runtimeBundleURL:runtimeBundleURL];
1818
});
1919
return securitydDaemonURL;
2020
}
2121

22-
static void securitydCtl(NSString* simulatorId, BOOL stop)
22+
static void securitydCtl(NSString* simulatorId, NSURL* runtimeBundleURL, BOOL stop)
2323
{
24-
NSURL *locationdDaemonURL = securitydURL();
24+
NSURL *locationdDaemonURL = securitydURL(runtimeBundleURL);
2525
NSCAssert(locationdDaemonURL != nil, @"Launch daemon “com.apple.securityd” not found. Please open an issue.");
2626

2727
NSTask* rebootTask = [NSTask new];
@@ -31,14 +31,14 @@ static void securitydCtl(NSString* simulatorId, BOOL stop)
3131
[rebootTask waitUntilExit];
3232
}
3333

34-
void performClearKeychainPass(NSString* simulatorIdentifier)
34+
void performClearKeychainPass(NSString* simulatorIdentifier, NSURL* runtimeBundleURL)
3535
{
36-
securitydCtl(simulatorIdentifier, YES);
36+
securitydCtl(simulatorIdentifier, runtimeBundleURL, YES);
3737

3838
NSURL* keychainDirURL = [[SimUtils libraryURLForSimulatorId:simulatorIdentifier] URLByAppendingPathComponent:@"Keychains"];
3939
[[NSFileManager.defaultManager contentsOfDirectoryAtURL:keychainDirURL includingPropertiesForKeys:nil options:0 error:NULL] enumerateObjectsUsingBlock:^(NSURL * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
4040
[NSFileManager.defaultManager removeItemAtURL:obj error:NULL];
4141
}];
4242

43-
securitydCtl(simulatorIdentifier, NO);
43+
securitydCtl(simulatorIdentifier, runtimeBundleURL, NO);
4444
}

applesimutils/applesimutils/ClearMedia.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@
88

99
#import <Foundation/Foundation.h>
1010

11-
extern void performClearMediaPass(NSString* simulatorIdentifier);
11+
extern void performClearMediaPass(NSString* simulatorIdentifier, NSURL* runtimeBundleURL);

applesimutils/applesimutils/ClearMedia.m

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,19 @@
99
#import "ClearMedia.h"
1010
#import "SimUtils.h"
1111

12-
extern NSURL* assetsdURL(void)
12+
extern NSURL* assetsdURL(NSURL* runtimeBundleURL)
1313
{
1414
static NSURL *assetsdURL;
1515
static dispatch_once_t onceToken;
1616
dispatch_once(&onceToken, ^{
17-
assetsdURL = [SimUtils launchDaemonPlistURLForDaemon:@"com.apple.assetsd"];
17+
assetsdURL = [SimUtils launchDaemonPlistURLForDaemon:@"com.apple.assetsd" runtimeBundleURL:runtimeBundleURL];
1818
});
1919
return assetsdURL;
2020
}
2121

22-
static void assetsdCtl(NSString* simulatorId, BOOL stop)
22+
static void assetsdCtl(NSString* simulatorId, NSURL* runtimeBundleURL, BOOL stop)
2323
{
24-
NSURL *locationdDaemonURL = assetsdURL();
24+
NSURL *locationdDaemonURL = assetsdURL(runtimeBundleURL);
2525
NSCAssert(locationdDaemonURL != nil, @"Launch daemon “com.apple.mobileassetd” not found. Please open an issue.");
2626

2727
NSTask* rebootTask = [NSTask new];
@@ -31,11 +31,11 @@ static void assetsdCtl(NSString* simulatorId, BOOL stop)
3131
[rebootTask waitUntilExit];
3232
}
3333

34-
void performClearMediaPass(NSString* simulatorIdentifier)
34+
void performClearMediaPass(NSString* simulatorIdentifier, NSURL* runtimeBundleURL)
3535
{
36-
assetsdCtl(simulatorIdentifier, YES);
36+
assetsdCtl(simulatorIdentifier, runtimeBundleURL, YES);
3737
NSURL* mediaURL = [[SimUtils dataURLForSimulatorId:simulatorIdentifier] URLByAppendingPathComponent:@"Media"];
3838
[NSFileManager.defaultManager removeItemAtURL:[mediaURL URLByAppendingPathComponent:@"DCIM"] error:NULL];
3939
[NSFileManager.defaultManager removeItemAtURL:[mediaURL URLByAppendingPathComponent:@"PhotoData"] error:NULL];
40-
assetsdCtl(simulatorIdentifier, NO);
40+
assetsdCtl(simulatorIdentifier, runtimeBundleURL, NO);
4141
}

applesimutils/applesimutils/SetLocationPermission.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010

1111
@interface SetLocationPermission : NSObject
1212

13-
+ (NSURL*)locationdURL;
13+
+ (NSURL*)locationdURLForRuntimeBundleURL:(NSURL*)runtimeBundleURL;
1414

15-
+ (BOOL)setLocationPermission:(NSString*)permission forBundleIdentifier:(NSString*)bundleIdentifier simulatorIdentifier:(NSString*)simulatorId error:(NSError**)error;
15+
+ (BOOL)setLocationPermission:(NSString*)permission forBundleIdentifier:(NSString*)bundleIdentifier simulatorIdentifier:(NSString*)simulatorId runtimeBundleURL:(NSURL*)runtimeBundleURL error:(NSError**)error;
1616

1717
@end

applesimutils/applesimutils/SetLocationPermission.m

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
#import "SetLocationPermission.h"
1010
#import "SimUtils.h"
1111

12-
static void startStopLocationdCtl(NSString* simulatorId, BOOL stop)
12+
static void startStopLocationdCtl(NSString* simulatorId, NSURL* runtimeBundleURL, BOOL stop)
1313
{
14-
NSURL *locationdDaemonURL = [SetLocationPermission locationdURL];
14+
NSURL *locationdDaemonURL = [SetLocationPermission locationdURLForRuntimeBundleURL:runtimeBundleURL];
1515
NSCAssert(locationdDaemonURL != nil, @"Launch daemon “com.apple.locationd” not found. Please open an issue.");
1616

1717
NSTask* rebootTask = [NSTask new];
@@ -23,17 +23,17 @@ static void startStopLocationdCtl(NSString* simulatorId, BOOL stop)
2323

2424
@implementation SetLocationPermission
2525

26-
+ (NSURL*)locationdURL
26+
+ (NSURL*)locationdURLForRuntimeBundleURL:(NSURL*)runtimeBundleURL
2727
{
2828
static NSURL *locationdDaemonURL;
2929
static dispatch_once_t onceToken;
3030
dispatch_once(&onceToken, ^{
31-
locationdDaemonURL = [SimUtils launchDaemonPlistURLForDaemon:@"com.apple.locationd"];
31+
locationdDaemonURL = [SimUtils launchDaemonPlistURLForDaemon:@"com.apple.locationd" runtimeBundleURL:runtimeBundleURL];
3232
});
3333
return locationdDaemonURL;
3434
}
3535

36-
+ (BOOL)setLocationPermission:(NSString*)permission forBundleIdentifier:(NSString*)bundleIdentifier simulatorIdentifier:(NSString*)simulatorId error:(NSError**)error
36+
+ (BOOL)setLocationPermission:(NSString*)permission forBundleIdentifier:(NSString*)bundleIdentifier simulatorIdentifier:(NSString*)simulatorId runtimeBundleURL:(NSURL*)runtimeBundleURL error:(NSError**)error
3737
{
3838
LNLog(LNLogLevelDebug, @"Setting location permission");
3939

@@ -86,11 +86,11 @@ + (BOOL)setLocationPermission:(NSString*)permission forBundleIdentifier:(NSStrin
8686
locationClients[bundleIdentifier] = bundlePermissions;
8787
}
8888

89-
startStopLocationdCtl(simulatorId, YES);
89+
startStopLocationdCtl(simulatorId, runtimeBundleURL, YES);
9090

9191
[[NSPropertyListSerialization dataWithPropertyList:locationClients format:NSPropertyListBinaryFormat_v1_0 options:0 error:NULL] writeToURL:plistURL atomically:YES];
9292

93-
startStopLocationdCtl(simulatorId, NO);
93+
startStopLocationdCtl(simulatorId, runtimeBundleURL, NO);
9494

9595
return YES;
9696
}

applesimutils/applesimutils/SimUtils.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ extern const NSTimeInterval AppleSimUtilsRetryTimeout;
1818
+ (NSURL*)dataURLForSimulatorId:(NSString*)simulatorId;
1919
+ (NSURL*)libraryURLForSimulatorId:(NSString*)simulatorId;
2020
+ (NSURL*)binaryURLForBundleId:(NSString*)bundleId simulatorId:(NSString*)simulatorId;
21-
+ (NSURL*)launchDaemonPlistURLForDaemon:(NSString*)daemon;
21+
+ (NSURL*)launchDaemonPlistURLForDaemon:(NSString*)daemon runtimeBundleURL:(NSURL*)runtimeBundleURL;
2222
+ (void)restartSpringBoardForSimulatorId:(NSString*)simulatorId;
2323

2424
+ (void)registerCleanupBlock:(dispatch_block_t)block;

applesimutils/applesimutils/SimUtils.m

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -117,37 +117,42 @@ + (NSURL *)binaryURLForBundleId:(NSString*)bundleId simulatorId:(NSString*)simul
117117
return [bundleURL URLByAppendingPathComponent:executableName];
118118
}
119119

120-
+ (NSURL*)launchDaemonPlistURLForDaemon:(NSString*)daemon
120+
+ (NSURL*)launchDaemonPlistURLForDaemon:(NSString*)daemon runtimeBundleURL:(NSURL*)runtimeBundleURL
121121
{
122122
if([daemon hasSuffix:@".plist"] == NO)
123123
{
124124
daemon = [daemon stringByAppendingString:@".plist"];
125125
}
126-
127-
NSFileManager *fileManager = [NSFileManager defaultManager];
128-
NSURL* developerTools = [SimUtils developerURL];
129-
126+
127+
//Xcode 14 and 15 (using runtimeBundleURL)
128+
NSURL *daemonURL = [runtimeBundleURL URLByAppendingPathComponent:[NSString stringWithFormat:@"Contents/Resources/RuntimeRoot/System/Library/LaunchDaemons/%@", daemon]];
129+
130130
//Xcode 11
131-
NSURL *locationdDaemonURL = [developerTools URLByAppendingPathComponent:[NSString stringWithFormat:@"Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/System/Library/LaunchDaemons/%@", daemon]];
132-
131+
NSURL* developerTools = [SimUtils developerURL];
132+
133+
if ([daemonURL checkResourceIsReachableAndReturnError:NULL] == NO)
134+
{
135+
daemonURL = [developerTools URLByAppendingPathComponent:[NSString stringWithFormat:@"Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/System/Library/LaunchDaemons/%@", daemon]];
136+
}
137+
133138
//Xcode 9
134-
if ([fileManager fileExistsAtPath:locationdDaemonURL.path] == NO)
139+
if ([daemonURL checkResourceIsReachableAndReturnError:NULL] == NO)
135140
{
136-
locationdDaemonURL = [developerTools URLByAppendingPathComponent:[NSString stringWithFormat:@"Platforms/iPhoneOS.platform/Developer/Library/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/System/Library/LaunchDaemons/%@", daemon]];
141+
daemonURL = [developerTools URLByAppendingPathComponent:[NSString stringWithFormat:@"Platforms/iPhoneOS.platform/Developer/Library/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/System/Library/LaunchDaemons/%@", daemon]];
137142
}
138-
143+
139144
//Older
140-
if ([fileManager fileExistsAtPath:locationdDaemonURL.path] == NO)
145+
if ([daemonURL checkResourceIsReachableAndReturnError:NULL] == NO)
141146
{
142-
locationdDaemonURL = [developerTools URLByAppendingPathComponent:[NSString stringWithFormat:@"Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/System/Library/LaunchDaemons/%@", daemon]];
147+
daemonURL = [developerTools URLByAppendingPathComponent:[NSString stringWithFormat:@"Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/System/Library/LaunchDaemons/%@", daemon]];
143148
}
144-
145-
if ([fileManager fileExistsAtPath:locationdDaemonURL.path] == NO)
149+
150+
if ([daemonURL checkResourceIsReachableAndReturnError:NULL] == NO)
146151
{
147152
return nil;
148153
}
149154

150-
return locationdDaemonURL;
155+
return daemonURL;
151156
}
152157

153158
+ (void)restartSpringBoardForSimulatorId:(NSString*)simulatorId
@@ -171,7 +176,7 @@ + (void)registerCleanupBlock:(dispatch_block_t)block
171176
}
172177

173178
__attribute__((destructor))
174-
static void cleanup()
179+
static void cleanup(void)
175180
{
176181
[_blocks enumerateObjectsUsingBlock:^(dispatch_block_t _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
177182
obj();

applesimutils/applesimutils/main.m

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ static void shutdownSimulator(NSString* simulatorId)
5656
[shutdownTask waitUntilExit];
5757
}
5858

59-
static NSArray* simulatorDevicesList()
59+
static NSArray* simulatorDevicesList(void)
6060
{
6161
LNLog(LNLogLevelDebug, @"Obtaining simulator device list");
6262

@@ -114,7 +114,7 @@ static void shutdownSimulator(NSString* simulatorId)
114114
return allDevices;
115115
}
116116

117-
static NSPredicate* predicateByBooted()
117+
static NSPredicate* predicateByBooted(void)
118118
{
119119
return [NSPredicate predicateWithFormat:@"state ==[c] %@", @"Booted"];
120120
}
@@ -274,6 +274,7 @@ static BOOL performPermissionsPass(NSString* permissionsArgument, NSString* simu
274274
@"speech": @"kTCCServiceSpeechRecognition",
275275
@"userTracking": @"kTCCServiceUserTracking",
276276
};
277+
NSURL *runtimeBundleURL = [NSURL fileURLWithPath:simulator[@"os"][@"bundlePath"]];
277278

278279
NSArray<NSString*>* parsedArguments = [permissionsArgument componentsSeparatedByString:@","];
279280

@@ -317,7 +318,7 @@ static BOOL performPermissionsPass(NSString* permissionsArgument, NSString* simu
317318
{
318319
assertStringInArrayValues(value, @[@"never", @"always", @"inuse", @"unset"], -10, [NSString stringWithFormat:@"Error: Illegal value “%@” parsed for permission “%@”.", value, permission]);
319320

320-
success = [SetLocationPermission setLocationPermission:value forBundleIdentifier:bundleIdentifier simulatorIdentifier:simulatorIdentifier error:&err];
321+
success = [SetLocationPermission setLocationPermission:value forBundleIdentifier:bundleIdentifier simulatorIdentifier:simulatorIdentifier runtimeBundleURL:runtimeBundleURL error:&err];
321322

322323
needsSpringBoardRestart |= NO;
323324
}
@@ -640,7 +641,8 @@ int main(int argc, const char* argv[]) {
640641
{
641642
[filteredSimulators enumerateObjectsUsingBlock:^(NSDictionary* _Nonnull simulator, NSUInteger idx, BOOL * _Nonnull stop) {
642643
NSString* simulatorId = simulator[@"udid"];
643-
644+
NSURL *runtimeBundleURL = [NSURL fileURLWithPath:simulator[@"os"][@"bundlePath"]];
645+
644646
NSString* title = [NSString stringWithFormat:@"%@ (%@, %@)", simulator[@"name"], simulatorId, simulator[@"state"]];
645647
NSString* underline = [@"" stringByPaddingToLength:title.length withString:@"-" startingAtIndex:0];
646648
LNLog(LNLogLevelStdOut, @"%@\n%@", title, underline);
@@ -676,13 +678,13 @@ int main(int argc, const char* argv[]) {
676678
simPaths[@"TCC Database Path"] = [url URLByAppendingPathComponent:@"TCC/TCC.db"].path;
677679
}
678680

679-
url = [SetLocationPermission locationdURL];
681+
url = [SetLocationPermission locationdURLForRuntimeBundleURL:runtimeBundleURL];
680682
if(url.path != nil)
681683
{
682684
simPaths[@"locationd Daemon Info Plist Path"] = url.path;
683685
}
684686

685-
url = securitydURL();
687+
url = securitydURL(runtimeBundleURL);
686688
if(url.path != nil)
687689
{
688690
simPaths[@"securityd Daemon Info Plist Path"] = url.path;
@@ -742,6 +744,7 @@ int main(int argc, const char* argv[]) {
742744

743745
[filteredSimulators enumerateObjectsUsingBlock:^(NSDictionary* _Nonnull simulator, NSUInteger idx, BOOL * _Nonnull stop) {
744746
NSString* simulatorId = simulator[@"udid"];
747+
NSURL *runtimeBundleURL = [NSURL fileURLWithPath:simulator[@"os"][@"bundlePath"]];
745748

746749
BOOL needsSimShutdown = NO;
747750
if([simulator[@"state"] isEqualToString:@"Shutdown"] && [settings objectForKey:@"setPermissions"] != nil)
@@ -769,14 +772,14 @@ int main(int argc, const char* argv[]) {
769772

770773
if([settings boolForKey:@"clearKeychain"])
771774
{
772-
performClearKeychainPass(simulatorId);
775+
performClearKeychainPass(simulatorId, runtimeBundleURL);
773776

774777
needsSpringBoardRestart = YES;
775778
}
776779

777780
if([settings boolForKey:@"clearMedia"])
778781
{
779-
performClearMediaPass(simulatorId);
782+
performClearMediaPass(simulatorId, runtimeBundleURL);
780783

781784
needsSpringBoardRestart = YES;
782785
}

0 commit comments

Comments
 (0)