Skip to content

Commit 9943819

Browse files
authored
Merge pull request #22 from BlackishGreen33/bg/upstream-fix-plugin-gate-ios-debug-and-align-version
fix(plugin): gate iOS debug logs and align plugin metadata
2 parents f3e4890 + afa3629 commit 9943819

12 files changed

Lines changed: 137 additions & 173 deletions

README.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,8 @@ export default ({ config }: ConfigContext): ExpoConfig => {
170170
- `appKey``channel``packageName` 仍然是插件必填项
171171
- iOS 初始化参数会写入 `Info.plist`,不再直接拼进 `AppDelegate.swift`
172172
- Android `manifestPlaceholders` 优先读取环境变量或 `gradle.properties`,缺失时会回退到插件配置里的 `appKey` / `channel` / `packageName`
173+
- 如果宿主已经定义了 `manifestPlaceholders`,插件会通过 `manifestPlaceholders += [...]` 追加 JPush 字段
174+
非 JPush 的宿主键会被保留;如果宿主和插件都声明了同名的 `JPUSH_*` 键,后追加的 JPush 默认值会生效
173175
- `vendorChannels` 决定要注入哪些厂商 SDK 与占位符;若声明某个厂商通道,就必须提供该厂商要求的必填字段
174176
- 厂商密钥仍然建议交给环境变量,避免把敏感信息直接提交到仓库
175177

@@ -261,14 +263,15 @@ JPUSH_XIAOMI_APP_KEY=your-xiaomi-app-key
261263
- `fetch`
262264
- `remote-notification`
263265
- `AppDelegate.swift` 中存在 `JPUSHService.setup`
266+
- `AppDelegate.swift` 中的调试日志与 `JPUSHService.setDebugMode()` 会被 `#if DEBUG` 包裹,release 构建不再无条件打印
264267
- 如果项目使用 Swift,插件会优先复用已有 `SWIFT_OBJC_BRIDGING_HEADER`;未配置时会自动创建 `<target>-Bridging-Header.h`
265268

266269
### Android
267270

268-
`android/app/build.gradle` 中的 `manifestPlaceholders` 应保持"运行时读取",而不是写死明文:
271+
`android/app/build.gradle` 中的 JPush 占位符应保持"运行时读取",而不是写死明文:
269272

270273
```gradle
271-
manifestPlaceholders = [
274+
manifestPlaceholders += [
272275
JPUSH_PKGNAME: System.getenv("JPUSH_PKGNAME") ?: (project.findProperty("JPUSH_PKGNAME") ?: "com.your.app"),
273276
JPUSH_APPKEY: System.getenv("JPUSH_APP_KEY") ?: (project.findProperty("JPUSH_APP_KEY") ?: "your-jpush-app-key"),
274277
JPUSH_CHANNEL: System.getenv("JPUSH_CHANNEL") ?: (project.findProperty("JPUSH_CHANNEL") ?: "developer-default")
@@ -277,6 +280,8 @@ manifestPlaceholders = [
277280

278281
也就是说:
279282

283+
- 宿主原本的 `manifestPlaceholders = [...]` 配置会被保留
284+
- 对于宿主和插件都声明的 `JPUSH_*` 键,后追加的 JPush 值会在合并结果中生效
280285
- 对最终消费方,插件配置本身已经足够让 `prebuild` 产出可用的 Android 默认值
281286
- 对 CI / EAS / 多环境发布,依然推荐通过环境变量或 `gradle.properties` 在构建时覆盖这些值
282287
- 厂商通道密钥如果需要按环境切换,也应沿用同样的覆盖策略

app.plugin.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* 支持 Expo SDK 53+ 和 React Native 0.79.5+
66
*
77
* @author MuxiStudio
8-
* @version 1.2.3-beta.0
8+
* @version 1.2.4
99
*
1010
* 参考文档:
1111
* - JPush 集成 Expo: https://juejin.cn/post/7423235127716659239

plugin/__tests__/androidTransforms.test.ts

Lines changed: 47 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,37 @@ import { applyAndroidGradleProperties } from '../src/android/gradleProperties';
66
import { applyAndroidProjectBuildGradle } from '../src/android/projectBuildGradle';
77
import { applyAndroidSettingsGradle } from '../src/android/settingsGradle';
88
import { mergeContents } from '../src/utils/generateCode';
9-
import { setConfig } from '../src/utils/config';
109

1110
const readFixture = (fixturePath: string): string =>
1211
fs.readFileSync(path.join(__dirname, 'fixtures', fixturePath), 'utf8');
1312

14-
describe('Android transforms', () => {
15-
beforeEach(() => {
16-
setConfig('demo-app-key', 'demo-channel', 'com.demo.app', false, undefined);
17-
});
13+
const TEST_APP_KEY = 'demo-app-key';
14+
const TEST_CHANNEL = 'demo-channel';
15+
const TEST_PACKAGE_NAME = 'com.demo.app';
1816

17+
describe('Android transforms', () => {
1918
it('should inject app/build.gradle for enabled vendors and remain idempotent', () => {
2019
const vendorChannels = {
2120
fcm: { enabled: true },
2221
huawei: { enabled: true },
2322
xiaomi: { appId: 'xiaomi-id', appKey: 'xiaomi-key' },
2423
};
25-
setConfig('demo-app-key', 'demo-channel', 'com.demo.app', false, vendorChannels);
2624

2725
const fixture = readFixture('android/app-build.gradle.fixture');
28-
const transformed = applyAndroidAppBuildGradle(fixture, vendorChannels);
29-
const repeated = applyAndroidAppBuildGradle(transformed, vendorChannels);
26+
const transformed = applyAndroidAppBuildGradle(
27+
fixture,
28+
vendorChannels,
29+
TEST_PACKAGE_NAME,
30+
TEST_APP_KEY,
31+
TEST_CHANNEL
32+
);
33+
const repeated = applyAndroidAppBuildGradle(
34+
transformed,
35+
vendorChannels,
36+
TEST_PACKAGE_NAME,
37+
TEST_APP_KEY,
38+
TEST_CHANNEL
39+
);
3040

3141
expect(transformed).toContain('defaultConfig {');
3242
expect(transformed).toContain('manifestPlaceholders += [');
@@ -45,9 +55,21 @@ describe('Android transforms', () => {
4555
huawei: { enabled: true },
4656
oppo: { appId: 'oppo-id', appKey: 'oppo-key', appSecret: 'oppo-secret' },
4757
};
48-
const enabled = applyAndroidAppBuildGradle(fixture, vendorConfig);
58+
const enabled = applyAndroidAppBuildGradle(
59+
fixture,
60+
vendorConfig,
61+
TEST_PACKAGE_NAME,
62+
TEST_APP_KEY,
63+
TEST_CHANNEL
64+
);
4965

50-
const disabled = applyAndroidAppBuildGradle(enabled, undefined);
66+
const disabled = applyAndroidAppBuildGradle(
67+
enabled,
68+
undefined,
69+
TEST_PACKAGE_NAME,
70+
TEST_APP_KEY,
71+
TEST_CHANNEL
72+
);
5173

5274
expect(disabled).toContain(`implementation project(':jpush-react-native')`);
5375
expect(disabled).not.toContain(`com.google.firebase:firebase-messaging`);
@@ -97,7 +119,13 @@ describe('Android transforms', () => {
97119
comment: '//',
98120
}).contents;
99121

100-
const upgraded = applyAndroidAppBuildGradle(withLegacyFileTree, undefined);
122+
const upgraded = applyAndroidAppBuildGradle(
123+
withLegacyFileTree,
124+
undefined,
125+
TEST_PACKAGE_NAME,
126+
TEST_APP_KEY,
127+
TEST_CHANNEL
128+
);
101129

102130
expect(upgraded).not.toContain('@generated begin jpush-ndk-config');
103131
expect(upgraded).not.toContain('@generated begin jpush-libs-filetree');
@@ -130,7 +158,6 @@ describe('Android transforms', () => {
130158
expect(enabled).toContain(`https://developer.hihonor.com/repo`);
131159
expect(repeated).toBe(enabled);
132160

133-
setConfig('demo-app-key', 'demo-channel', 'com.demo.app', false, undefined);
134161
const disabled = applyAndroidProjectBuildGradle(enabled);
135162

136163
expect(disabled).not.toContain(`com.google.gms:google-services`);
@@ -140,12 +167,11 @@ describe('Android transforms', () => {
140167
});
141168

142169
it('should remove legacy project/build.gradle generated sections during upgrade', () => {
143-
setConfig('demo-app-key', 'demo-channel', 'com.demo.app', false, {
170+
const vendorChannels = {
144171
fcm: { enabled: true },
145172
huawei: { enabled: true },
146173
honor: { appId: 'honor-id' },
147-
});
148-
174+
};
149175
const fixture = readFixture('android/project-build.gradle.fixture');
150176
const withLegacyBuildscriptHuawei = mergeContents({
151177
src: fixture,
@@ -189,7 +215,10 @@ describe('Android transforms', () => {
189215
comment: '//',
190216
}).contents;
191217

192-
const upgraded = applyAndroidProjectBuildGradle(withLegacyHonorAllprojects);
218+
const upgraded = applyAndroidProjectBuildGradle(
219+
withLegacyHonorAllprojects,
220+
vendorChannels
221+
);
193222

194223
expect(upgraded).not.toContain('@generated begin jpush-huawei-maven-buildscript');
195224
expect(upgraded).not.toContain('@generated begin jpush-honor-maven-buildscript');
@@ -227,11 +256,9 @@ describe('Android transforms', () => {
227256
});
228257

229258
it('should add gradle.properties compatibility only for Huawei', () => {
230-
setConfig('demo-app-key', 'demo-channel', 'com.demo.app', false, {
259+
const withHuawei = applyAndroidGradleProperties([], {
231260
huawei: { enabled: true },
232261
});
233-
234-
const withHuawei = applyAndroidGradleProperties([]);
235262
expect(withHuawei).toEqual([
236263
{
237264
type: 'property',
@@ -240,8 +267,7 @@ describe('Android transforms', () => {
240267
},
241268
]);
242269

243-
setConfig('demo-app-key', 'demo-channel', 'com.demo.app', false, undefined);
244-
const withoutHuawei = applyAndroidGradleProperties(withHuawei);
270+
const withoutHuawei = applyAndroidGradleProperties(withHuawei, undefined);
245271
expect(withoutHuawei).toBe(withHuawei);
246272
});
247273
});

plugin/__tests__/iosTransforms.test.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import {
99
upsertBridgingHeaderImports,
1010
} from '../src/ios/bridgingHeader';
1111
import { applyIosInfoPlist, mergeBackgroundModes } from '../src/ios/infoPlist';
12-
import { setConfig } from '../src/utils/config';
1312

1413
const readFixture = (fixturePath: string): string =>
1514
fs.readFileSync(path.join(__dirname, 'fixtures', fixturePath), 'utf8');
@@ -54,10 +53,6 @@ function createMockXcodeProject() {
5453
}
5554

5655
describe('iOS transforms', () => {
57-
beforeEach(() => {
58-
setConfig('demo-app-key', 'demo-channel', 'com.demo.app', true, undefined);
59-
});
60-
6156
it('should merge Info.plist background modes without overwriting existing values', () => {
6257
expect(mergeBackgroundModes(['processing', 'fetch'])).toEqual([
6358
'processing',
@@ -94,6 +89,8 @@ describe('iOS transforms', () => {
9489

9590
expect(transformed).toContain('import UserNotifications');
9691
expect(transformed).toContain('JPUSHService.setup(withOption: launchOptions');
92+
expect(transformed).toContain('#if DEBUG');
93+
expect(transformed).toContain('JPUSHService.setDebugMode()');
9794
expect(transformed).toContain('didRegisterForRemoteNotificationsWithDeviceToken');
9895
expect(transformed).toContain('extension AppDelegate: JPUSHRegisterDelegate');
9996
expect(repeated).toBe(transformed);

plugin/__tests__/nativeIosAppDelegate.test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ describe('native iOS AppDelegate mod', () => {
2727
expect(appDelegate).toContain(
2828
'JPUSHService.register(forRemoteNotificationConfig: entity, delegate: self)'
2929
);
30+
expect(appDelegate).toContain('#if DEBUG');
31+
expect(appDelegate).toContain('JPUSHService.setDebugMode()');
3032
expect(appDelegate).toContain('JPUSHService.setup(withOption: launchOptions,');
3133
expect(appDelegate).toContain(
3234
'didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data'
@@ -66,6 +68,7 @@ describe('native iOS AppDelegate mod', () => {
6668
'JPUSHService.register(forRemoteNotificationConfig: entity, delegate: self)'
6769
)
6870
).toBe(1);
71+
expect(countOccurrences(twiceCompiled, '#if DEBUG')).toBeGreaterThan(0);
6972
expect(
7073
countOccurrences(
7174
twiceCompiled,

plugin/src/android/appBuildGradle.ts

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import {
1111
replaceGeneratedContentsAtLine,
1212
syncGeneratedContentsAtEnd,
1313
} from '../utils/generateCode';
14-
import { getConfig } from '../utils/config';
1514
import {
1615
ensureNestedBlock,
1716
ensureTopLevelBlock,
@@ -52,18 +51,16 @@ function removeLegacyGeneratedSections(contents: string, tags: string[]): string
5251
}
5352

5453
function getResolvedConfig({
55-
packageName,
56-
appKey,
57-
channel,
54+
packageName = '',
55+
appKey = '',
56+
channel = '',
5857
vendorChannels,
5958
}: AndroidBuildGradleConfigInput): ResolvedAndroidBuildGradleConfig {
60-
const fallbackConfig = getConfig();
61-
6259
return {
63-
appKey: appKey ?? fallbackConfig?.appKey ?? '',
64-
channel: channel ?? fallbackConfig?.channel ?? '',
65-
packageName: packageName ?? fallbackConfig?.packageName ?? '',
66-
vendorChannels: vendorChannels ?? fallbackConfig?.vendorChannels,
60+
appKey,
61+
channel,
62+
packageName,
63+
vendorChannels,
6764
};
6865
}
6966

plugin/src/android/gradleProperties.ts

Lines changed: 9 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@
55

66
import { ExpoConfig } from 'expo/config';
77
import { withGradleProperties } from 'expo/config-plugins';
8-
import { ResolvedJPushPluginProps } from '../types';
9-
import { getVendorChannels } from '../utils/vendorChannels';
8+
import { ResolvedJPushPluginProps, VendorChannelConfig } from '../types';
109

1110
type GradleProperty =
1211
| {
@@ -22,9 +21,10 @@ type GradleProperty =
2221
value: string;
2322
};
2423

25-
export function applyAndroidGradleProperties(properties: GradleProperty[]): GradleProperty[] {
26-
const vendorChannels = getVendorChannels();
27-
24+
export function applyAndroidGradleProperties(
25+
properties: GradleProperty[],
26+
vendorChannels?: VendorChannelConfig
27+
): GradleProperty[] {
2828
if (!vendorChannels?.huawei?.enabled) {
2929
return properties;
3030
}
@@ -63,25 +63,10 @@ export function withAndroidGradleProperties(
6363
props: Pick<ResolvedJPushPluginProps, 'vendorChannels'>
6464
): ExpoConfig {
6565
return withGradleProperties(config, (nextConfig) => {
66-
if (props.vendorChannels?.huawei?.enabled === true) {
67-
console.log(
68-
'\n[MX_JPush_Expo] 配置 gradle.properties 华为 AGC 兼容性(Gradle 8.0)...'
69-
);
70-
71-
const existingProp = nextConfig.modResults.find(
72-
(prop) =>
73-
prop.type === 'property' && prop.key === 'apmsInstrumentationEnabled'
74-
);
75-
76-
if (!existingProp) {
77-
nextConfig.modResults.push({
78-
type: 'property',
79-
key: 'apmsInstrumentationEnabled',
80-
value: 'false',
81-
});
82-
}
83-
}
84-
66+
nextConfig.modResults = applyAndroidGradleProperties(
67+
nextConfig.modResults,
68+
props.vendorChannels
69+
);
8570
return nextConfig;
8671
});
8772
}

plugin/src/android/projectBuildGradle.ts

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,47 @@ import { withProjectBuildGradle } from 'expo/config-plugins';
99
import { VendorChannelConfig } from '../types';
1010
import { removeGeneratedContents, syncGeneratedContentsAtLine } from '../utils/generateCode';
1111
import { ensureTopLevelBlock, ensureNestedBlock, findNestedBlockRange } from '../utils/sourceCode';
12-
import { getProjectVendorFlags, LEGACY_PROJECT_BUILD_TAGS, getBuildscriptRepositories } from '../utils/vendorChannels';
12+
13+
const LEGACY_PROJECT_BUILD_TAGS = [
14+
'jpush-buildscript-repositories',
15+
'jpush-buildscript-classpaths',
16+
'jpush-allprojects-repositories',
17+
'jpush-huawei-maven-buildscript',
18+
'jpush-honor-maven-buildscript',
19+
'jpush-vendor-classpaths',
20+
'jpush-huawei-maven-allprojects',
21+
'jpush-honor-maven-allprojects',
22+
];
23+
24+
function getProjectVendorFlags(
25+
vendorChannels?: VendorChannelConfig
26+
): Record<string, boolean> {
27+
if (!vendorChannels) {
28+
return {};
29+
}
30+
31+
return Object.fromEntries(
32+
Object.entries(vendorChannels).map(([key, value]) => [
33+
key,
34+
Boolean(value?.enabled || value?.appId || value?.appKey),
35+
])
36+
);
37+
}
38+
39+
function getBuildscriptRepositories(vendorChannels?: VendorChannelConfig): string {
40+
const flags = getProjectVendorFlags(vendorChannels);
41+
const repositories: string[] = [];
42+
43+
if (flags.huawei) {
44+
repositories.push(`maven { url 'https://developer.huawei.com/repo/' }`);
45+
}
46+
47+
if (flags.honor) {
48+
repositories.push(`maven { url 'https://developer.hihonor.com/repo' }`);
49+
}
50+
51+
return repositories.join('\n ');
52+
}
1353

1454
/**
1555
* 获取厂商通道开启标记
@@ -150,7 +190,7 @@ export function applyAndroidProjectBuildGradle(
150190

151191
export function withAndroidProjectBuildGradle(
152192
config: ExpoConfig,
153-
props: { vendorChannels?: any }
193+
props: { vendorChannels?: VendorChannelConfig }
154194
): ExpoConfig {
155195
return withProjectBuildGradle(config, (config) => {
156196
const { vendorChannels } = props;
@@ -160,4 +200,4 @@ export function withAndroidProjectBuildGradle(
160200
);
161201
return config;
162202
});
163-
}
203+
}

0 commit comments

Comments
 (0)