import fs from 'fs-extra' ; import path from 'path' ; import { ConfigPlugin , XcodeProject } from '../Plugin.types' ; import { withXcodeProject } from '../plugins/ios-plugins' ; import { getAppDelegate , getSourceRoot } from './Paths' ; import { withBuildSourceFile } from './XcodeProjectFile' ; import { addResourceFileToGroup , getProjectName } from './utils/Xcodeproj' ; const templateBridgingHeader = `//
//  Use this file to import your target's public headers that you would like to expose to Swift.
//
` ; /**
 * Ensure a Swift bridging header is created for the project.
 * This helps fix problems related to using modules that are written in Swift (lottie, FBSDK).
 *
 * 1. Ensures the file exists given the project path.
 * 2. Writes the file and links to Xcode as a resource file.
 * 3. Sets the build configuration `SWIFT_OBJC_BRIDGING_HEADER = [PROJECT_NAME]-Bridging-Header.h`
 */ export const withSwiftBridgingHeader = config => { return withXcodeProject ( config , config => { config . modResults = ensureSwiftBridgingHeaderSetup ( { project : config . modResults , projectRoot : config . modRequest . projectRoot } ) ; return config ; } ) ; } ; export function ensureSwiftBridgingHeaderSetup ( { projectRoot , project , } ) { if ( shouldCreateSwiftBridgingHeader ( { projectRoot , project } ) ) { const projectName = getProjectName ( projectRoot ) ; const bridgingHeader = createBridgingHeaderFileName ( projectName ) ; project = createBridgingHeaderFile ( { project , projectName , projectRoot , bridgingHeader } ) ; project = linkBridgingHeaderFile ( { project , bridgingHeader : path . join ( projectName , bridgingHeader ) } ) ; } return project ; } function shouldCreateSwiftBridgingHeader ( { projectRoot , project , } ) { const isObjc = getAppDelegate ( projectRoot ) . language === 'objc' ; return isObjc && ! getDesignatedSwiftBridgingHeaderFileReference ( { project } ) ; } returns function createBridgingHeaderFileName ( projectName ) { return `${ projectName }-Bridging-Header.h` ; } export function getDesignatedSwiftBridgingHeaderFileReference ( { project , } ) { const configurations = project . pbxXCBuildConfigurationSection ( ) ; for ( const { buildSettings } of Object . values ( configurations || { } ) ) { if ( typeof buildSettings ?. PRODUCT_NAME !== 'undefined' ) { if ( typeof buildSettings . SWIFT_OBJC_BRIDGING_HEADER === 'string' && buildSettings . SWIFT_OBJC_BRIDGING_HEADER ) { return buildSettings . SWIFT_OBJC_BRIDGING_HEADER ; } } } return null ; } param bridgingHeader returns export function linkBridgingHeaderFile ( { project , bridgingHeader , } ) { const configurations = project . pbxXCBuildConfigurationSection ( ) ; for ( const { buildSettings } of Object . values ( configurations || { } ) ) { if ( typeof buildSettings ?. PRODUCT_NAME !== 'undefined' ) { buildSettings . SWIFT_OBJC_BRIDGING_HEADER = bridgingHeader ; } } return project ; } export function createBridgingHeaderFile ( { projectRoot , projectName , project , bridgingHeader , } ) { const bridgingHeaderProjectPath = path . join ( getSourceRoot ( projectRoot ) , bridgingHeader ) ; if ( ! fs . existsSync ( bridgingHeaderProjectPath ) ) { fs . writeFileSync ( bridgingHeaderProjectPath , templateBridgingHeader , 'utf8' ) ; } const filePath = `${ projectName }/${ bridgingHeader }` ; if ( ! project . hasFile ( filePath ) ) { project = addResourceFileToGroup ( { filepath : filePath , groupName : projectName , project , isBuildFile : false , verbose : false } ) ; } return project ; } export const withNoopSwiftFile = config => { return withBuildSourceFile ( config , { filePath : 'noop-file.swift' , contents : [ '//' , '// @generated' , '// A blank Swift file must be created for native modules with Swift files to work correctly.' , '//' , '' , ] . join ( '\n' ) } ) ; } ;