Skip to content

Commit ea04549

Browse files
Fatme HavaluovaFatme Havaluova
Fatme Havaluova
authored and
Fatme Havaluova
committed
Enable image resources from App_Resources in iOS
Fixes #520
1 parent 4b8342a commit ea04549

8 files changed

+78
-13
lines changed

lib/definitions/project.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ interface IPlatformProjectService {
2727
interpolateData(projectRoot: string): IFuture<void>;
2828
afterCreateProject(projectRoot: string): IFuture<void>;
2929
buildProject(projectRoot: string): IFuture<void>;
30+
prepareProject(): IFuture<void>;
3031
isPlatformPrepared(projectRoot: string): IFuture<boolean>;
3132
addLibrary(platformData: IPlatformData, libraryPath: string): IFuture<void>;
3233
canUpdatePlatform(currentVersion: string, newVersion: string): IFuture<boolean>;

lib/services/android-project-service.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ class AndroidProjectService implements IPlatformProjectService {
5151
frameworkFilesExtensions: [".jar", ".dat", ".so"],
5252
configurationFileName: "AndroidManifest.xml",
5353
configurationFilePath: path.join(this.$projectData.platformsDir, "android", "AndroidManifest.xml"),
54-
mergeXmlConfig: [{ "nodename": "manifest", "attrname": "*" }]
54+
mergeXmlConfig: [{ "nodename": "manifest", "attrname": "*" }, { "application": "manifest", "attrname": "*" }]
5555
};
5656
}
5757

@@ -273,6 +273,10 @@ class AndroidProjectService implements IPlatformProjectService {
273273
public getFrameworkFilesExtensions(): string[] {
274274
return [".jar", ".dat"];
275275
}
276+
277+
public prepareProject(): IFuture<void> {
278+
return (() => { }).future<void>()();
279+
}
276280

277281
private copy(projectRoot: string, frameworkDir: string, files: string, cpArg: string): IFuture<void> {
278282
return (() => {

lib/services/ios-project-service.ts

+55-5
Original file line numberDiff line numberDiff line change
@@ -182,13 +182,11 @@ class IOSProjectService implements IPlatformProjectService {
182182
this.$fs.ensureDirectoryExists(targetPath).wait();
183183
shell.cp("-R", libraryPath, targetPath);
184184

185-
var pbxProjPath = path.join(platformData.projectRoot, this.$projectData.projectName + ".xcodeproj", "project.pbxproj");
186-
var project = new xcode.project(pbxProjPath);
187-
project.parseSync();
185+
let project = this.createPbxProj();
188186

189187
project.addFramework(path.join(targetPath, frameworkName + ".framework"), { customFramework: true, embed: true });
190188
project.updateBuildProperty("IPHONEOS_DEPLOYMENT_TARGET", "8.0");
191-
this.$fs.writeFile(pbxProjPath, project.writeSync()).wait();
189+
this.savePbxProj(project).wait();
192190
this.$logger.info("The iOS Deployment Target is now 8.0 in order to support Cocoa Touch Frameworks.");
193191
}).future<void>()();
194192
}
@@ -221,11 +219,63 @@ class IOSProjectService implements IPlatformProjectService {
221219
shell.cp("-R", path.join(cachedPackagePath, "*"), path.join(this.platformData.projectRoot, util.format("%s.xcodeproj", this.$projectData.projectName)));
222220
this.$logger.info("Copied from %s at %s.", cachedPackagePath, this.platformData.projectRoot);
223221

224-
225222
var pbxprojFilePath = path.join(this.platformData.projectRoot, this.$projectData.projectName + IOSProjectService.XCODE_PROJECT_EXT_NAME, "project.pbxproj");
226223
this.replaceFileContent(pbxprojFilePath).wait();
227224
}).future<void>()();
228225
}
226+
227+
public prepareProject(): IFuture<void> {
228+
return (() => {
229+
let project = this.createPbxProj();
230+
let resources = project.pbxGroupByName("Resources");
231+
232+
if(resources) {
233+
let references = project.pbxFileReferenceSection();
234+
235+
let xcodeProjectImages = _.map(<any[]>resources.children, resource => this.replace(references[resource.value].name));
236+
this.$logger.trace("Images from Xcode project");
237+
this.$logger.trace(xcodeProjectImages);
238+
239+
let appResourcesImages = this.$fs.readDirectory(this.platformData.appResourcesDestinationDirectoryPath).wait();
240+
this.$logger.trace("Current images from App_Resources");
241+
this.$logger.trace(appResourcesImages);
242+
243+
let imagesToAdd = _.difference(appResourcesImages, xcodeProjectImages);
244+
this.$logger.trace(`New images to add into xcode project: ${imagesToAdd.join(", ")}`);
245+
_.each(imagesToAdd, image => project.addResourceFile(path.relative(this.platformData.projectRoot, path.join( this.platformData.appResourcesDestinationDirectoryPath, image))));
246+
247+
let imagesToRemove = _.difference(xcodeProjectImages, appResourcesImages);
248+
this.$logger.trace(`Images to remove from xcode project: ${imagesToRemove.join(", ")}`);
249+
_.each(imagesToRemove, image => project.removeResourceFile(path.join(this.platformData.appResourcesDestinationDirectoryPath, image)));
250+
251+
this.savePbxProj(project).wait();
252+
}
253+
254+
}).future<void>()();
255+
}
256+
257+
private replace(name: string): string {
258+
if(_.startsWith(name, '"')) {
259+
name = name.substr(1, name.length-2);
260+
}
261+
262+
return name.replace(/\\\"/g, "\"");
263+
}
264+
265+
private get pbxProjPath(): string {
266+
return path.join(this.platformData.projectRoot, this.$projectData.projectName + ".xcodeproj", "project.pbxproj");
267+
}
268+
269+
private createPbxProj(): any {
270+
let project = new xcode.project(this.pbxProjPath);
271+
project.parseSync();
272+
273+
return project;
274+
}
275+
276+
private savePbxProj(project: any): IFuture<void> {
277+
return this.$fs.writeFile(this.pbxProjPath, project.writeSync());
278+
}
229279

230280
private buildPathToXcodeProjectFile(version: string): string {
231281
return path.join(this.$npmInstallationManager.getCachedPackagePath(this.platformData.frameworkPackageName, version), constants.PROJECT_FRAMEWORK_FOLDER_NAME, util.format("%s.xcodeproj", IOSProjectService.IOS_PROJECT_NAME_PLACEHOLDER), "project.pbxproj");

lib/services/platform-service.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,8 @@ export class PlatformService implements IPlatformService {
161161
this.$fs.ensureDirectoryExists(platformData.appResourcesDestinationDirectoryPath).wait(); // Should be deleted
162162
var appResourcesDirectoryPath = path.join(platformData.appDestinationDirectoryPath, constants.APP_FOLDER_NAME, constants.APP_RESOURCES_FOLDER_NAME);
163163
if (this.$fs.exists(appResourcesDirectoryPath).wait()) {
164-
shell.cp("-Rf", path.join(appResourcesDirectoryPath, platformData.normalizedPlatformName, "*"), platformData.appResourcesDestinationDirectoryPath);
164+
this.$fs.deleteDirectory(platformData.appResourcesDestinationDirectoryPath).wait(); // Respect removed files
165+
shell.cp("-R", path.join(appResourcesDirectoryPath, platformData.normalizedPlatformName, "*"), platformData.appResourcesDestinationDirectoryPath);
165166
this.$fs.deleteDirectory(appResourcesDirectoryPath).wait();
166167
}
167168

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@
6868
"utf-8-validate": "https://github.com/telerik/utf-8-validate/tarball/master",
6969
"winreg": "0.0.12",
7070
"ws": "0.7.1",
71-
"xcode": "https://github.com/NativeScript/node-xcode/archive/NativeScript-0.9.tar.gz",
71+
"xcode": "https://github.com/NativeScript/node-xcode/archive/NativeScript-1.1.tar.gz",
7272
"xmldom": "0.1.19",
7373
"xmlhttprequest": "https://github.com/telerik/node-XMLHttpRequest/tarball/master",
7474
"xmlmerge-js": "0.2.4",

test/npm-support.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,10 @@ describe("Npm support tests", () => {
121121
appDestinationDirectoryPath: appDestinationFolderPath,
122122
appResourcesDestinationDirectoryPath: path.join(appDestinationFolderPath, "app", "App_Resources"),
123123
frameworkPackageName: "tns-android",
124-
normalizedPlatformName: "Android"
124+
normalizedPlatformName: "Android",
125+
platformProjectService: {
126+
prepareProject: () => Future.fromResult()
127+
}
125128
}
126129
};
127130

test/platform-service.ts

+8-2
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,10 @@ describe('Platform Service Tests', () => {
225225
return {
226226
appDestinationDirectoryPath: appDestFolderPath,
227227
appResourcesDestinationDirectoryPath: appResourcesFolderPath,
228-
normalizedPlatformName: "iOS"
228+
normalizedPlatformName: "iOS",
229+
platformProjectService: {
230+
prepareProject: () => Future.fromResult()
231+
}
229232
}
230233
};
231234

@@ -276,7 +279,10 @@ describe('Platform Service Tests', () => {
276279
return {
277280
appDestinationDirectoryPath: appDestFolderPath,
278281
appResourcesDestinationDirectoryPath: appResourcesFolderPath,
279-
normalizedPlatformName: "Android"
282+
normalizedPlatformName: "Android",
283+
platformProjectService: {
284+
prepareProject: () => Future.fromResult()
285+
}
280286
}
281287
};
282288

test/stubs.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -276,8 +276,8 @@ export class PlatformProjectServiceStub implements IPlatformProjectService {
276276
afterCreateProject(projectRoot: string): IFuture<void> {
277277
return Future.fromResult();
278278
}
279-
prepareProject(platformData: IPlatformData): IFuture<string> {
280-
return Future.fromResult("");
279+
prepareProject(): IFuture<void> {
280+
return Future.fromResult();
281281
}
282282
buildProject(projectRoot: string): IFuture<void> {
283283
return Future.fromResult();

0 commit comments

Comments
 (0)