diff --git a/lib/simctl.js b/lib/simctl.js index 899587a..a4f3feb 100644 --- a/lib/simctl.js +++ b/lib/simctl.js @@ -25,6 +25,7 @@ exports.getSim = getSim; exports.install = install; exports.launch = launch; exports.list = list; +exports.listDevices = listDevices; exports.pair = pair; exports.pairAndActivate = pairAndActivate; exports.shutdown = shutdown; @@ -246,6 +247,72 @@ function list(params, callback) { ); } + +/** + * Returns a list of all devices. + * + * @param {Object} params - Various parameters. + * @param {String} params.simctl - The path to the `simctl` executable. + * @param {Number} [params.tries] - The max number of `simctl` tries. + * @param {Function} callback(err, info) - A function to call when finished. + */ +function listDevices(params, callback) { + if (!params || typeof params !== 'object') { + return callback(new Error(__('Missing params'))); + } + if (!params.simctl) { + return callback(new Error(__('Missing "simctl" param'))); + } + + var done = false; + var tries = 0; + var maxTries = params.tries || 4; + + async.whilst( + function (cb) { + return cb(null, !done && tries++ < maxTries); + }, + function (cb) { + trySimctl(params, ['list', 'devices', '--json'], function (err, output) { + if (err) { + return cb(err); + } + + output = output.trim(); + if (!output) { + log('simctl list devices output was empty!'); + return cb(); + } + + var json = null; + try { + json = JSON.parse(output.substring(output.indexOf('{'))); + } catch (e) { + return cb(e); + } + + if (!json) { + return cb(new Error(__('simctl list devices: json is null'))); + } + + done = true; + cb(null, json); + }); + }, + function (err, info) { + if (err) { + return callback(err); + } + + if (!done) { + return callback(new Error(__('simctl list devices failed after %s tries', maxTries))); + } + + callback(null, info); + } + ); +} + /** * Pairs a iOS Simulator with a watchOS Simulator. * diff --git a/lib/xcode.js b/lib/xcode.js index 3d532c8..b5f08d6 100644 --- a/lib/xcode.js +++ b/lib/xcode.js @@ -237,6 +237,38 @@ const simulatorDevicePairCompatibility = { '8.x': true, // watchOS 8.x '9.x': true // watchOS 9.x } + }, + '15.x': { // Xcode 15.x + '13.x': { // iOS 13.x + '7.x': true, // watchOS 7.x + '8.x': true, // watchOS 8.x + '9.x': true, // watchOS 9.x + '10.x': true // watchOS 10.x + }, + '14.x': { // iOS 14.x + '7.x': true, // watchOS 7.x + '8.x': true, // watchOS 8.x + '9.x': true, // watchOS 9.x + '10.x': true // watchOS 10.x + }, + '15.x': { + '7.x': true, // watchOS 7.x + '8.x': true, // watchOS 8.x + '9.x': true, // watchOS 9.x + '10.x': true // watchOS 10.x + }, + '16.x': { + '7.x': true, // watchOS 7.x + '8.x': true, // watchOS 8.x + '9.x': true, // watchOS 9.x + '10.x': true // watchOS 10.x + }, + '17.x': { + '7.x': true, // watchOS 7.x + '8.x': true, // watchOS 8.x + '9.x': true, // watchOS 9.x + '10.x': true // watchOS 10.x + } } }; @@ -556,8 +588,26 @@ exports.detect = function detect(options, callback) { } }); - // read in the runtimes - appc.util.mix(xc.simRuntimes, findSimRuntimes(path.join(deviceTypePath, 'Runtimes'))); + simctl.listDevices({ simctl: xc.executables.simctl }, function (err, info) { + if (err) { + return next(err); + } + + // Map the platform and version from CoreSimulator string like: + // - com.apple.CoreSimulator.SimRuntime.iOS-17-0 + // - com.apple.CoreSimulator.SimRuntime.watchOS-10-0 + for (const key of Object.keys(info.devices)) { + const [_, platform, rawVersion] = key.match(/\.SimRuntime\.(.*?)\-(.*)$/); + const version = rawVersion.replaceAll('-', '.'); + + const mapping = { + name: `${platform} ${version}`, + version + } + appc.util.mix(xc.simRuntimes, { [key]: mapping }); + + } + }); }); ['Simulator', 'iOS Simulator'].some(function (name) { diff --git a/package-lock.json b/package-lock.json index 6ffadd0..5e46b16 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ioslib", - "version": "1.7.30", + "version": "1.7.32", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "ioslib", - "version": "1.7.30", + "version": "1.7.32", "license": "Apache-2.0", "dependencies": { "always-tail": "0.2.0", diff --git a/package.json b/package.json index 344f732..b3a7e72 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ioslib", - "version": "1.7.31", + "version": "1.7.32", "description": "iOS Utility Library", "keywords": [ "appcelerator",