Skip to content
This repository was archived by the owner on Feb 2, 2021. It is now read-only.

Commit 90c4944

Browse files
committed
Merge pull request #462 from telerik/livesync-ios-restart
Livesync iOS simulator restart fixes
2 parents af544e6 + ee89f94 commit 90c4944

File tree

2 files changed

+98
-26
lines changed

2 files changed

+98
-26
lines changed

mobile/ios/ios-emulator-services.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,12 @@ class IosEmulatorServices implements Mobile.IiOSSimulatorService {
208208
this.$logger.trace("Unable to kill simulator: " + e);
209209
}
210210

211-
this.$childProcess.exec(`xcrun simctl launch ${runningSimulatorId} ${appIdentifier}`).wait();
211+
setTimeout(() => {
212+
// Killall doesn't always finish immediately, and the subsequent
213+
// start fails since the app is already running.
214+
// Give it some time to die before we attempt restarting.
215+
this.$childProcess.exec(`xcrun simctl launch ${runningSimulatorId} ${appIdentifier}`);
216+
}, 500);
212217
}).future<void>()();
213218
}
214219
}

services/usb-livesync-service-base.ts

+92-25
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,41 @@ interface IProjectFileInfo {
1212
shouldIncludeFile: boolean;
1313
}
1414

15+
class SyncBatch {
16+
private timer: NodeJS.Timer = null;
17+
private syncQueue: string[] = [];
18+
19+
constructor(
20+
private $logger: ILogger,
21+
private $dispatcher: IFutureDispatcher,
22+
private done: (filesToSync: Array<string>) => void) {
23+
}
24+
25+
public addFile(filePath: string): void {
26+
if (this.timer) {
27+
clearTimeout(this.timer);
28+
}
29+
30+
this.syncQueue.push(filePath);
31+
32+
this.timer = setTimeout(() => {
33+
let filesToSync = this.syncQueue;
34+
if (filesToSync.length > 0) {
35+
this.syncQueue = [];
36+
this.$logger.trace("Syncing %s", filesToSync.join(", "));
37+
this.$dispatcher.dispatch( () => {
38+
return (() => this.done(filesToSync)).future<void>()();
39+
});
40+
}
41+
this.timer = null;
42+
}, 500);
43+
}
44+
45+
public get syncPending() {
46+
return this.syncQueue.length > 0;
47+
}
48+
}
49+
1550
export class UsbLiveSyncServiceBase implements IUsbLiveSyncServiceBase {
1651
private _initialized = false;
1752

@@ -68,17 +103,31 @@ export class UsbLiveSyncServiceBase implements IUsbLiveSyncServiceBase {
68103

69104
if(this.$options.watch) {
70105
let that = this;
71-
72106
gaze("**/*", { cwd: watchGlob }, function(err: any, watcher: any) {
73107
this.on('all', (event: string, filePath: string) => {
74108
if(event === "added" || event === "changed") {
75109
if(!_.contains(excludedProjectDirsAndFiles, filePath)) {
76110
if(synciOSSimulator) {
77-
that.$dispatcher.dispatch(() => that.$iOSEmulatorServices.syncFiles(appIdentifier, projectFilesPath, [filePath], notRunningiOSSimulatorAction, iOSSimulatorRelativeToProjectBasePathAction));
111+
that.batchSimulatorLiveSync(
112+
appIdentifier,
113+
projectFilesPath,
114+
filePath,
115+
notRunningiOSSimulatorAction,
116+
iOSSimulatorRelativeToProjectBasePathAction
117+
);
78118
}
79119

80120
if(!that.$options.emulator || platform.toLowerCase() === "android") {
81-
that.batchLiveSync(platform, filePath, appIdentifier, localProjectRootPath || projectFilesPath, platformSpecificLiveSyncServices, notInstalledAppOnDeviceAction, beforeLiveSyncAction, beforeBatchLiveSyncAction);
121+
that.batchLiveSync(
122+
platform,
123+
filePath,
124+
appIdentifier,
125+
localProjectRootPath || projectFilesPath,
126+
platformSpecificLiveSyncServices,
127+
notInstalledAppOnDeviceAction,
128+
beforeLiveSyncAction,
129+
beforeBatchLiveSyncAction
130+
);
82131
}
83132
}
84133
}
@@ -134,38 +183,56 @@ export class UsbLiveSyncServiceBase implements IUsbLiveSyncServiceBase {
134183
}).future<void>()();
135184
}
136185

137-
private timer: NodeJS.Timer = null;
138-
private syncQueue: string[] = [];
186+
private batch: SyncBatch = null;
187+
139188
private batchLiveSync(platform: string, filePath: string, appIdentifier: string, projectFilesPath: string,
140189
platformSpecificLiveSyncServices: IDictionary<any>,
141190
notInstalledAppOnDeviceAction: (_device: Mobile.IDevice) => IFuture<void>,
142191
beforeLiveSyncAction?: (_device1: Mobile.IDevice, _deviceAppData: Mobile.IDeviceAppData) => IFuture<void>,
143192
beforeBatchLiveSyncAction?: (_filePath: string) => IFuture<string>) : void {
144-
145-
if (!this.timer) {
146-
this.timer = setInterval(() => {
147-
let filesToSync = this.syncQueue;
148-
if (filesToSync.length > 0) {
149-
this.syncQueue = [];
150-
this.$logger.trace("Syncing %s", filesToSync.join(", "));
151-
this.$dispatcher.dispatch( () => {
152-
return (() => {
153-
this.preparePlatformForSync(platform);
154-
this.syncCore(platform, filesToSync, appIdentifier, projectFilesPath, platformSpecificLiveSyncServices, notInstalledAppOnDeviceAction, beforeLiveSyncAction).wait();
155-
}).future<void>()();
156-
});
157-
}
158-
}, 500);
159-
}
193+
if (!this.batch || !this.batch.syncPending) {
194+
this.batch = new SyncBatch(
195+
this.$logger, this.$dispatcher, (filesToSync) => {
196+
this.preparePlatformForSync(platform);
197+
this.syncCore(
198+
platform,
199+
filesToSync,
200+
appIdentifier,
201+
projectFilesPath,
202+
platformSpecificLiveSyncServices,
203+
notInstalledAppOnDeviceAction,
204+
beforeLiveSyncAction
205+
).wait();
206+
}
207+
);
208+
}
160209

161210
this.$dispatcher.dispatch( () => (() => {
162-
this.syncQueue.push(beforeBatchLiveSyncAction ? beforeBatchLiveSyncAction(filePath).wait() : filePath);
211+
let fileToSync = beforeBatchLiveSyncAction ? beforeBatchLiveSyncAction(filePath).wait() : filePath;
212+
this.batch.addFile(fileToSync);
163213
}).future<void>()());
164214
}
165215

166-
protected preparePlatformForSync(platform: string) {
167-
//Overridden in platform-specific services.
168-
}
216+
private batchSimulatorLiveSync(
217+
appIdentifier: string,
218+
projectFilesPath: string,
219+
filePath: string,
220+
notRunningiOSSimulatorAction: () => IFuture<void>,
221+
iOSSimulatorRelativeToProjectBasePathAction:(projectFile: string) => string): void {
222+
if (!this.batch || !this.batch.syncPending) {
223+
this.batch = new SyncBatch(
224+
this.$logger, this.$dispatcher, (filesToSync) => {
225+
this.$iOSEmulatorServices.syncFiles(appIdentifier, projectFilesPath, filesToSync, notRunningiOSSimulatorAction, iOSSimulatorRelativeToProjectBasePathAction);
226+
}
227+
);
228+
}
229+
230+
this.batch.addFile(filePath);
231+
}
232+
233+
protected preparePlatformForSync(platform: string) {
234+
//Overridden in platform-specific services.
235+
}
169236

170237
private isFileExcluded(path: string, exclusionList: string[], projectDir: string): boolean {
171238
return !!_.find(exclusionList, (pattern) => minimatch(path, pattern, { nocase: true }));

0 commit comments

Comments
 (0)