@@ -85,7 +85,25 @@ export class XCodeSimctlSimulator extends IPhoneSimulatorNameGetter implements I
8585 return this . simctl . uninstall ( deviceId , appIdentifier , { skipError : true } ) ;
8686 }
8787
88+ private static startingApps : IDictionary < Promise < string > > = { } ;
89+ private static stoppingApps : IDictionary < Promise < void > > = { } ;
90+
8891 public async startApplication ( deviceId : string , appIdentifier : string , options : IOptions ) : Promise < string > {
92+ const startingAppKey : string = deviceId + appIdentifier ;
93+ if ( XCodeSimctlSimulator . startingApps [ startingAppKey ] ) {
94+ return XCodeSimctlSimulator . startingApps [ startingAppKey ] ;
95+ }
96+
97+ const deferPromise = utils . deferPromise < string > ( ) ;
98+ XCodeSimctlSimulator . startingApps [ startingAppKey ] = deferPromise . promise ;
99+ // let the app start for 3 seconds in order to avoid a frozen simulator
100+ // when the app is killed on splash screen
101+ setTimeout ( ( ) => {
102+ delete XCodeSimctlSimulator . startingApps [ startingAppKey ] ;
103+ deferPromise . resolve ( ) ;
104+ } , 3000 ) ;
105+
106+
89107 // simctl launch command does not launch the process immediately and we have to wait a little bit,
90108 // just to ensure all related processes and services are alive.
91109 const launchResult = await this . simctl . launch ( deviceId , appIdentifier , options ) ;
@@ -94,6 +112,18 @@ export class XCodeSimctlSimulator extends IPhoneSimulatorNameGetter implements I
94112 }
95113
96114 public async stopApplication ( deviceId : string , appIdentifier : string , bundleExecutable : string ) : Promise < void > {
115+ const appKey : string = deviceId + appIdentifier ;
116+ if ( XCodeSimctlSimulator . stoppingApps [ appKey ] ) {
117+ return XCodeSimctlSimulator . stoppingApps [ appKey ] ;
118+ }
119+
120+ const deferPromise = utils . deferPromise < void > ( ) ;
121+ XCodeSimctlSimulator . stoppingApps [ appKey ] = deferPromise . promise ;
122+
123+ if ( XCodeSimctlSimulator . startingApps [ appKey ] ) {
124+ await XCodeSimctlSimulator . startingApps [ appKey ] ;
125+ }
126+
97127 try {
98128 let pid = this . getPid ( deviceId , bundleExecutable ) ;
99129 while ( pid ) {
@@ -108,6 +138,11 @@ export class XCodeSimctlSimulator extends IPhoneSimulatorNameGetter implements I
108138
109139 await this . simctl . terminate ( deviceId , appIdentifier ) ;
110140 utils . sleep ( 0.5 ) ;
141+
142+ delete XCodeSimctlSimulator . stoppingApps [ appKey ] ;
143+ deferPromise . resolve ( ) ;
144+
145+ return deferPromise . promise ;
111146 }
112147
113148 private getPid ( deviceId : string , bundleExecutable : string ) : string {
0 commit comments