@@ -22,6 +22,7 @@ const path = require('node:path');
2222const bplist = require ( 'bplist-parser' ) ;
2323const plist = require ( 'plist' ) ;
2424const execa = require ( 'execa' ) ;
25+ const devicectl = require ( 'devicectl' ) ;
2526const { CordovaError, events } = require ( 'cordova-common' ) ;
2627const build = require ( './build' ) ;
2728const check_reqs = require ( './check_reqs' ) ;
@@ -64,7 +65,11 @@ module.exports.run = function (runOptions) {
6465 // we also explicitly set device flag in options as we pass
6566 // those parameters to other api (build as an example)
6667 runOptions . device = true ;
67- return check_reqs . check_ios_deploy ( ) ;
68+ runOptions . target = devices [ 0 ] . split ( ' ' ) [ 0 ] ;
69+
70+ if ( ! runOptions . target . includes ( '-' ) ) {
71+ return check_reqs . check_ios_deploy ( ) ;
72+ }
6873 }
6974 } ) ;
7075 }
@@ -90,7 +95,7 @@ module.exports.run = function (runOptions) {
9095 const buildOutputDir = path . join ( projectPath , 'build' , `${ configuration } -iphoneos` ) ;
9196 const appPath = path . join ( buildOutputDir , `${ productName } .app` ) ;
9297
93- return module . exports . checkDeviceConnected ( )
98+ return module . exports . checkDeviceConnected ( runOptions . target )
9499 . then ( ( ) => {
95100 // Unpack IPA
96101 const ipafile = path . join ( buildOutputDir , `${ productName } .ipa` ) ;
@@ -172,8 +177,13 @@ function filterSupportedArgs (args) {
172177 * Checks if any iOS device is connected
173178 * @return {Promise } Fullfilled when any device is connected, rejected otherwise
174179 */
175- function checkDeviceConnected ( ) {
176- return execa ( 'ios-deploy' , [ '-c' , '-t' , '1' ] , { stdio : 'inherit' } ) ;
180+ function checkDeviceConnected ( target = '' ) {
181+ if ( target . includes ( '-' ) ) {
182+ const details = devicectl . info ( devicectl . InfoTypes . Details , target ) . json ?. result ;
183+ return details ?. connectionProperties ?. transportType === 'wired' ;
184+ } else {
185+ return execa ( 'ios-deploy' , [ '-c' , '-t' , '1' ] , { stdio : 'inherit' } ) ;
186+ }
177187}
178188
179189/**
@@ -184,13 +194,19 @@ function checkDeviceConnected () {
184194 */
185195function deployToDevice ( appPath , target , extraArgs ) {
186196 events . emit ( 'log' , 'Deploying to device' ) ;
187- const args = [ '--justlaunch' , '-d' , '-b' , appPath ] ;
188- if ( target ) {
189- args . push ( '-i' , target ) ;
197+ if ( target . includes ( '-' ) ) {
198+ return devicectl . install ( target , appPath )
199+ . then ( ( ) => getBundleIdentifierFromApp ( appPath ) )
200+ . then ( appIdentifier => devicectl . launch ( target , appIdentifier , extraArgs ) ) ;
190201 } else {
191- args . push ( '--no-wifi' ) ;
202+ const args = [ '--justlaunch' , '-d' , '-b' , appPath ] ;
203+ if ( target ) {
204+ args . push ( '-i' , target ) ;
205+ } else {
206+ args . push ( '--no-wifi' ) ;
207+ }
208+ return execa ( 'ios-deploy' , args . concat ( extraArgs ) , { stdio : 'inherit' } ) ;
192209 }
193- return execa ( 'ios-deploy' , args . concat ( extraArgs ) , { stdio : 'inherit' } ) ;
194210}
195211
196212/**
@@ -223,48 +239,52 @@ async function deployToSim (appPath, target) {
223239 return module . exports . startSim ( appPath , target ) ;
224240}
225241
226- async function startSim ( appPath , target ) {
227- const projectPath = path . join ( path . dirname ( appPath ) , '../..' ) ;
228- const logPath = path . join ( projectPath , 'cordova/console.log' ) ;
229- const deviceTypeId = `com.apple.CoreSimulator.SimDeviceType.${ target } ` ;
230-
231- try {
232- const infoPlistPath = path . join ( appPath , 'Info.plist' ) ;
233- if ( ! fs . existsSync ( infoPlistPath ) ) {
234- throw new Error ( `${ infoPlistPath } file not found.` ) ;
235- }
236-
237- bplist . parseFile ( infoPlistPath , function ( err , obj ) {
238- let appIdentifier ;
242+ function getBundleIdentifierFromApp ( appPath ) {
243+ const infoPlistPath = path . join ( appPath , 'Info.plist' ) ;
244+ if ( ! fs . existsSync ( infoPlistPath ) ) {
245+ return Promise . reject ( new Error ( `${ infoPlistPath } file not found.` ) ) ;
246+ }
239247
248+ return new Promise ( ( resolve , reject ) => {
249+ bplist . parseFile ( infoPlistPath , ( err , obj ) => {
240250 if ( err ) {
241251 obj = plist . parse ( fs . readFileSync ( infoPlistPath , 'utf8' ) ) ;
242252 if ( obj ) {
243- appIdentifier = obj . CFBundleIdentifier ;
253+ return resolve ( obj . CFBundleIdentifier ) ;
244254 } else {
245- throw err ;
255+ return reject ( err ) ;
246256 }
247257 } else {
248- appIdentifier = obj [ 0 ] . CFBundleIdentifier ;
258+ return resolve ( obj [ 0 ] . CFBundleIdentifier ) ;
249259 }
260+ } ) ;
261+ } ) ;
262+ }
250263
251- // get the deviceid from --devicetypeid
252- // --devicetypeid is a string in the form "devicetype, runtime_version" (optional: runtime_version)
253- const device = getDeviceFromDeviceTypeId ( deviceTypeId ) ;
264+ async function startSim ( appPath , target ) {
265+ const projectPath = path . join ( path . dirname ( appPath ) , '../..' ) ;
266+ const logPath = path . join ( projectPath , 'cordova/console.log' ) ;
267+ const deviceTypeId = `com.apple.CoreSimulator.SimDeviceType.${ target } ` ;
254268
255- // so now we have the deviceid, we can proceed
256- try {
257- startSimulator ( device , { appPath, appIdentifier, logPath, waitForDebugger : false } ) ;
258- } catch ( e ) {
259- events . emit ( 'warn' , `Failed to start simulator with error: "${ e . message } "` ) ;
260- }
269+ try {
270+ const appIdentifier = await getBundleIdentifierFromApp ( appPath ) ;
261271
262- if ( logPath ) {
263- events . emit ( 'log' , `Log Path: ${ path . resolve ( logPath ) } ` ) ;
264- }
272+ // get the deviceid from --devicetypeid
273+ // --devicetypeid is a string in the form "devicetype, runtime_version" (optional: runtime_version)
274+ const device = getDeviceFromDeviceTypeId ( deviceTypeId ) ;
265275
266- process . exit ( 0 ) ;
267- } ) ;
276+ // so now we have the deviceid, we can proceed
277+ try {
278+ startSimulator ( device , { appPath, appIdentifier, logPath, waitForDebugger : false } ) ;
279+ } catch ( e ) {
280+ events . emit ( 'warn' , `Failed to start simulator with error: "${ e . message } "` ) ;
281+ }
282+
283+ if ( logPath ) {
284+ events . emit ( 'log' , `Log Path: ${ path . resolve ( logPath ) } ` ) ;
285+ }
286+
287+ process . exit ( 0 ) ;
268288 } catch ( e ) {
269289 events . emit ( 'warn' , `Failed to launch simulator with error: ${ e . message } ` ) ;
270290 process . exit ( 1 ) ;
0 commit comments