Created
March 25, 2023 23:34
-
-
Save shichen85/ab1d96fac2a2d8c25b735dc392718611 to your computer and use it in GitHub Desktop.
Use npm XCode to add localization metadata to an iOS project generated by GameMaker.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { dirname, basename, join } from 'path'; | |
import fs from 'fs-extra'; | |
//@ts-ignore | |
import xcode from 'xcode'; | |
export async function addLocalizationWithXCode( | |
projectPath: string, | |
languages: L10nLang[], | |
) { | |
const languageFileRootDir = getLanguageFileRootDir(projectPath); | |
// No types available. See https://www.npmjs.com/package/xcode for API | |
const parsedProj = xcode.project(projectPath); | |
const gameLanguages = languages; | |
const englishFileName = join( | |
languageFileRootDir, | |
'en.lproj', | |
'InfoPlist.strings', | |
); | |
return new Promise((resolve, reject) => { | |
parsedProj.parse(function (err: any) { | |
if (err) { | |
return reject(err); | |
} else { | |
gameLanguages.forEach((language) => { | |
if (language != 'en-US') { | |
//GMS's xcodeproj has en-us by default | |
//For example, adding "zh-Hans" requires the presence of the file ".../demo/zh-Hans.lproj/InfoPlist.strings" | |
const xcodeLang = l10nToXcode(language); | |
const languageFileDir = `${xcodeLang.replace( | |
/"/g, | |
'', | |
)}.lproj/InfoPlist.strings`; | |
const languageFileDirAbsolute = join( | |
languageFileRootDir, | |
languageFileDir, | |
); | |
fs.ensureFileSync(languageFileDirAbsolute); | |
fs.copyFileSync(englishFileName, languageFileDirAbsolute); | |
const groupKey = parsedProj.findPBXVariantGroupKey({ | |
name: 'InfoPlist.strings', | |
}); | |
/** | |
* | |
* @param path {String} | |
* @param group {String} group key | |
* @param opt {Object} see pbxFile for avail options | |
* @returns {Object} file; see pbxFile | |
*/ | |
parsedProj.addFile(languageFileDir, groupKey); | |
parsedProj.addKnownRegion(xcodeLang); | |
} | |
}); | |
fs.writeFileSync(projectPath, parsedProj.writeSync()); | |
return resolve( | |
`Successfully added localization for ${languages.join(',')}`, | |
); | |
} | |
}); | |
}); | |
} | |
const l10nToXcodeDic = { | |
'zh-CN': '"zh-Hans"', | |
'ru-RU': 'ru', | |
'es-XL': 'es', | |
'es-ES': '"es-419"', | |
'pt-BR': '"pt-BR"', | |
'de-DE': 'de', | |
'it-IT': 'it', | |
'fr-FR': 'fr', | |
'ja-JP': 'ja', | |
'ko-KR': 'ko', | |
'zh-TW': '"zh-Hant"', | |
'en-US': 'en', | |
}; | |
export type L10nLang = keyof typeof l10nToXcodeDic; | |
function l10nToXcode(l10nLang: L10nLang) { | |
const xcodeLang = l10nToXcodeDic[l10nLang]; | |
if (xcodeLang) { | |
return xcodeLang; | |
} else { | |
throw new Error(`${l10nLang} does not exist in the l10nToXcodeDic!`); | |
} | |
} | |
/** | |
* @desc ".../demo.xcodeproj/project.pbxproj" should return ".../demo/" | |
* @param projectPath | |
*/ | |
function getLanguageFileRootDir(projectPath: string) { | |
const projectDir = dirname(projectPath); | |
const projectName = basename(projectDir, '.xcodeproj'); | |
const languageFileRootDir = join(dirname(projectDir), projectName); | |
return languageFileRootDir; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment