mx-jpush-expo
Version:
Expo 集成极光推送(JPush)一体化解决方案,支持 iOS/Android 厂商通道
179 lines • 8.05 kB
JavaScript
;
/**
* iOS Bridging Header 配置
* 支持 Swift/OC 混编
* 参考: https://juejin.cn/post/7554288083597885467
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.withIosBridgingHeader = void 0;
exports.applyBridgingHeaderBuildSettings = applyBridgingHeaderBuildSettings;
exports.getBridgingHeaderFilePath = getBridgingHeaderFilePath;
exports.upsertBridgingHeaderImports = upsertBridgingHeaderImports;
exports.syncBridgingHeaderFile = syncBridgingHeaderFile;
const config_plugins_1 = require("expo/config-plugins");
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const sourceCode_1 = require("../utils/sourceCode");
const APPLICATION_PRODUCT_TYPE = 'com.apple.product-type.application';
const BRIDGING_HEADER_IMPORTS = [
'#import <JPUSHService.h>',
'#import <RCTJPushModule.h>',
'#import <RCTJPushEventQueue.h>',
];
const BRIDGING_HEADER_BUILD_SETTING = 'SWIFT_OBJC_BRIDGING_HEADER';
const BRIDGING_HEADER_FILE_SUFFIX = '-Bridging-Header.h';
function getApplicationTargetInfo(xcodeProject) {
const applicationTarget = xcodeProject.getTarget(APPLICATION_PRODUCT_TYPE);
if (!applicationTarget) {
throw new Error('[MX_JPush_Expo] 未找到 iOS application target');
}
const targetName = (0, sourceCode_1.normalizeQuotedName)(applicationTarget.target.name);
if (!targetName) {
throw new Error('[MX_JPush_Expo] 未找到 iOS application target 名称');
}
const buildConfigurationListId = applicationTarget.target.buildConfigurationList;
if (!buildConfigurationListId) {
throw new Error('[MX_JPush_Expo] 未找到 application target 的 buildConfigurationList');
}
const configurationList = xcodeProject.pbxXCConfigurationList()[buildConfigurationListId];
const buildConfigurationIds = configurationList?.buildConfigurations?.map((configuration) => configuration.value) ?? [];
if (buildConfigurationIds.length === 0) {
throw new Error('[MX_JPush_Expo] application target 未关联任何 build configuration');
}
return {
buildConfigurationIds,
targetName,
};
}
function getDefaultRelativeHeaderPath(targetName) {
return `${targetName}/${targetName}${BRIDGING_HEADER_FILE_SUFFIX}`;
}
function getExistingBridgingHeaderPath(xcodeProject, buildConfigurationIds) {
const configurations = xcodeProject.pbxXCBuildConfigurationSection();
for (const configurationId of buildConfigurationIds) {
const currentValue = configurations[configurationId]?.buildSettings?.[BRIDGING_HEADER_BUILD_SETTING];
if (typeof currentValue === 'string' && currentValue.trim()) {
return currentValue;
}
if (Array.isArray(currentValue)) {
const firstValue = currentValue.find((value) => typeof value === 'string' && value.trim().length > 0);
if (firstValue) {
return firstValue;
}
}
}
return undefined;
}
function normalizeRelativeHeaderPath(existingPath, targetName) {
const defaultRelativePath = getDefaultRelativeHeaderPath(targetName);
if (!existingPath) {
return defaultRelativePath;
}
const normalizedPath = path.posix
.normalize(existingPath
.replace(/^"(.*)"$/, '$1')
.replace(/^\$\(SRCROOT\)\//, '')
.replace(/\$\(TARGET_NAME\)/g, targetName)
.replace(/\\/g, '/')
.trim())
.replace(/^\.\//, '');
const isEscapingProjectRoot = !normalizedPath ||
normalizedPath === '.' ||
normalizedPath === '..' ||
normalizedPath.startsWith('../');
const isAbsolutePath = path.posix.isAbsolute(normalizedPath) || /^[A-Za-z]:\//.test(normalizedPath);
if (isEscapingProjectRoot || isAbsolutePath) {
return defaultRelativePath;
}
return normalizedPath;
}
function resolveBridgingHeaderRelativePath(xcodeProject) {
const applicationTarget = getApplicationTargetInfo(xcodeProject);
const existingPath = getExistingBridgingHeaderPath(xcodeProject, applicationTarget.buildConfigurationIds);
return normalizeRelativeHeaderPath(existingPath, applicationTarget.targetName);
}
function applyBridgingHeaderBuildSettings(xcodeProject, bridgingHeaderPath) {
const applicationTarget = getApplicationTargetInfo(xcodeProject);
const configurations = xcodeProject.pbxXCBuildConfigurationSection();
for (const configurationId of applicationTarget.buildConfigurationIds) {
const configuration = configurations[configurationId];
if (!configuration) {
continue;
}
configuration.buildSettings = configuration.buildSettings ?? {};
configuration.buildSettings.SWIFT_OBJC_BRIDGING_HEADER = bridgingHeaderPath;
}
return applicationTarget.targetName;
}
function getBridgingHeaderFilePath(projectRoot, relativeHeaderPath) {
return path.join(projectRoot, 'ios', relativeHeaderPath);
}
function upsertBridgingHeaderImports(content) {
const normalizedContent = content.trimEnd();
const missingImports = BRIDGING_HEADER_IMPORTS.filter((importLine) => !content.includes(importLine));
if (missingImports.length === 0) {
return normalizedContent ? `${normalizedContent}\n` : '';
}
const additions = [
content.includes('// JPush 相关导入') ? null : '// JPush 相关导入',
...missingImports,
].filter((line) => !!line);
const prefix = normalizedContent ? `${normalizedContent}\n` : '';
return `${prefix}${additions.join('\n')}\n`;
}
function syncBridgingHeaderFile(filePath) {
fs.mkdirSync(path.dirname(filePath), { recursive: true });
const currentContent = fs.existsSync(filePath) ? fs.readFileSync(filePath, 'utf8') : '';
const nextContent = upsertBridgingHeaderImports(currentContent);
if (currentContent !== nextContent) {
fs.writeFileSync(filePath, nextContent);
}
}
/**
* 配置 iOS 桥接头文件
* 支持 React Native 0.83.6+ 的 Swift 新架构
*/
const withIosBridgingHeader = (config) => (0, config_plugins_1.withXcodeProject)(config, (config) => {
console.log('\n[MX_JPush_Expo] 配置 Bridging Header ...');
const xcodeProject = config.modResults;
const relativeBridgingHeaderPath = resolveBridgingHeaderRelativePath(xcodeProject);
applyBridgingHeaderBuildSettings(xcodeProject, `"${relativeBridgingHeaderPath}"`);
const bridgingHeaderFilePath = getBridgingHeaderFilePath(config.modRequest.projectRoot, relativeBridgingHeaderPath);
syncBridgingHeaderFile(bridgingHeaderFilePath);
return config;
});
exports.withIosBridgingHeader = withIosBridgingHeader;
//# sourceMappingURL=bridgingHeader.js.map