@@ -11,6 +11,7 @@ import * as constants from "../constants";
1111import * as helpers from "../common/helpers" ;
1212import * as projectServiceBaseLib from "./platform-project-service-base" ;
1313import Future = require( "fibers/future" ) ;
14+ import { PlistSession } from "plist-merge-patch" ;
1415
1516export class IOSProjectService extends projectServiceBaseLib . PlatformProjectServiceBase implements IPlatformProjectService {
1617 private static XCODE_PROJECT_EXT_NAME = ".xcodeproj" ;
@@ -33,7 +34,8 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
3334 private $injector : IInjector ,
3435 $projectDataService : IProjectDataService ,
3536 private $prompter : IPrompter ,
36- private $config : IConfiguration ) {
37+ private $config : IConfiguration ,
38+ private $devicePlatformsConstants : Mobile . IDevicePlatformsConstants ) {
3739 super ( $fs , $projectData , $projectDataService ) ;
3840 }
3941
@@ -350,12 +352,89 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
350352
351353 public prepareAppResources ( appResourcesDirectoryPath : string ) : IFuture < void > {
352354 return ( ( ) => {
355+ let platformFolder = path . join ( appResourcesDirectoryPath , this . platformData . normalizedPlatformName ) ;
356+ let filterFile = ( filename : string ) => this . $fs . deleteFile ( path . join ( platformFolder , filename ) ) . wait ( ) ;
357+
358+ filterFile ( this . platformData . configurationFileName ) ;
359+
353360 this . $fs . deleteDirectory ( this . getAppResourcesDestinationDirectoryPath ( ) . wait ( ) ) . wait ( ) ;
354361 } ) . future < void > ( ) ( ) ;
355362 }
356363
357364 public processConfigurationFilesFromAppResources ( ) : IFuture < void > {
358- return Future . fromResult ( ) ;
365+ return ( ( ) => {
366+ this . mergeInfoPlists ( ) . wait ( ) ;
367+ } ) . future < void > ( ) ( ) ;
368+ }
369+
370+ private mergeInfoPlists ( ) : IFuture < void > {
371+ return ( ( ) => {
372+ let projectDir = this . $projectData . projectDir ;
373+ let infoPlistPath = path . join ( projectDir , constants . APP_FOLDER_NAME , constants . APP_RESOURCES_FOLDER_NAME , this . platformData . normalizedPlatformName , this . platformData . configurationFileName ) ;
374+
375+ if ( ! this . $fs . exists ( infoPlistPath ) . wait ( ) ) {
376+ // The project is missing Info.plist, try to populate it from the project tempalte.
377+ let projectTemplateService : IProjectTemplatesService = this . $injector . resolve ( "projectTemplatesService" ) ;
378+ let defaultTemplatePath = projectTemplateService . defaultTemplatePath . wait ( ) ;
379+ let templateInfoPlist = path . join ( defaultTemplatePath , constants . APP_RESOURCES_FOLDER_NAME , this . $devicePlatformsConstants . iOS , this . platformData . configurationFileName ) ;
380+ if ( this . $fs . exists ( templateInfoPlist ) . wait ( ) ) {
381+ this . $logger . trace ( "Info.plist: app/App_Resources/iOS/Info.plist is missing. Upgrading the source of the project with one from the new project template. Copy " + templateInfoPlist + " to " + infoPlistPath ) ;
382+ try {
383+ this . $fs . copyFile ( templateInfoPlist , infoPlistPath ) . wait ( ) ;
384+ } catch ( e ) {
385+ this . $logger . trace ( "Copying template's Info.plist failed. " + e ) ;
386+ }
387+ } else {
388+ this . $logger . trace ( "Info.plist: app/App_Resources/iOS/Info.plist is missing but the template " + templateInfoPlist + " is missing too, can not upgrade Info.plist." ) ;
389+ }
390+ }
391+
392+ if ( ! this . $fs . exists ( infoPlistPath ) . wait ( ) ) {
393+ this . $logger . trace ( "Info.plist: No app/App_Resources/iOS/Info.plist found, falling back to pre-1.6.0 Info.plist behavior." ) ;
394+ return ;
395+ }
396+
397+ let session = new PlistSession ( { log : ( txt : string ) => this . $logger . trace ( "Info.plist: " + txt ) } ) ;
398+ let makePatch = ( plistPath : string ) => {
399+ if ( ! this . $fs . exists ( plistPath ) . wait ( ) ) {
400+ return ;
401+ }
402+
403+ session . patch ( {
404+ name : path . relative ( projectDir , plistPath ) ,
405+ read : ( ) => this . $fs . readFile ( plistPath ) . wait ( ) . toString ( )
406+ } ) ;
407+ } ;
408+
409+ let allPlugins : IPluginData [ ] = ( < IPluginsService > this . $injector . resolve ( "pluginsService" ) ) . getAllInstalledPlugins ( ) . wait ( ) ;
410+ for ( let plugin of allPlugins ) {
411+ let pluginInfoPlistPath = path . join ( plugin . pluginPlatformsFolderPath ( IOSProjectService . IOS_PLATFORM_NAME ) , this . platformData . configurationFileName ) ;
412+ makePatch ( pluginInfoPlistPath ) ;
413+ }
414+
415+ makePatch ( infoPlistPath ) ;
416+
417+ if ( this . $projectData . projectId ) {
418+ session . patch ( {
419+ name : "CFBundleIdentifier from package.json nativescript.id" ,
420+ read : ( ) =>
421+ `<?xml version="1.0" encoding="UTF-8"?>
422+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
423+ <plist version="1.0">
424+ <dict>
425+ <key>CFBundleIdentifier</key>
426+ <string>${ this . $projectData . projectId } </string>
427+ </dict>
428+ </plist>`
429+ } ) ;
430+ }
431+
432+ let plistContent = session . build ( ) ;
433+
434+ this . $logger . trace ( "Info.plist: Write to: " + this . platformData . configurationFilePath ) ;
435+ this . $fs . writeFile ( this . platformData . configurationFilePath , plistContent ) . wait ( ) ;
436+
437+ } ) . future < void > ( ) ( ) ;
359438 }
360439
361440 private get projectPodFilePath ( ) : string {
0 commit comments