Add a command to check whether a device has enabled developer mode. D… (#563)
Retry of #556 that guards the developer mode check by a preprocessor define so that it is not build by default. Developer mode requires a MobileDevice method introduced with Xcode 14 so including it by default will break builds where Xcode 14 is unavailable.
diff --git a/README.md b/README.md
index 592d6b0..772f7f8 100644
--- a/README.md
+++ b/README.md
@@ -66,8 +66,8 @@
-m, --noinstall directly start debugging without app install (-d not required)
-A, --app_deltas incremental install. must specify a directory to store app deltas to determine what needs to be installed
-p, --port <number> port used for device, default: dynamic
- -r, --uninstall uninstall the app before install (do not use with -m; app cache and data are cleared)
- -9, --uninstall_only uninstall the app ONLY. Use only with -1 <bundle_id>
+ -r, --uninstall uninstall the app before install (do not use with -m; app cache and data are cleared)
+ -9, --uninstall_only uninstall the app ONLY. Use only with -1 <bundle_id>
-1, --bundle_id <bundle id> specify bundle id for list and upload
-l, --list[=<dir>] list all app files or the specified directory
-o, --upload <file> upload file
@@ -76,18 +76,28 @@
-D, --mkdir <dir> make directory on device
-R, --rm <path> remove file or directory on device (directories must be empty)
-X, --rmtree <path> remove directory and all contained files recursively on device
- -V, --version print the executable version
- -e, --exists check if the app with given bundle_id is installed or not
- -B, --list_bundle_id list bundle_id
+ -V, --version print the executable version
+ -e, --exists check if the app with given bundle_id is installed or not
+ -B, --list_bundle_id list bundle_id
-W, --no-wifi ignore wifi devices
- -C, --get_battery_level get battery current capacity
+ -C, --get_battery_level get battery current capacity
-O, --output <file> write stdout to this file
-E, --error_output <file> write stderr to this file
--detect_deadlocks <sec> start printing backtraces for all threads periodically after specific amount of seconds
-f, --file_system specify file system for mkdir / list / upload / download / rm
- -k, --key keys for the properties of the bundle. Joined by ',' and used only with -B <list_bundle_id> and -j <json>
-F, --non-recursively specify non-recursively walk directory
+ -S, --symbols download OS symbols. must specify a directory to store the downloaded symbols
-j, --json format output as JSON
+ -k, --key keys for the properties of the bundle. Joined by ',' and used only with -B <list_bundle_id> and -j <json>
+ --custom-script <script> path to custom python script to execute in lldb
+ --custom-command <command> specify additional lldb commands to execute
+ --faster-path-search use alternative logic to find the device support paths faster
+ -P, --list_profiles list all provisioning profiles on device
+ --profile-uuid <uuid> the UUID of the provisioning profile to target, use with other profile commands
+ --profile-download <path> download a provisioning profile (requires --profile-uuid)
+ --profile-install <file> install a provisioning profile
+ --profile-uninstall uninstall a provisioning profile (requires --profile-uuid <UUID>)
+ --check-developer-mode checks whether the given device has developer mode enabled (Requires Xcode 14 or newer)
## Examples
diff --git a/src/ios-deploy/ios-deploy.m b/src/ios-deploy/ios-deploy.m
index 7c281ee..0e4536a 100644
--- a/src/ios-deploy/ios-deploy.m
+++ b/src/ios-deploy/ios-deploy.m
@@ -91,6 +91,9 @@
mach_error_t AMDeviceLookupApplications(AMDeviceRef device, CFDictionaryRef options, CFDictionaryRef *result);
int AMDeviceGetInterfaceType(AMDeviceRef device);
AMDeviceRef AMDeviceCopyPairedCompanion(AMDeviceRef device);
+#if defined(IOS_DEPLOY_FEATURE_DEVELOPER_MODE)
+unsigned int AMDeviceCopyDeveloperModeStatus(AMDeviceRef device, uint32_t *error_code);
+#endif
int AMDServiceConnectionSend(ServiceConnRef con, const void * data, size_t size);
int AMDServiceConnectionReceive(ServiceConnRef con, void * data, size_t size);
@@ -2289,6 +2292,34 @@
}
}
+#if defined(IOS_DEPLOY_FEATURE_DEVELOPER_MODE)
+void check_developer_mode(AMDeviceRef device) {
+ unsigned int error_code = 0;
+ bool is_enabled = AMDeviceCopyDeveloperModeStatus(device, &error_code);
+
+ if (error_code) {
+ const char *mobdev_error = get_error_message(error_code);
+ NSString *error_description = mobdev_error ? [NSString stringWithUTF8String:mobdev_error] : @"unknown.";
+ if (_json_output) {
+ NSLogJSON(@{
+ @"Event": @"DeveloperMode",
+ @"IsEnabled": @(is_enabled),
+ @"Code": @(error_code),
+ @"Status": error_description,
+ });
+ } else {
+ NSLogOut(@"Encountered error checking developer mode status: %@", error_description);
+ }
+ } else {
+ if (_json_output) {
+ NSLogJSON(@{@"Event": @"DeveloperMode", @"IsEnabled": @(is_enabled)});
+ } else {
+ NSLogOut(@"Developer mode is%s enabled.", is_enabled ? "" : " not");
+ }
+ }
+}
+#endif
+
void start_symbols_service_with_command(AMDeviceRef device, uint32_t command) {
connect_and_start_session(device);
check_error(AMDeviceSecureStartService(device, symbols_service_name,
@@ -2608,7 +2639,11 @@
uninstall_provisioning_profile(device);
} else if (strcmp("download_profile", command) == 0) {
download_provisioning_profile(device);
- }
+#if defined(IOS_DEPLOY_FEATURE_DEVELOPER_MODE)
+ } else if (strcmp("check_developer_mode", command) == 0) {
+ check_developer_mode(device);
+#endif
+ }
exit(0);
}
@@ -2874,7 +2909,12 @@
@" --profile-uuid <uuid> the UUID of the provisioning profile to target, use with other profile commands\n"
@" --profile-download <path> download a provisioning profile (requires --profile-uuid)\n"
@" --profile-install <file> install a provisioning profile\n"
- @" --profile-uninstall uninstall a provisioning profile (requires --profile-uuid <UUID>)\n",
+ @" --profile-uninstall uninstall a provisioning profile (requires --profile-uuid <UUID>)\n"
+#if defined(IOS_DEPLOY_FEATURE_DEVELOPER_MODE)
+ @" --check-developer-mode checks whether the given device has developer mode enabled (requires Xcode 14 or newer)\n",
+#else
+ ,
+#endif
[NSString stringWithUTF8String:app]);
}
@@ -2940,6 +2980,9 @@
{ "profile-uninstall", no_argument, NULL, 1005},
{ "profile-download", required_argument, NULL, 1006},
{ "profile-uuid", required_argument, NULL, 1007},
+#if defined(IOS_DEPLOY_FEATURE_DEVELOPER_MODE)
+ { "check-developer-mode", no_argument, NULL, 1008},
+#endif
{ NULL, 0, NULL, 0 },
};
int ch;
@@ -3115,6 +3158,12 @@
case 1007:
profile_uuid = optarg;
break;
+#if defined(IOS_DEPLOY_FEATURE_DEVELOPER_MODE)
+ case 1008:
+ command_only = true;
+ command = "check_developer_mode";
+ break;
+#endif
case 'P':
command_only = true;
command = "list_profiles";