@@ -23,6 +23,7 @@ interface INativeSourceCodeGroup {
2323
2424const DevicePlatformSdkName = "iphoneos" ;
2525const SimulatorPlatformSdkName = "iphonesimulator" ;
26+ const FRAMEWORK_EXTENSIONS = [ ".framework" , ".xcframework" ] ;
2627
2728const getPlatformSdkName = ( forDevice : boolean ) : string => forDevice ? DevicePlatformSdkName : SimulatorPlatformSdkName ;
2829const getConfigurationName = ( release : boolean ) : string => release ? Configurations . Release : Configurations . Debug ;
@@ -88,8 +89,7 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
8889 packageNames : [ `${ projectData . projectName } .app` , `${ projectData . projectName } .zip` ]
8990 } ;
9091 } ,
91- frameworkFilesExtensions : [ ".a" , ".framework" , ".bin" ] ,
92- frameworkDirectoriesExtensions : [ ".framework" ] ,
92+ frameworkDirectoriesExtensions : FRAMEWORK_EXTENSIONS ,
9393 frameworkDirectoriesNames : [ "Metadata" , "metadataGenerator" , "NativeScript" , "internal" ] ,
9494 targetedOS : [ 'darwin' ] ,
9595 configurationFileName : constants . INFO_PLIST_FILE_NAME ,
@@ -155,6 +155,9 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
155155 this . replaceFileName ( "-Info.plist" , projectRootFilePath , projectData ) ;
156156 }
157157 this . replaceFileName ( "-Prefix.pch" , projectRootFilePath , projectData ) ;
158+ if ( this . $fs . exists ( path . join ( projectRootFilePath , IOSProjectService . IOS_PROJECT_NAME_PLACEHOLDER + ".entitlements" ) ) ) {
159+ this . replaceFileName ( ".entitlements" , projectRootFilePath , projectData ) ;
160+ }
158161
159162 const xcschemeDirPath = path . join ( this . getPlatformData ( projectData ) . projectRoot , IOSProjectService . IOS_PROJECT_NAME_PLACEHOLDER + IosProjectConstants . XcodeProjExtName , "xcshareddata/xcschemes" ) ;
160163 const xcschemeFilePath = path . join ( xcschemeDirPath , IOSProjectService . IOS_PROJECT_NAME_PLACEHOLDER + IosProjectConstants . XcodeSchemeExtName ) ;
@@ -225,17 +228,38 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
225228 return Promise . resolve ( ) ;
226229 }
227230
231+ private async isDynamicFramework ( frameworkPath : string ) : Promise < boolean > {
232+ const frameworkName = path . basename ( frameworkPath , path . extname ( frameworkPath ) ) ;
233+ const isDynamicFrameworkBundle = async ( bundlePath : string ) => {
234+ const frameworkBinaryPath = path . join ( bundlePath , frameworkName ) ;
235+
236+ return _ . includes ( ( await this . $childProcess . spawnFromEvent ( "file" , [ frameworkBinaryPath ] , "close" ) ) . stdout , "dynamically linked" ) ;
237+ } ;
238+
239+ if ( path . extname ( frameworkPath ) === ".xcframework" ) {
240+ let isDynamic = true ;
241+ const subDirs = this . $fs . readDirectory ( frameworkPath ) . filter ( entry => this . $fs . getFsStats ( entry ) . isDirectory ( ) ) ;
242+ for ( const subDir of subDirs ) {
243+ const singlePlatformFramework = path . join ( subDir , frameworkName + ".framework" ) ;
244+ if ( this . $fs . exists ( singlePlatformFramework ) ) {
245+ isDynamic = await isDynamicFrameworkBundle ( singlePlatformFramework ) ;
246+ break ;
247+ }
248+ }
249+
250+ return isDynamic ;
251+ } else {
252+ return await isDynamicFrameworkBundle ( frameworkName ) ;
253+ }
254+ }
255+
228256 private async addFramework ( frameworkPath : string , projectData : IProjectData ) : Promise < void > {
229257 if ( ! this . $hostInfo . isWindows ) {
230258 this . validateFramework ( frameworkPath ) ;
231259
232260 const project = this . createPbxProj ( projectData ) ;
233- const frameworkName = path . basename ( frameworkPath , path . extname ( frameworkPath ) ) ;
234- const frameworkBinaryPath = path . join ( frameworkPath , frameworkName ) ;
235- const isDynamic = _ . includes ( ( await this . $childProcess . spawnFromEvent ( "file" , [ frameworkBinaryPath ] , "close" ) ) . stdout , "dynamically linked" ) ;
236261 const frameworkAddOptions : IXcode . Options = { customFramework : true } ;
237-
238- if ( isDynamic ) {
262+ if ( this . isDynamicFramework ( frameworkPath ) ) {
239263 frameworkAddOptions [ "embed" ] = true ;
240264 }
241265
@@ -577,8 +601,10 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
577601 return target ;
578602 }
579603
580- private getAllLibsForPluginWithFileExtension ( pluginData : IPluginData , fileExtension : string ) : string [ ] {
581- const filterCallback = ( fileName : string , pluginPlatformsFolderPath : string ) => path . extname ( fileName ) === fileExtension ;
604+ private getAllLibsForPluginWithFileExtension ( pluginData : IPluginData , fileExtension : string | string [ ] ) : string [ ] {
605+ const fileExtensions = _ . isArray ( fileExtension ) ? fileExtension : [ fileExtension ] ;
606+ const filterCallback = ( fileName : string , pluginPlatformsFolderPath : string ) =>
607+ fileExtensions . indexOf ( path . extname ( fileName ) ) !== - 1 ;
582608 return this . getAllNativeLibrariesForPlugin ( pluginData , IOSProjectService . IOS_PLATFORM_NAME , filterCallback ) ;
583609 }
584610
@@ -599,7 +625,7 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
599625 const plistJson = this . $plistParser . parseFileSync ( infoPlistPath ) ;
600626 const packageType = plistJson [ "CFBundlePackageType" ] ;
601627
602- if ( packageType !== "FMWK" ) {
628+ if ( packageType !== "FMWK" && packageType !== "XFWK" ) {
603629 this . $errors . failWithoutHelp ( "The bundle at %s does not appear to be a dynamic framework." , libraryPath ) ;
604630 }
605631 }
@@ -679,7 +705,7 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
679705 this . savePbxProj ( project , projectData ) ;
680706 }
681707 private async prepareFrameworks ( pluginPlatformsFolderPath : string , pluginData : IPluginData , projectData : IProjectData ) : Promise < void > {
682- for ( const fileName of this . getAllLibsForPluginWithFileExtension ( pluginData , ".framework" ) ) {
708+ for ( const fileName of this . getAllLibsForPluginWithFileExtension ( pluginData , FRAMEWORK_EXTENSIONS ) ) {
683709 await this . addFramework ( path . join ( pluginPlatformsFolderPath , fileName ) , projectData ) ;
684710 }
685711 }
@@ -700,7 +726,7 @@ export class IOSProjectService extends projectServiceBaseLib.PlatformProjectServ
700726
701727 private removeFrameworks ( pluginPlatformsFolderPath : string , pluginData : IPluginData , projectData : IProjectData ) : void {
702728 const project = this . createPbxProj ( projectData ) ;
703- _ . each ( this . getAllLibsForPluginWithFileExtension ( pluginData , ".framework" ) , fileName => {
729+ _ . each ( this . getAllLibsForPluginWithFileExtension ( pluginData , FRAMEWORK_EXTENSIONS ) , fileName => {
704730 const relativeFrameworkPath = this . getLibSubpathRelativeToProjectPath ( fileName , projectData ) ;
705731 project . removeFramework ( relativeFrameworkPath , { customFramework : true , embed : true } ) ;
706732 } ) ;
0 commit comments