diff --git a/lib/simulator.js b/lib/simulator.js index 1470baf..c1fd416 100644 --- a/lib/simulator.js +++ b/lib/simulator.js @@ -80,27 +80,27 @@ const deviceStateNames = exports.deviceStateNames = { * what Watch Simulator. It's a mystery! */ const devicePairCompatiblity = exports.devicePairCompatiblity = { - '>=6.2 <7.0': { // Xcode 6.2, 6.3, 6.4 - '>=8.2 <9.0': { // iOS 8.2, 8.3, 8.4 - '1.x': true // watchOS 1.0 + '>=6.2 <7.0': { // Xcode 6.2, 6.3, 6.4 + '>=8.2 <9.0': { // iOS 8.2, 8.3, 8.4 + '1.x': true // watchOS 1.0 } }, - '7.x': { // Xcode 7.0 - '>=8.2 <9.0': { // iOS 8.2, 8.3, 8.4 - '1.x': true // watchOS 1.0 + '7.x': { // Xcode 7.x + '>=8.2 <9.0': { // iOS 8.2, 8.3, 8.4 + '1.x': true // watchOS 1.0 }, - '9.x': { // iOS 9.0 - '2.x': true // watchOS 2.0 + '9.x': { // iOS 9.x + '2.x': true // watchOS 2.x } }, - '8.x': { - '9.x': { - '2.x': true, - '3.x': true + '8.x': { // Xcode 8.x + '9.x': { // iOS 9.x + '2.x': true, // watchOS 2.x + '3.x': true // watchOS 3.x }, - '10.x': { - '2.x': true, - '3.x': true + '10.x': { // iOS 10.x + '2.x': true, // watchOS 2.x + '3.x': true // watchOS 3.x } } }; @@ -165,7 +165,6 @@ function detect(options, callback) { simulators: { ios: {}, watchos: {}, - devicePairs: {}, crashDir: appc.fs.resolvePath('~/Library/Logs/DiagnosticReports'), }, issues: [] @@ -296,17 +295,6 @@ function detect(options, callback) { }); }); - // load the device pairs - var deviceSetPlist = readPlist(path.join(coreSimDir, 'device_set.plist')); - if (deviceSetPlist && deviceSetPlist.DevicePairs) { - Object.keys(deviceSetPlist.DevicePairs).forEach(function (udid) { - results.simulators.devicePairs[udid] = { - phone: deviceSetPlist.DevicePairs[udid].companion, - watch: deviceSetPlist.DevicePairs[udid].gizmo - }; - }); - } - // the cache must be a clean copy that we'll clone for subsequent detect() calls // because we can't allow the cache to be modified by reference cache = JSON.parse(JSON.stringify(results)); @@ -1133,31 +1121,54 @@ function launch(simHandleOrUDID, options, callback) { return next(); } - // we need to pair, check if we're already paired - if (Object.keys(simInfo.simulators.devicePairs).some(function (udid) { var dp = simInfo.simulators.devicePairs[udid]; return dp.phone === simHandle.udid && dp.watch === watchSimHandle.udid; })) { - // already paired! - emitter.emit('log-debug', __('iOS and watchOS simulators already paired')); - return next(); - } + emitter.emit('log-debug', __('Running: %s', selectedXcode.executables.simctl + ' list pairs --json')); + appc.subprocess.run(selectedXcode.executables.simctl, ['list', 'pairs', '--json'], function (code, out, err) { + if (code) { + return next(code ? new Error(err.trim()) : null); + } + + var devicePairs; + try { + devicePairs = JSON.parse(out.substring(out.indexOf('{'))).pairs; + } catch (e) { + return next(e); + } + + // we need to pair, check if we're already paired + if (Object.keys(devicePairs).some(function (udid) { + var dp = devicePairs[udid]; + return dp.phone.udid === simHandle.udid && dp.watch.udid === watchSimHandle.udid; + })) { + // already paired! + emitter.emit('log-debug', __('iOS and watchOS simulators already paired')); + return next(); + } + + // check if we need to unpair + async.eachSeries(Object.keys(devicePairs), function (udid, next) { + var dp = devicePairs[udid]; + if (dp.phone.udid !== simHandle.udid && dp.watch.udid !== watchSimHandle.udid) { + return next(); + } - // check if we need to unpair - async.eachSeries(Object.keys(simInfo.simulators.devicePairs), function (udid, next) { - var dp = simInfo.simulators.devicePairs[udid]; - if (dp.phone === simHandle.udid || dp.watch === watchSimHandle.udid) { emitter.emit('log-debug', __('Unpairing iOS and watchOS simulator pair: %s', udid)); var args = ['unpair', udid]; emitter.emit('log-debug', __('Running: %s', selectedXcode.executables.simctl + ' ' + args.join(' '))); - appc.subprocess.run(selectedXcode.executables.simctl, args, next); - } else { - next(); - } - }, function () { - // pair! - emitter.emit('log-debug', __('Pairing iOS and watchOS simulator pair: %s -> %s', watchSimHandle.udid, simHandle.udid)); - var args = ['pair', watchSimHandle.udid, simHandle.udid]; - emitter.emit('log-debug', __('Running: %s', selectedXcode.executables.simctl + ' ' + args.join(' '))); - appc.subprocess.run(selectedXcode.executables.simctl, args, function (code, out, err) { - next(code); + appc.subprocess.run(selectedXcode.executables.simctl, args, function (code, out, err) { + next(code ? new Error(err.trim()) : null); + }); + }, function (err) { + if (err) { + return next(err); + } + + // pair! + emitter.emit('log-debug', __('Pairing iOS and watchOS simulator pair: %s -> %s', watchSimHandle.udid, simHandle.udid)); + var args = ['pair', watchSimHandle.udid, simHandle.udid]; + emitter.emit('log-debug', __('Running: %s', selectedXcode.executables.simctl + ' ' + args.join(' '))); + appc.subprocess.run(selectedXcode.executables.simctl, args, function (code, out, err) { + next(code ? new Error(err.trim()) : null); + }); }); }); }, @@ -1334,6 +1345,7 @@ function launch(simHandleOrUDID, options, callback) { } ], function (err) { if (err) { + emitter.emit('error', err); return callback(err); } diff --git a/package.json b/package.json index 9ffd939..ac94fbd 100644 --- a/package.json +++ b/package.json @@ -38,15 +38,15 @@ }, "dependencies": { "always-tail": "0.2.0", - "async": "1.5.2", + "async": "2.0.1", "bplist-parser": "0.1.1", "mkdirp": "0.5.1", "node-appc": "0.2.36", - "node-ios-device": "0.9.5" + "node-ios-device": "0.10.1" }, "devDependencies": { "mocha": "^2.5.3", - "should": "^9.0.2" + "should": "^10.0.0" }, "scripts": { "test": "mocha --require test/init --reporter spec --check-leaks test/", diff --git a/test/test-simulator.js b/test/test-simulator.js index a952cec..2c47631 100644 --- a/test/test-simulator.js +++ b/test/test-simulator.js @@ -172,7 +172,7 @@ describe('simulator', function () { should(results).have.keys('simulators', 'issues'); should(results.simulators).be.an.Object; - should(results.simulators).have.keys('ios', 'watchos', 'devicePairs', 'crashDir'); + should(results.simulators).have.keys('ios', 'watchos', 'crashDir'); should(results.simulators.ios).be.an.Object; Object.keys(results.simulators.ios).forEach(function (ver) { @@ -184,16 +184,6 @@ describe('simulator', function () { checkSims(results.simulators.watchos[ver]); }); - should(results.simulators.devicePairs).be.an.Object; - Object.keys(results.simulators.devicePairs).forEach(function (udid) { - should(results.simulators.devicePairs[udid]).be.an.Object; - should(results.simulators.devicePairs[udid]).have.keys('phone', 'watch'); - should(results.simulators.devicePairs[udid].phone).be.a.String; - should(results.simulators.devicePairs[udid].phone).not.equal(''); - should(results.simulators.devicePairs[udid].watch).be.a.String; - should(results.simulators.devicePairs[udid].watch).not.equal(''); - }); - should(results.simulators.crashDir).be.a.String; should(results.simulators.crashDir).not.equal(''); if (fs.existsSync(results.simulators.crashDir)) {