diff --git a/lib/subcommands/index.js b/lib/subcommands/index.js index 79ae0eb..1fb2c8b 100644 --- a/lib/subcommands/index.js +++ b/lib/subcommands/index.js @@ -22,6 +22,7 @@ import spawnCommands from './spawn'; import terminateCommands from './terminate'; import uiCommands from './ui'; import uninstallCommands from './uninstall'; +import locationCommands from './location'; // xcrun simctl --help const subcommands = Object.assign({}, @@ -49,6 +50,7 @@ const subcommands = Object.assign({}, terminateCommands, uiCommands, uninstallCommands, + locationCommands, ); export default subcommands; diff --git a/lib/subcommands/location.js b/lib/subcommands/location.js new file mode 100644 index 0000000..23885b2 --- /dev/null +++ b/lib/subcommands/location.js @@ -0,0 +1,46 @@ +const commands = {}; + +/** + * Formats the given location argument for simctl usage + * + * @param {string} name Argument name + * @param {string|number} value Location argument value + * @returns {string} Formatted value, for example -73.768254 + */ +function formatArg (name, value) { + const flt = parseFloat(value); + if (isNaN(flt)) { + throw new TypeError(`${name} must be a valid number, got '${value}' instead`); + } + return flt.toFixed(7); +} + +/** + * Set the Simulator location to a specific latitude and longitude. + * This functionality is only available since Xcode 14. + * + * @param {string|number} latitude Location latitude value + * @param {string|number} longitude Location longitude value + * @throws {Error} If the corresponding simctl subcommand command + * returns non-zero return code. + * @throws {TypeError} If any of the arguments is not a valid value. + */ +commands.setLocation = async function setLocation (latitude, longitude) { + const lat = formatArg('latitude', latitude); + const lon = formatArg('longitude', longitude); + await this.exec('location', { + args: [this.requireUdid('location'), 'set', `${lat},${lon}`], + }); +}; + +/** + * Stop any running scenario and clear any simulated location. + * This functionality is only available since Xcode 14. + */ +commands.clearLocation = async function clearLocation () { + await this.exec('location', { + args: [this.requireUdid('location'), 'clear'], + }); +}; + +export default commands;