1import fs from 'fs'; 2import path from 'path'; 3 4import { addBuildSourceFileToGroup, getProjectName } from './utils/Xcodeproj'; 5import { ConfigPlugin, XcodeProject } from '../Plugin.types'; 6import { withXcodeProject } from '../plugins/ios-plugins'; 7 8/** 9 * Create a build source file and link it to Xcode. 10 * 11 * @param config 12 * @param props.filePath relative to the build source folder. ex: `ViewController.swift` would be created in `ios/myapp/ViewController.swift`. 13 * @param props.contents file contents to write. 14 * @param props.overwrite should the contents overwrite any existing file in the same location on disk. 15 * @returns 16 */ 17export const withBuildSourceFile: ConfigPlugin<{ 18 filePath: string; 19 contents: string; 20 overwrite?: boolean; 21}> = (config, { filePath, contents, overwrite }) => { 22 return withXcodeProject(config, (config) => { 23 const projectName = getProjectName(config.modRequest.projectRoot); 24 25 config.modResults = createBuildSourceFile({ 26 project: config.modResults, 27 nativeProjectRoot: config.modRequest.platformProjectRoot, 28 fileContents: contents, 29 filePath: path.join(projectName, filePath), 30 overwrite, 31 }); 32 return config; 33 }); 34}; 35 36/** 37 * Add a source file to the Xcode project and write it to the file system. 38 * 39 * @param nativeProjectRoot absolute path to the native app root `user/app/ios` 40 * @param filePath path relative to the `nativeProjectRoot` for the file to create `user/app/ios/myapp/foobar.swift` 41 * @param fileContents string file contents to write to the `filePath` 42 * @param overwrite should write file even if one already exists 43 */ 44export function createBuildSourceFile({ 45 project, 46 nativeProjectRoot, 47 filePath, 48 fileContents, 49 overwrite, 50}: { 51 project: XcodeProject; 52 nativeProjectRoot: string; 53 filePath: string; 54 fileContents: string; 55 overwrite?: boolean; 56}): XcodeProject { 57 const absoluteFilePath = path.join(nativeProjectRoot, filePath); 58 if (overwrite || !fs.existsSync(absoluteFilePath)) { 59 // Create the file 60 fs.writeFileSync(absoluteFilePath, fileContents, 'utf8'); 61 } 62 63 // `myapp` 64 const groupName = path.dirname(filePath); 65 66 // Ensure the file is linked with Xcode resource files 67 if (!project.hasFile(filePath)) { 68 project = addBuildSourceFileToGroup({ 69 filepath: filePath, 70 groupName, 71 project, 72 }); 73 } 74 return project; 75} 76