Skip to content

Commit 6f0ef8c

Browse files
committed
fix(tvos): address review findings for the tvOS platform integration
- Plugins keep their native code for visionOS and tvOS in platforms/ios. Change detection and native-file watching now resolve that folder the same way preparation already did (IMobileHelper.getPluginPlatformsFolderName), so an edit to a plugin's iOS sources is seen by tvOS/visionOS builds and watch mode. - getEmulatorImages only queried iOS simulators for the iOS platform, so startEmulator could not find a simulator for tvOS or visionOS. - ios-sim-portable 4.5.4 for tvOS simulator discovery (NativeScript/ios-sim-portable#135); also brings package-lock back in sync with package.json.
1 parent 27b4f02 commit 6f0ef8c

11 files changed

Lines changed: 158 additions & 67 deletions

File tree

lib/common/definitions/mobile.d.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1108,6 +1108,12 @@ declare global {
11081108
isvisionOSPlatform(platform: string): boolean;
11091109
istvOSPlatform(platform: string): boolean;
11101110
isApplePlatform(platform: string): boolean;
1111+
/**
1112+
* The platforms/<name> folder a plugin's native code for the platform is read
1113+
* from. visionOS and tvOS build from the iOS native project, so they consume
1114+
* platforms/ios.
1115+
*/
1116+
getPluginPlatformsFolderName(platform: string): string;
11111117
normalizePlatformName(platform: string): string;
11121118
validatePlatformName(platform: string): string;
11131119
buildDevicePath(...args: string[]): string;

lib/common/mobile/mobile-core/devices-service.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ export class DevicesService
163163
this.$hostInfo.isDarwin &&
164164
(!options ||
165165
!options.platform ||
166-
this.$mobileHelper.isiOSPlatform(options.platform))
166+
this.$mobileHelper.isApplePlatform(options.platform))
167167
) {
168168
result.ios = await this.$iOSEmulatorServices.getEmulatorImages();
169169
}
@@ -1203,7 +1203,7 @@ export class DevicesService
12031203
private getEmulatorError(error: Error, platform: string): string {
12041204
let emulatorName = constants.DeviceTypes.Emulator;
12051205

1206-
if (this.$mobileHelper.isiOSPlatform(platform)) {
1206+
if (this.$mobileHelper.isApplePlatform(platform)) {
12071207
emulatorName = constants.DeviceTypes.Simulator;
12081208
}
12091209

lib/common/mobile/mobile-helper.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export class MobileHelper implements Mobile.IMobileHelper {
1313
private $errors: IErrors,
1414
private $fs: IFileSystem,
1515
private $devicePlatformsConstants: Mobile.IDevicePlatformsConstants,
16-
private $tempService: ITempService
16+
private $tempService: ITempService,
1717
) {}
1818

1919
public get platformNames(): string[] {
@@ -65,6 +65,12 @@ export class MobileHelper implements Mobile.IMobileHelper {
6565
);
6666
}
6767

68+
public getPluginPlatformsFolderName(platform: string): string {
69+
return this.isApplePlatform(platform)
70+
? this.$devicePlatformsConstants.iOS.toLowerCase()
71+
: platform.toLowerCase();
72+
}
73+
6874
public normalizePlatformName(platform: string): string {
6975
if (this.isAndroidPlatform(platform)) {
7076
return "Android";
@@ -92,7 +98,7 @@ export class MobileHelper implements Mobile.IMobileHelper {
9298
this.$errors.fail(
9399
"'%s' is not a valid device platform. Valid platforms are %s.",
94100
platform,
95-
helpers.formatListOfNames(this.platformNames)
101+
helpers.formatListOfNames(this.platformNames),
96102
);
97103
}
98104

@@ -101,7 +107,7 @@ export class MobileHelper implements Mobile.IMobileHelper {
101107

102108
public buildDevicePath(...args: string[]): string {
103109
return this.correctDevicePath(
104-
args.join(MobileHelper.DEVICE_PATH_SEPARATOR)
110+
args.join(MobileHelper.DEVICE_PATH_SEPARATOR),
105111
);
106112
}
107113

@@ -116,15 +122,15 @@ export class MobileHelper implements Mobile.IMobileHelper {
116122
public async getDeviceFileContent(
117123
device: Mobile.IDevice,
118124
deviceFilePath: string,
119-
projectData: IProjectData
125+
projectData: IProjectData,
120126
): Promise<string> {
121127
const uniqueFilePath = await this.$tempService.path({ suffix: ".tmp" });
122128
const platform = device.deviceInfo.platform.toLowerCase();
123129
try {
124130
await device.fileSystem.getFile(
125131
deviceFilePath,
126132
projectData.projectIdentifiers[platform],
127-
uniqueFilePath
133+
uniqueFilePath,
128134
);
129135
} catch (e) {
130136
return null;

lib/common/test/unit-tests/mobile/devices-service.ts

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,9 @@ class AndroidEmulatorServices {
173173
public getRunningEmulator(emulatorId: string): Promise<Mobile.IDeviceInfo> {
174174
return null;
175175
}
176+
public async getEmulatorImages(): Promise<Mobile.IEmulatorImagesOutput> {
177+
return { devices: [], errors: [] };
178+
}
176179
}
177180

178181
class IOSEmulatorServices {
@@ -193,6 +196,9 @@ class IOSEmulatorServices {
193196
public async getRunningEmulator(): Promise<Mobile.IDeviceInfo> {
194197
return null;
195198
}
199+
public async getEmulatorImages(): Promise<Mobile.IEmulatorImagesOutput> {
200+
return { devices: [], errors: [] };
201+
}
196202
}
197203

198204
function createTestInjector(): IInjector {
@@ -210,19 +216,22 @@ function createTestInjector(): IInjector {
210216
testInjector.register("prompter", {});
211217

212218
testInjector.register("mobileHelper", {
213-
platformNames: ["ios", "android", "visionos"],
219+
platformNames: ["ios", "android", "visionos", "tvos"],
214220
validatePlatformName: (platform: string) => platform.toLowerCase(),
215221
isiOSPlatform: (platform: string) =>
216222
!!(platform && platform.toLowerCase() === "ios"),
217223
isAndroidPlatform: (platform: string) =>
218224
!!(platform && platform.toLowerCase() === "android"),
219225
isvisionOSPlatform: (platform: string) =>
220226
!!(platform && platform.toLowerCase() === "visionos"),
227+
istvOSPlatform: (platform: string) =>
228+
!!(platform && platform.toLowerCase() === "tvos"),
221229
isApplePlatform: (platform: string) =>
222230
!!(
223231
platform &&
224232
(platform.toLowerCase() === "ios" ||
225-
platform.toLowerCase() === "visionos")
233+
platform.toLowerCase() === "visionos" ||
234+
platform.toLowerCase() === "tvos")
226235
),
227236
});
228237

@@ -542,6 +551,26 @@ describe("devicesService", () => {
542551
);
543552
});
544553

554+
describe("getEmulatorImages", () => {
555+
it("lists iOS simulators for every Apple platform", async () => {
556+
testInjector.resolve("hostInfo").isDarwin = true;
557+
for (const platform of ["iOS", "visionOS", "tvOS"]) {
558+
const result = await devicesService.getEmulatorImages({ platform });
559+
assert.isDefined(result.ios, platform);
560+
assert.isUndefined(result.android, platform);
561+
}
562+
});
563+
564+
it("lists only Android emulators for Android", async () => {
565+
testInjector.resolve("hostInfo").isDarwin = true;
566+
const result = await devicesService.getEmulatorImages({
567+
platform: "android",
568+
});
569+
assert.isUndefined(result.ios);
570+
assert.isDefined(result.android);
571+
});
572+
});
573+
545574
describe("startEmulatorIfNecessary behaves as expected:", () => {
546575
it("throws error if --device and --emulator flags are passed simultaniously", () => {
547576
assert.isRejected(

lib/controllers/prepare-controller.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,9 @@ export class PrepareController
414414
path.join(
415415
dep.directory,
416416
PLATFORMS_DIR_NAME,
417-
platformData.platformNameLowerCase,
417+
this.$mobileHelper.getPluginPlatformsFolderName(
418+
platformData.platformNameLowerCase,
419+
),
418420
),
419421
);
420422
const pluginsPackageJsonFiles = dependencies.map((dep) =>

lib/services/plugins-service.ts

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -640,16 +640,10 @@ This framework comes from ${dependencyName} plugin, which is installed multiple
640640
);
641641
pluginData.isPlugin = !!cacheData.nativescript;
642642
pluginData.pluginPlatformsFolderPath = (platform: string) => {
643-
if (
644-
this.$mobileHelper.isvisionOSPlatform(platform) ||
645-
this.$mobileHelper.istvOSPlatform(platform)
646-
) {
647-
platform = constants.PlatformTypes.ios;
648-
}
649643
return path.join(
650644
pluginData.fullPath,
651645
"platforms",
652-
platform.toLowerCase(),
646+
this.$mobileHelper.getPluginPlatformsFolderName(platform),
653647
);
654648
};
655649
const data = cacheData.nativescript;

0 commit comments

Comments
 (0)