@@ -85,7 +85,25 @@ export class XCodeSimctlSimulator extends IPhoneSimulatorNameGetter implements I
85
85
return this . simctl . uninstall ( deviceId , appIdentifier , { skipError : true } ) ;
86
86
}
87
87
88
+ private static startingApps : IDictionary < Promise < string > > = { } ;
89
+ private static stoppingApps : IDictionary < Promise < void > > = { } ;
90
+
88
91
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
+
89
107
// simctl launch command does not launch the process immediately and we have to wait a little bit,
90
108
// just to ensure all related processes and services are alive.
91
109
const launchResult = await this . simctl . launch ( deviceId , appIdentifier , options ) ;
@@ -94,6 +112,18 @@ export class XCodeSimctlSimulator extends IPhoneSimulatorNameGetter implements I
94
112
}
95
113
96
114
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
+
97
127
try {
98
128
let pid = this . getPid ( deviceId , bundleExecutable ) ;
99
129
while ( pid ) {
@@ -108,6 +138,11 @@ export class XCodeSimctlSimulator extends IPhoneSimulatorNameGetter implements I
108
138
109
139
await this . simctl . terminate ( deviceId , appIdentifier ) ;
110
140
utils . sleep ( 0.5 ) ;
141
+
142
+ delete XCodeSimctlSimulator . stoppingApps [ appKey ] ;
143
+ deferPromise . resolve ( ) ;
144
+
145
+ return deferPromise . promise ;
111
146
}
112
147
113
148
private getPid ( deviceId : string , bundleExecutable : string ) : string {
0 commit comments