Skip to content

Commit 1f52461

Browse files
committed
refactor: extract more common logic for extension and watchapp
1 parent e0aaae0 commit 1f52461

File tree

4 files changed

+96
-59
lines changed

4 files changed

+96
-59
lines changed

lib/constants.ts

+2
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ export const TNS_NATIVE_SOURCE_GROUP_NAME = "TNSNativeSource";
4949
export const NATIVE_SOURCE_FOLDER = "src";
5050
export const APPLICATION_RESPONSE_TIMEOUT_SECONDS = 60;
5151
export const NATIVE_EXTENSION_FOLDER = "extensions";
52+
export const IOS_WATCHAPP_FOLDER = "watchapp";
53+
export const IOS_WATCHAPP_EXTENSION_FOLDER = "watchextension";
5254

5355
export class PackageVersion {
5456
static NEXT = "next";

lib/services/ios-extensions-service.ts

+6-21
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,7 @@ export class IOSExtensionsService extends NativeTargetServiceBase implements IIO
1616
}
1717
const project = new this.$xcode.project(pbxProjPath);
1818
project.parseSync();
19-
this.$fs.readDirectory(extensionsFolderPath)
20-
.filter(fileName => {
21-
const filePath = path.join(extensionsFolderPath, fileName);
22-
const stats = this.$fs.getFsStats(filePath);
23-
24-
return stats.isDirectory() && !fileName.startsWith(".");
25-
})
19+
this.getTargetDirectories(extensionsFolderPath)
2620
.forEach(extensionFolder => {
2721
const target = this.addTargetToProject(extensionsFolderPath, extensionFolder, 'app_extension', project, platformData);
2822
this.configureTarget(extensionFolder, path.join(extensionsFolderPath, extensionFolder), target, project, projectData);
@@ -38,21 +32,12 @@ export class IOSExtensionsService extends NativeTargetServiceBase implements IIO
3832

3933
private configureTarget(extensionName: string, extensionPath: string, target: IXcode.target, project: IXcode.project, projectData: IProjectData) {
4034
const extJsonPath = path.join(extensionPath, "extension.json");
41-
if (this.$fs.exists(extJsonPath)) {
42-
const extensionJson = this.$fs.readJson(extJsonPath);
43-
_.forEach(extensionJson.frameworks, framework => {
44-
project.addFramework(
45-
framework,
46-
{ target: target.uuid }
47-
);
48-
});
49-
if (extensionJson.assetcatalogCompilerAppiconName) {
50-
project.addToBuildSettings("ASSETCATALOG_COMPILER_APPICON_NAME", extensionJson.assetcatalogCompilerAppiconName, target.uuid);
51-
}
52-
}
35+
this.setConfigurationsFromJsonFile(extJsonPath, target.uuid, project);
5336

54-
project.addBuildProperty("PRODUCT_BUNDLE_IDENTIFIER", `${projectData.projectIdentifiers.ios}.${extensionName}`, "Debug", extensionName);
55-
project.addBuildProperty("PRODUCT_BUNDLE_IDENTIFIER", `${projectData.projectIdentifiers.ios}.${extensionName}`, "Release", extensionName);
37+
this.setXcodeTargetBuildConfigurationProperties(
38+
[{name: "PRODUCT_BUNDLE_IDENTIFIER", value: `${projectData.projectIdentifiers.ios}.${extensionName}`}],
39+
extensionName,
40+
project);
5641
}
5742

5843
public removeExtensions({pbxProjPath}: IRemoveExtensionsOptions): void {

lib/services/ios-native-target-service-base.ts

+45
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
import * as path from "path";
22

3+
export enum BuildNames {
4+
debug = "Debug",
5+
release = "Release"
6+
}
7+
8+
export interface IXcodeTargetBuildConfigurationProperty {
9+
name: string;
10+
value: any;
11+
buildNames?: BuildNames[];
12+
}
13+
314
export abstract class NativeTargetServiceBase implements IIOSNativeTargetServiceBase {
415
constructor(protected $fs: IFileSystem,
516
protected $pbxprojDomXcode: IPbxprojDomXcode,
@@ -40,4 +51,38 @@ export abstract class NativeTargetServiceBase implements IIOSNativeTargetService
4051
}
4152
xcode.save();
4253
}
54+
55+
protected getTargetDirectories(folderPath: string): string[] {
56+
return this.$fs.readDirectory(folderPath)
57+
.filter(fileName => {
58+
const filePath = path.join(folderPath, fileName);
59+
const stats = this.$fs.getFsStats(filePath);
60+
61+
return stats.isDirectory() && !fileName.startsWith(".");
62+
});
63+
}
64+
65+
protected setXcodeTargetBuildConfigurationProperties(properties: IXcodeTargetBuildConfigurationProperty[], targetName: string, project: IXcode.project): void {
66+
properties.forEach(property => {
67+
const buildNames = property.buildNames || [BuildNames.debug, BuildNames.release];
68+
buildNames.forEach((buildName) => {
69+
project.addBuildProperty(property.name, property.value, buildName, targetName);
70+
});
71+
});
72+
}
73+
74+
protected setConfigurationsFromJsonFile(jsonPath: string, targetUuid: string, project: IXcode.project) {
75+
if (this.$fs.exists(jsonPath)) {
76+
const configurationJson = this.$fs.readJson(jsonPath) || {};
77+
_.forEach(configurationJson.frameworks, framework => {
78+
project.addFramework(
79+
framework,
80+
{ target: targetUuid }
81+
);
82+
});
83+
if (configurationJson.assetcatalogCompilerAppiconName) {
84+
project.addToBuildSettings("ASSETCATALOG_COMPILER_APPICON_NAME", configurationJson.assetcatalogCompilerAppiconName, targetUuid);
85+
}
86+
}
87+
}
4388
}

lib/services/ios-watch-app-service.ts

+43-38
Original file line numberDiff line numberDiff line change
@@ -10,59 +10,45 @@ export class IOSWatchAppService extends NativeTargetServiceBase implements IIOSW
1010

1111
public async addWatchAppFromPath({watchAppFolderPath, projectData, platformData, pbxProjPath}: IAddWatchAppFromPathOptions): Promise<boolean> {
1212
const targetUuids: string[] = [];
13-
let addedExtensions = false;
13+
1414
if (!this.$fs.exists(watchAppFolderPath)) {
1515
return false;
1616
}
17-
const project = new this.$xcode.project(pbxProjPath);
18-
const appPath = path.join(watchAppFolderPath, "watchapp");
19-
const extensionPath = path.join(watchAppFolderPath, "watchextension");
20-
project.parseSync();
21-
const appFolder = this.$fs.readDirectory(appPath)
22-
.filter(fileName => {
23-
const filePath = path.join(appPath, fileName);
24-
const stats = this.$fs.getFsStats(filePath);
2517

26-
return stats.isDirectory() && !fileName.startsWith(".");
27-
})[0];
18+
const appPath = path.join(watchAppFolderPath, "watchapp");
19+
const appFolder = this.getTargetDirectories(appPath)[0];
2820

29-
const extensionFolder = this.$fs.readDirectory(extensionPath)
30-
.filter(fileName => {
31-
const filePath = path.join(extensionPath, fileName);
32-
const stats = this.$fs.getFsStats(filePath);
21+
const extensionPath = path.join(watchAppFolderPath, "watchextension");
22+
const extensionFolder = this.getTargetDirectories(extensionPath)[0];
3323

34-
return stats.isDirectory() && !fileName.startsWith(".");
35-
})[0];
24+
const project = new this.$xcode.project(pbxProjPath);
25+
project.parseSync();
3626

3727
const watchApptarget = this.addTargetToProject(appPath, appFolder, "watch_app", project, platformData, project.getFirstTarget().uuid);
38-
this.configureTarget(appFolder, path.join(appPath, appFolder), `${projectData.projectIdentifiers.ios}.watchkitapp`, watchApptarget, project);
28+
this.configureTarget(
29+
appFolder,
30+
path.join(appPath, appFolder),
31+
`${projectData.projectIdentifiers.ios}.watchkitapp`,
32+
"watchapp.json",
33+
watchApptarget,
34+
project
35+
);
3936
targetUuids.push(watchApptarget.uuid);
37+
4038
const watchExtensionTarget = this.addTargetToProject(extensionPath, extensionFolder, "watch_extension", project, platformData, watchApptarget.uuid);
41-
this.configureTarget(extensionFolder, path.join(extensionPath, extensionFolder), `${projectData.projectIdentifiers.ios}.watchkitapp.watchkitextension`, watchExtensionTarget, project);
39+
this.configureTarget(
40+
extensionFolder,
41+
path.join(extensionPath, extensionFolder),
42+
`${projectData.projectIdentifiers.ios}.watchkitapp.watchkitextension`,
43+
"extension.json",
44+
watchExtensionTarget,
45+
project);
4246
targetUuids.push(watchExtensionTarget.uuid);
43-
addedExtensions = true;
4447

4548
this.$fs.writeFile(pbxProjPath, project.writeSync({omitEmptyValues: true}));
4649
this.prepareSigning(targetUuids, projectData, pbxProjPath);
4750

48-
return addedExtensions;
49-
}
50-
51-
private configureTarget(targetName: string, targetPath: string, identifier: string, target: IXcode.target, project: IXcode.project) {
52-
const identifierParts = identifier.split(".");
53-
identifierParts.pop();
54-
const wkAppBundleIdentifier = identifierParts.join(".");
55-
project.addBuildProperty("PRODUCT_BUNDLE_IDENTIFIER", identifier, "Debug", targetName);
56-
project.addBuildProperty("PRODUCT_BUNDLE_IDENTIFIER", identifier, "Release", targetName);
57-
project.addBuildProperty("SDKROOT", "watchos", "Debug", targetName);
58-
project.addBuildProperty("SDKROOT", "watchos", "Release", targetName);
59-
project.addBuildProperty("TARGETED_DEVICE_FAMILY", 4, "Debug", targetName);
60-
project.addBuildProperty("TARGETED_DEVICE_FAMILY", 4, "Release", targetName);
61-
project.addBuildProperty("WATCHOS_DEPLOYMENT_TARGET", 4.1, "Debug", targetName);
62-
project.addBuildProperty("WATCHOS_DEPLOYMENT_TARGET", 4.1, "Release", targetName);
63-
project.addBuildProperty("WK_APP_BUNDLE_IDENTIFIER", wkAppBundleIdentifier, "Debug", targetName);
64-
project.addBuildProperty("WK_APP_BUNDLE_IDENTIFIER", wkAppBundleIdentifier, "Release", targetName);
65-
project.addToHeaderSearchPaths(targetPath, target.pbxNativeTarget.productName);
51+
return true;
6652
}
6753

6854
public removeWatchApp({pbxProjPath}: IRemoveWatchAppOptions): void {
@@ -72,6 +58,25 @@ export class IOSWatchAppService extends NativeTargetServiceBase implements IIOSW
7258
project.removeTargetsByProductType("com.apple.product-type.watchkit2-extension");
7359
this.$fs.writeFile(pbxProjPath, project.writeSync({omitEmptyValues: true}));
7460
}
61+
62+
private configureTarget(targetName: string, targetPath: string, identifier: string, configurationFileName: string, target: IXcode.target, project: IXcode.project) {
63+
const targetConfigurationJsonPath = path.join(targetPath, configurationFileName);
64+
this.setConfigurationsFromJsonFile(targetConfigurationJsonPath, target.uuid, project);
65+
66+
const identifierParts = identifier.split(".");
67+
identifierParts.pop();
68+
const wkAppBundleIdentifier = identifierParts.join(".");
69+
70+
this.setXcodeTargetBuildConfigurationProperties([
71+
{name: "PRODUCT_BUNDLE_IDENTIFIER", value: identifier},
72+
{name: "SDKROOT", value: "watchos"},
73+
{name: "TARGETED_DEVICE_FAMILY", value: 4},
74+
{name: "WATCHOS_DEPLOYMENT_TARGET", value: 4.1},
75+
{name: "WK_APP_BUNDLE_IDENTIFIER", value: wkAppBundleIdentifier}
76+
], targetName, project);
77+
78+
project.addToHeaderSearchPaths(targetPath, target.pbxNativeTarget.productName);
79+
}
7580
}
7681

7782
$injector.register("iOSWatchAppService", IOSWatchAppService);

0 commit comments

Comments
 (0)