zcw-shared 1.44.2 → 1.46.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -10,33 +10,32 @@ import { configureIOSPermissions } from '../../ios/configurePermissions';
10
10
  import { modifyInfoPlistKeyValue } from '../../ios/modifyInfoPlistKeyValue';
11
11
  import { safelyModifyProjectPbxproj } from '../../ios/safelyModifyProjectPbxproj';
12
12
  export async function buildIOSApp(options, deps) {
13
- const logs = [];
14
13
  if (!options.uniappProjectPath) {
15
14
  return {
16
15
  success: false,
17
16
  error: 'uniappProjectPath 是必需的',
18
- logs
17
+ logs: []
19
18
  };
20
19
  }
21
20
  if (!options.projectPath) {
22
21
  return {
23
22
  success: false,
24
23
  error: 'projectPath 是必需的',
25
- logs
24
+ logs: []
26
25
  };
27
26
  }
28
27
  if (!options.uniAppId) {
29
28
  return {
30
29
  success: false,
31
30
  error: 'uniAppId 是必需的',
32
- logs
31
+ logs: []
33
32
  };
34
33
  }
35
34
  if (!options.displayName) {
36
35
  return {
37
36
  success: false,
38
37
  error: 'displayName 是必需的',
39
- logs
38
+ logs: []
40
39
  };
41
40
  }
42
41
  try {
@@ -47,16 +46,16 @@ export async function buildIOSApp(options, deps) {
47
46
  return {
48
47
  success: false,
49
48
  error: `在 ${options.projectPath} 中未找到 Xcode 项目文件(.xcodeproj)`,
50
- logs
49
+ logs: []
51
50
  };
52
51
  }
53
52
  const projectFile = projectFiles[0];
54
53
  const projectName = options.sourceDirectoryName || projectFile.replace(/\.xcodeproj$/, '');
55
- logs.push(`找到 Xcode 项目: ${projectFile}`);
54
+ deps.log(`找到 Xcode 项目: ${projectFile}`);
56
55
  if (options.sourceDirectoryName) {
57
- logs.push(`使用指定的源码目录: ${projectName}`);
56
+ deps.log(`使用指定的源码目录: ${projectName}`);
58
57
  }
59
- logs.push('步骤 1: 同步 project.pbxproj 版本配置');
58
+ deps.log('步骤 1: 同步 project.pbxproj 版本配置');
60
59
  const projectPbxprojPath = deps.join(options.projectPath, projectFile, 'project.pbxproj');
61
60
  const pbxprojResult = safelyModifyProjectPbxproj(projectPbxprojPath, {
62
61
  bundleId: options.bundleId,
@@ -70,12 +69,12 @@ export async function buildIOSApp(options, deps) {
70
69
  writeFileSync: deps.writeFileSync
71
70
  });
72
71
  if (pbxprojResult.success) {
73
- logs.push('project.pbxproj 版本配置同步完成');
72
+ deps.log('project.pbxproj 版本配置同步完成');
74
73
  }
75
74
  else {
76
- logs.push(`project.pbxproj 版本配置同步失败: ${pbxprojResult.error}`);
75
+ deps.log(`project.pbxproj 版本配置同步失败: ${pbxprojResult.error}`);
77
76
  }
78
- logs.push('步骤 2: 修改 Info.plist 配置');
77
+ deps.log('步骤 2: 修改 Info.plist 配置');
79
78
  const infoPlistPath = deps.join(options.projectPath, projectName, `${projectName}-Info.plist`);
80
79
  if (deps.existsSync(infoPlistPath)) {
81
80
  try {
@@ -125,20 +124,20 @@ export async function buildIOSApp(options, deps) {
125
124
  const serializer = new deps.xmlSerializer();
126
125
  const newXmlContent = serializer.serializeToString(xmlDoc);
127
126
  deps.writeFileSync(infoPlistPath, newXmlContent, 'utf8');
128
- logs.push('Info.plist 配置完成');
127
+ deps.log('Info.plist 配置完成');
129
128
  if (options.enableIDFA) {
130
- logs.push('IDFA 配置完成');
129
+ deps.log('IDFA 配置完成');
131
130
  }
132
131
  if (options.buildCustomBase) {
133
- logs.push('Application supports iTunes file sharing 配置完成');
132
+ deps.log('Application supports iTunes file sharing 配置完成');
134
133
  }
135
134
  }
136
135
  catch (error) {
137
- logs.push(`配置 Info.plist 失败: ${error instanceof Error ? error.message : String(error)}`);
136
+ deps.log(`配置 Info.plist 失败: ${error instanceof Error ? error.message : String(error)}`);
138
137
  }
139
138
  }
140
139
  if (options.permissions && options.permissions.length > 0) {
141
- logs.push('步骤 2.1: 配置 iOS 权限');
140
+ deps.log('步骤 2.1: 配置 iOS 权限');
142
141
  const permissionsResult = await configureIOSPermissions(infoPlistPath, options.permissions, undefined, {
143
142
  existsSync: deps.existsSync,
144
143
  readFileSync: deps.readFileSync,
@@ -147,16 +146,16 @@ export async function buildIOSApp(options, deps) {
147
146
  xmlSerializer: deps.xmlSerializer
148
147
  });
149
148
  if (permissionsResult.success) {
150
- logs.push('iOS 权限配置完成');
151
- logs.push(...permissionsResult.logs);
149
+ deps.log('iOS 权限配置完成');
150
+ permissionsResult.logs.forEach(msg => deps.log(msg));
152
151
  }
153
152
  else {
154
- logs.push(`iOS 权限配置失败: ${permissionsResult.error}`);
155
- logs.push(...permissionsResult.logs);
153
+ deps.log(`iOS 权限配置失败: ${permissionsResult.error}`);
154
+ permissionsResult.logs.forEach(msg => deps.log(msg));
156
155
  }
157
156
  }
158
157
  if (options.displayName) {
159
- logs.push('步骤 2.2: 修改本地化字符串文件');
158
+ deps.log('步骤 2.2: 修改本地化字符串文件');
160
159
  const projectDir = deps.join(options.projectPath, projectName);
161
160
  const lprojDirs = ['en.lproj', 'zh-Hans.lproj', 'zh-Hant.lproj', 'Base.lproj', 'English.lproj'];
162
161
  for (const lprojDir of lprojDirs) {
@@ -172,18 +171,18 @@ export async function buildIOSApp(options, deps) {
172
171
  content += `\nCFBundleDisplayName="${options.displayName}";\n`;
173
172
  }
174
173
  deps.writeFileSync(infoPlistStringsPath, content, 'utf8');
175
- logs.push(`已更新 ${lprojDir}/InfoPlist.strings`);
174
+ deps.log(`已更新 ${lprojDir}/InfoPlist.strings`);
176
175
  }
177
176
  catch (error) {
178
- logs.push(`更新 ${lprojDir}/InfoPlist.strings 失败: ${error instanceof Error ? error.message : String(error)}`);
177
+ deps.log(`更新 ${lprojDir}/InfoPlist.strings 失败: ${error instanceof Error ? error.message : String(error)}`);
179
178
  }
180
179
  }
181
180
  }
182
181
  }
183
182
  if (options.appIconPath) {
184
- logs.push('步骤 2: 配置 App Icons Source');
183
+ deps.log('步骤 2: 配置 App Icons Source');
185
184
  if (!deps.sharp) {
186
- logs.push('警告: 未提供 sharp 依赖,跳过图标配置。请安装 sharp 并在 deps 中传入。');
185
+ deps.log('警告: 未提供 sharp 依赖,跳过图标配置。请安装 sharp 并在 deps 中传入。');
187
186
  }
188
187
  else {
189
188
  const appIconResult = await configureAppIconIOS(options.appIconPath, options.projectPath, projectName, {
@@ -196,19 +195,19 @@ export async function buildIOSApp(options, deps) {
196
195
  sharp: deps.sharp
197
196
  });
198
197
  if (appIconResult.success) {
199
- logs.push('App Icons Source 配置完成');
200
- logs.push(...appIconResult.logs);
198
+ deps.log('App Icons Source 配置完成');
199
+ appIconResult.logs.forEach(msg => deps.log(msg));
201
200
  }
202
201
  else {
203
- logs.push(`App Icons Source 配置失败: ${appIconResult.error}`);
204
- logs.push(...appIconResult.logs);
202
+ deps.log(`App Icons Source 配置失败: ${appIconResult.error}`);
203
+ appIconResult.logs.forEach(msg => deps.log(msg));
205
204
  }
206
205
  }
207
206
  }
208
207
  if (options.launchScreenPath) {
209
- logs.push('步骤 3: 配置 LaunchScreen');
208
+ deps.log('步骤 3: 配置 LaunchScreen');
210
209
  if (!deps.sharp) {
211
- logs.push('警告: 未提供 sharp 依赖,跳过启动屏配置。请安装 sharp 并在 deps 中传入。');
210
+ deps.log('警告: 未提供 sharp 依赖,跳过启动屏配置。请安装 sharp 并在 deps 中传入。');
212
211
  }
213
212
  else {
214
213
  const launchScreenResult = await configureLaunchScreen(options.launchScreenPath, options.projectPath, projectName, {
@@ -221,17 +220,17 @@ export async function buildIOSApp(options, deps) {
221
220
  sharp: deps.sharp
222
221
  });
223
222
  if (launchScreenResult.success) {
224
- logs.push('LaunchScreen 配置完成');
225
- logs.push(...launchScreenResult.logs);
223
+ deps.log('LaunchScreen 配置完成');
224
+ launchScreenResult.logs.forEach(msg => deps.log(msg));
226
225
  }
227
226
  else {
228
- logs.push(`LaunchScreen 配置失败: ${launchScreenResult.error}`);
229
- logs.push(...launchScreenResult.logs);
227
+ deps.log(`LaunchScreen 配置失败: ${launchScreenResult.error}`);
228
+ launchScreenResult.logs.forEach(msg => deps.log(msg));
230
229
  }
231
230
  }
232
231
  }
233
232
  if (options.buildCustomBase) {
234
- logs.push('步骤 4: 配置自定义基座(control.xml)');
233
+ deps.log('步骤 4: 配置自定义基座(control.xml)');
235
234
  const controlXmlPath = deps.join(options.projectPath, projectName, 'control.xml');
236
235
  if (deps.existsSync(controlXmlPath)) {
237
236
  try {
@@ -254,37 +253,37 @@ export async function buildIOSApp(options, deps) {
254
253
  const serializer = new deps.xmlSerializer();
255
254
  const newXmlContent = serializer.serializeToString(xmlDoc);
256
255
  deps.writeFileSync(controlXmlPath, newXmlContent, 'utf8');
257
- logs.push('control.xml 自定义基座配置完成:debug="true" syncDebug="true"');
256
+ deps.log('control.xml 自定义基座配置完成:debug="true" syncDebug="true"');
258
257
  }
259
258
  else {
260
- logs.push('control.xml 自定义基座配置已存在,无需修改');
259
+ deps.log('control.xml 自定义基座配置已存在,无需修改');
261
260
  }
262
261
  }
263
262
  else {
264
- logs.push('警告:未找到 HBuilder 根节点,无法添加自定义基座配置');
263
+ deps.log('警告:未找到 HBuilder 根节点,无法添加自定义基座配置');
265
264
  }
266
265
  }
267
266
  catch (error) {
268
- logs.push(`配置 control.xml 失败: ${error instanceof Error ? error.message : String(error)}`);
267
+ deps.log(`配置 control.xml 失败: ${error instanceof Error ? error.message : String(error)}`);
269
268
  }
270
269
  }
271
270
  }
272
- logs.push('步骤 8: 编译 UniApp 项目并复制到 apps 目录');
271
+ deps.log('步骤 8: 编译 UniApp 项目并复制到 apps 目录');
273
272
  let sourcePath;
274
273
  if (options.uniappBuildOutputPath) {
275
- logs.push('使用提供的 UniApp 编译结果路径');
274
+ deps.log('使用提供的 UniApp 编译结果路径');
276
275
  sourcePath = options.uniappBuildOutputPath;
277
276
  if (!deps.existsSync(sourcePath)) {
278
277
  return {
279
278
  success: false,
280
279
  error: `提供的编译结果路径不存在: ${sourcePath}`,
281
- logs
280
+ logs: []
282
281
  };
283
282
  }
284
- logs.push(`使用编译结果路径: ${sourcePath}`);
283
+ deps.log(`使用编译结果路径: ${sourcePath}`);
285
284
  }
286
285
  else {
287
- logs.push('构建 UniApp 项目');
286
+ deps.log('构建 UniApp 项目');
288
287
  const buildDeps = {
289
288
  exec: deps.exec,
290
289
  join: deps.join,
@@ -296,10 +295,10 @@ export async function buildIOSApp(options, deps) {
296
295
  return {
297
296
  success: false,
298
297
  error: `构建失败: ${uniBuildResult.error}`,
299
- logs: [...logs, ...uniBuildResult.logs]
298
+ logs: []
300
299
  };
301
300
  }
302
- logs.push(...uniBuildResult.logs);
301
+ uniBuildResult.logs.forEach(msg => deps.log(msg));
303
302
  sourcePath = deps.join(options.uniappProjectPath, 'dist', 'build', 'app');
304
303
  }
305
304
  const targetPath = deps.join(options.projectPath, projectName, 'Pandora', 'apps', options.uniAppId, 'www');
@@ -309,13 +308,13 @@ export async function buildIOSApp(options, deps) {
309
308
  deps.mkdirSync(targetDir, { recursive: true });
310
309
  }
311
310
  await deps.cp(sourcePath, targetPath, { recursive: true, force: true });
312
- logs.push('应用资源复制完成');
311
+ deps.log('应用资源复制完成');
313
312
  }
314
313
  catch (error) {
315
314
  return {
316
315
  success: false,
317
316
  error: `复制应用资源失败: ${error instanceof Error ? error.message : String(error)}`,
318
- logs
317
+ logs: []
319
318
  };
320
319
  }
321
320
  const controlXmlPath = deps.join(options.projectPath, projectName, 'control.xml');
@@ -341,13 +340,13 @@ export async function buildIOSApp(options, deps) {
341
340
  if (options.appkey && appElement.getAttribute('appkey') !== options.appkey) {
342
341
  appElement.setAttribute('appkey', options.appkey);
343
342
  hasChanges = true;
344
- logs.push(`更新 appkey: ${options.appkey}`);
343
+ deps.log(`更新 appkey: ${options.appkey}`);
345
344
  }
346
345
  if (hasChanges) {
347
- logs.push(`更新现有 app 元素,appid: ${options.uniAppId}`);
346
+ deps.log(`更新现有 app 元素,appid: ${options.uniAppId}`);
348
347
  }
349
348
  else {
350
- logs.push(`app 元素已存在且配置正确,appid: ${options.uniAppId}`);
349
+ deps.log(`app 元素已存在且配置正确,appid: ${options.uniAppId}`);
351
350
  }
352
351
  break;
353
352
  }
@@ -356,41 +355,41 @@ export async function buildIOSApp(options, deps) {
356
355
  while (existingAppElements.length > 0) {
357
356
  appsElement.removeChild(existingAppElements[0]);
358
357
  }
359
- logs.push('已删除所有现有的 app 元素');
358
+ deps.log('已删除所有现有的 app 元素');
360
359
  const newAppElement = xmlDoc.createElement('app');
361
360
  newAppElement.setAttribute('appid', options.uniAppId);
362
361
  newAppElement.setAttribute('appver', '');
363
362
  if (options.appkey) {
364
363
  newAppElement.setAttribute('appkey', options.appkey);
365
- logs.push(`设置 appkey: ${options.appkey}`);
364
+ deps.log(`设置 appkey: ${options.appkey}`);
366
365
  }
367
366
  appsElement.appendChild(newAppElement);
368
- logs.push(`添加新的 app 元素,appid: ${options.uniAppId}`);
367
+ deps.log(`添加新的 app 元素,appid: ${options.uniAppId}`);
369
368
  hasChanges = true;
370
369
  }
371
370
  if (hasChanges || !appExists) {
372
371
  const serializer = new deps.xmlSerializer();
373
372
  const newXmlContent = serializer.serializeToString(xmlDoc);
374
373
  deps.writeFileSync(controlXmlPath, newXmlContent, 'utf8');
375
- logs.push(`control.xml appid 配置完成,appid: ${options.uniAppId}`);
374
+ deps.log(`control.xml appid 配置完成,appid: ${options.uniAppId}`);
376
375
  }
377
376
  else {
378
- logs.push(`control.xml appid 配置已存在,无需修改`);
377
+ deps.log(`control.xml appid 配置已存在,无需修改`);
379
378
  }
380
379
  }
381
380
  else {
382
- logs.push('control.xml 中未找到 apps 元素');
381
+ deps.log('control.xml 中未找到 apps 元素');
383
382
  }
384
383
  }
385
384
  catch (error) {
386
- logs.push(`配置 control.xml appid 失败: ${error instanceof Error ? error.message : String(error)}`);
385
+ deps.log(`配置 control.xml appid 失败: ${error instanceof Error ? error.message : String(error)}`);
387
386
  }
388
387
  }
389
388
  if (options.appkey && options.sourceDirectoryName) {
390
389
  const pluginInfoPlistPath = deps.join(options.projectPath, options.sourceDirectoryName, 'HBuilder-uniPlugin-Info.plist');
391
390
  if (deps.existsSync(pluginInfoPlistPath)) {
392
391
  try {
393
- logs.push('配置插件项目 Info.plist (HBuilder-uniPlugin-Info.plist)');
392
+ deps.log('配置插件项目 Info.plist (HBuilder-uniPlugin-Info.plist)');
394
393
  const plistContent = deps.readFileSync(pluginInfoPlistPath, 'utf8');
395
394
  const parser = new deps.xmlParser();
396
395
  const xmlDoc = parser.parseFromString(plistContent, 'text/xml');
@@ -399,23 +398,23 @@ export async function buildIOSApp(options, deps) {
399
398
  const serializer = new deps.xmlSerializer();
400
399
  const newPlistContent = serializer.serializeToString(xmlDoc);
401
400
  deps.writeFileSync(pluginInfoPlistPath, newPlistContent, 'utf8');
402
- logs.push(`HBuilder-uniPlugin-Info.plist dcloud_appkey 配置完成: ${options.appkey}`);
401
+ deps.log(`HBuilder-uniPlugin-Info.plist dcloud_appkey 配置完成: ${options.appkey}`);
403
402
  }
404
403
  else {
405
- logs.push(`HBuilder-uniPlugin-Info.plist dcloud_appkey 配置失败(未找到或无法修改)`);
404
+ deps.log(`HBuilder-uniPlugin-Info.plist dcloud_appkey 配置失败(未找到或无法修改)`);
406
405
  }
407
406
  }
408
407
  catch (error) {
409
- logs.push(`配置 HBuilder-uniPlugin-Info.plist 失败: ${error instanceof Error ? error.message : String(error)}`);
408
+ deps.log(`配置 HBuilder-uniPlugin-Info.plist 失败: ${error instanceof Error ? error.message : String(error)}`);
410
409
  }
411
410
  }
412
411
  else {
413
- logs.push(`HBuilder-uniPlugin-Info.plist 文件不存在: ${pluginInfoPlistPath}`);
412
+ deps.log(`HBuilder-uniPlugin-Info.plist 文件不存在: ${pluginInfoPlistPath}`);
414
413
  }
415
414
  }
416
415
  const bundleId = options.bundleId || 'io.dcloud.HBuilder';
417
416
  if (options.wechatShare && bundleId) {
418
- logs.push('集成微信分享模块');
417
+ deps.log('集成微信分享模块');
419
418
  const wechatShareResult = await integrateWechatShareIOS(options.projectPath, projectName, bundleId, {
420
419
  appId: options.wechatShare.appId,
421
420
  universalLinks: options.wechatShare.universalLinks,
@@ -439,16 +438,16 @@ export async function buildIOSApp(options, deps) {
439
438
  xpath: deps.xpath
440
439
  });
441
440
  if (wechatShareResult.success) {
442
- logs.push('微信分享模块集成完成');
443
- logs.push(...wechatShareResult.logs);
441
+ deps.log('微信分享模块集成完成');
442
+ wechatShareResult.logs.forEach(msg => deps.log(msg));
444
443
  }
445
444
  else {
446
- logs.push(`微信分享模块集成失败: ${wechatShareResult.error}`);
447
- logs.push(...wechatShareResult.logs);
445
+ deps.log(`微信分享模块集成失败: ${wechatShareResult.error}`);
446
+ wechatShareResult.logs.forEach(msg => deps.log(msg));
448
447
  }
449
448
  }
450
449
  if (options.wechatOauth && bundleId) {
451
- logs.push('集成微信登录模块');
450
+ deps.log('集成微信登录模块');
452
451
  const wechatOauthResult = await integrateWechatOauthIOS(options.projectPath, projectName, bundleId, {
453
452
  appId: options.wechatOauth.appId,
454
453
  universalLinks: options.wechatOauth.universalLinks,
@@ -472,16 +471,16 @@ export async function buildIOSApp(options, deps) {
472
471
  xpath: deps.xpath
473
472
  });
474
473
  if (wechatOauthResult.success) {
475
- logs.push('微信登录模块集成完成');
476
- logs.push(...wechatOauthResult.logs);
474
+ deps.log('微信登录模块集成完成');
475
+ wechatOauthResult.logs.forEach(msg => deps.log(msg));
477
476
  }
478
477
  else {
479
- logs.push(`微信登录模块集成失败: ${wechatOauthResult.error}`);
480
- logs.push(...wechatOauthResult.logs);
478
+ deps.log(`微信登录模块集成失败: ${wechatOauthResult.error}`);
479
+ wechatOauthResult.logs.forEach(msg => deps.log(msg));
481
480
  }
482
481
  }
483
482
  if (options.qqShare && bundleId) {
484
- logs.push('集成QQ分享模块');
483
+ deps.log('集成QQ分享模块');
485
484
  const qqShareResult = await integrateQQShareIOS(options.projectPath, projectName, bundleId, {
486
485
  appId: options.qqShare.appId,
487
486
  universalLinks: options.qqShare.universalLinks,
@@ -505,16 +504,16 @@ export async function buildIOSApp(options, deps) {
505
504
  xpath: deps.xpath
506
505
  });
507
506
  if (qqShareResult.success) {
508
- logs.push('QQ分享模块集成完成');
509
- logs.push(...qqShareResult.logs);
507
+ deps.log('QQ分享模块集成完成');
508
+ qqShareResult.logs.forEach(msg => deps.log(msg));
510
509
  }
511
510
  else {
512
- logs.push(`QQ分享模块集成失败: ${qqShareResult.error}`);
513
- logs.push(...qqShareResult.logs);
511
+ deps.log(`QQ分享模块集成失败: ${qqShareResult.error}`);
512
+ qqShareResult.logs.forEach(msg => deps.log(msg));
514
513
  }
515
514
  }
516
515
  if (options.sinaShare && bundleId) {
517
- logs.push('集成新浪微博分享模块');
516
+ deps.log('集成新浪微博分享模块');
518
517
  const sinaShareResult = await integrateSinaShareIOS(options.projectPath, projectName, bundleId, {
519
518
  appKey: options.sinaShare.appKey,
520
519
  appSecret: options.sinaShare.appSecret,
@@ -540,16 +539,16 @@ export async function buildIOSApp(options, deps) {
540
539
  xpath: deps.xpath
541
540
  });
542
541
  if (sinaShareResult.success) {
543
- logs.push('新浪微博分享模块集成完成');
544
- logs.push(...sinaShareResult.logs);
542
+ deps.log('新浪微博分享模块集成完成');
543
+ sinaShareResult.logs.forEach(msg => deps.log(msg));
545
544
  }
546
545
  else {
547
- logs.push(`新浪微博分享模块集成失败: ${sinaShareResult.error}`);
548
- logs.push(...sinaShareResult.logs);
546
+ deps.log(`新浪微博分享模块集成失败: ${sinaShareResult.error}`);
547
+ sinaShareResult.logs.forEach(msg => deps.log(msg));
549
548
  }
550
549
  }
551
550
  if (options.nativePlugins && options.nativePlugins.length > 0) {
552
- logs.push('集成 UniApp 原生插件');
551
+ deps.log('集成 UniApp 原生插件');
553
552
  for (const pluginConfig of options.nativePlugins) {
554
553
  const pluginResult = await integrateNativePluginIOS(options.projectPath, projectName, pluginConfig.pluginPath, {
555
554
  existsSync: deps.existsSync,
@@ -566,51 +565,59 @@ export async function buildIOSApp(options, deps) {
566
565
  exec: deps.exec,
567
566
  parse: deps.parse,
568
567
  xmlParser: deps.xmlParser,
569
- xmlSerializer: deps.xmlSerializer
568
+ xmlSerializer: deps.xmlSerializer,
569
+ setTimeout: deps.setTimeout,
570
+ clearTimeout: deps.clearTimeout,
571
+ log: deps.log,
570
572
  }, pluginConfig.parameters);
571
573
  if (pluginResult.success) {
572
- logs.push(`原生插件集成完成: ${pluginConfig.pluginPath}`);
573
- logs.push(...pluginResult.logs);
574
+ deps.log(`原生插件集成完成: ${pluginConfig.pluginPath}`);
575
+ pluginResult.logs.forEach(msg => deps.log(msg));
574
576
  }
575
577
  else {
576
- logs.push(`原生插件集成失败: ${pluginResult.error}`);
577
- logs.push(...pluginResult.logs);
578
+ deps.log(`原生插件集成失败: ${pluginResult.error}`);
579
+ pluginResult.logs.forEach(msg => deps.log(msg));
578
580
  }
579
581
  }
580
582
  }
581
- logs.push('步骤 9: 编译 iOS 应用');
583
+ deps.log('步骤 9: 编译 iOS 应用');
582
584
  const configuration = options.configuration || 'Release';
583
585
  const scheme = options.scheme || projectName;
584
- logs.push(`提示: 签名配置必须在 Xcode 中手动设置`);
585
- logs.push(`提示: 请打开项目 ${projectFile},在 Signing & Capabilities 中配置 Team`);
586
586
  if (options.signing?.teamId) {
587
- logs.push(`提示: 开发团队 ID 应该是: ${options.signing.teamId}`);
587
+ deps.log(`签名配置: 开发团队 ID ${options.signing.teamId} 已自动配置到 project.pbxproj`);
588
588
  }
589
589
  const buildCommand = `cd "${options.projectPath}" && xcodebuild -project "${projectFile}" -scheme "${scheme}" -configuration "${configuration}" -destination "generic/platform=iOS" -allowProvisioningUpdates -archivePath "${deps.join(options.outputPath || options.projectPath, 'build', `${projectName}.xcarchive`)}" archive`;
590
590
  if (options.clean) {
591
- logs.push('清理构建目录');
591
+ deps.log('清理构建目录');
592
592
  const cleanCommand = `cd "${options.projectPath}" && xcodebuild -project "${projectFile}" -scheme "${scheme}" -destination "generic/platform=iOS" clean`;
593
593
  await new Promise((resolve) => {
594
594
  deps.exec(cleanCommand, (error, stdout, stderr) => {
595
595
  if (error) {
596
- logs.push(`清理警告: ${error.message}`);
596
+ deps.log(`清理警告: ${error.message}`);
597
597
  }
598
598
  if (stdout)
599
- logs.push(`清理输出: ${stdout}`);
599
+ deps.log(`清理输出: ${stdout}`);
600
600
  resolve();
601
601
  });
602
602
  });
603
603
  }
604
- logs.push(`执行构建命令: ${buildCommand}`);
604
+ deps.log(`执行构建命令: ${buildCommand}`);
605
+ deps.log(`提示: iOS 构建可能需要较长时间,请耐心等待...`);
606
+ deps.log(`提示: 如果超过 10 分钟没有输出,构建可能会被取消`);
607
+ let resolved = false;
605
608
  const buildResult = await new Promise((resolve) => {
606
609
  const child = deps.exec(buildCommand, (error, stdout, stderr) => {
610
+ if (resolved)
611
+ return;
612
+ resolved = true;
613
+ deps.clearTimeout(timeout);
607
614
  const allOutput = stdout + (stderr ? '\n' + stderr : '');
608
615
  if (error) {
609
- logs.push(`构建错误: ${error.message}`);
616
+ deps.log(`构建错误: ${error.message}`);
610
617
  if (stdout)
611
- logs.push(`标准输出:\n${stdout}`);
618
+ deps.log(`标准输出:\n${stdout}`);
612
619
  if (stderr)
613
- logs.push(`错误输出:\n${stderr}`);
620
+ deps.log(`错误输出:\n${stderr}`);
614
621
  const errorDetails = allOutput.includes('error:')
615
622
  ? allOutput.split('error:').slice(1).join('error:').split('\n').slice(0, 5).join('\n')
616
623
  : (stderr || stdout || error.message);
@@ -622,14 +629,18 @@ export async function buildIOSApp(options, deps) {
622
629
  return;
623
630
  }
624
631
  if (stdout)
625
- logs.push(`构建输出:\n${stdout}`);
632
+ deps.log(`构建输出:\n${stdout}`);
626
633
  if (stderr)
627
- logs.push(`警告信息:\n${stderr}`);
634
+ deps.log(`警告信息:\n${stderr}`);
628
635
  resolve({ success: true });
629
636
  });
630
- deps.setTimeout(() => {
637
+ const timeout = deps.setTimeout(() => {
638
+ if (resolved)
639
+ return;
640
+ resolved = true;
641
+ deps.log(`警告: 构建超时(10分钟),正在终止进程...`);
631
642
  child.kill();
632
- resolve({ success: false, error: '构建超时' });
643
+ resolve({ success: false, error: '构建超时(10分钟)' });
633
644
  }, 600000);
634
645
  });
635
646
  if (!buildResult.success) {
@@ -639,7 +650,7 @@ export async function buildIOSApp(options, deps) {
639
650
  return {
640
651
  success: false,
641
652
  error: errorMessage,
642
- logs
653
+ logs: []
643
654
  };
644
655
  }
645
656
  const shouldExportIPA = options.exportIPA !== false;
@@ -647,29 +658,29 @@ export async function buildIOSApp(options, deps) {
647
658
  const archivePath = deps.join(buildBasePath, `${projectName}.xcarchive`);
648
659
  if (!deps.existsSync(archivePath)) {
649
660
  const errorMessage = `Archive 文件不存在: ${archivePath}`;
650
- logs.push(errorMessage);
661
+ deps.log(errorMessage);
651
662
  return {
652
663
  success: false,
653
664
  error: errorMessage,
654
- logs
665
+ logs: []
655
666
  };
656
667
  }
657
- logs.push(`Archive 文件已找到: ${archivePath}`);
668
+ deps.log(`Archive 文件已找到: ${archivePath}`);
658
669
  if (!shouldExportIPA) {
659
- logs.push('iOS 插件项目编译完成(跳过 IPA 导出)');
660
- logs.push(`Archive 文件: ${archivePath}`);
661
- logs.push('\n💡 提示: 插件开发构建已完成,可以在 Xcode 中运行项目进行调试');
662
- logs.push('💡 如需导出 IPA,请设置 exportIPA: true');
670
+ deps.log('iOS 插件项目编译完成(跳过 IPA 导出)');
671
+ deps.log(`Archive 文件: ${archivePath}`);
672
+ deps.log('\n💡 提示: 插件开发构建已完成,可以在 Xcode 中运行项目进行调试');
673
+ deps.log('💡 如需导出 IPA,请设置 exportIPA: true');
663
674
  return {
664
675
  success: true,
665
676
  outputPath: archivePath,
666
- logs
677
+ logs: []
667
678
  };
668
679
  }
669
680
  const exportBasePath = deps.join(buildBasePath, 'export');
670
681
  if (!deps.existsSync(exportBasePath)) {
671
682
  deps.mkdirSync(exportBasePath, { recursive: true });
672
- logs.push(`创建导出目录: ${exportBasePath}`);
683
+ deps.log(`创建导出目录: ${exportBasePath}`);
673
684
  }
674
685
  const exportOptionsPlistPath = deps.join(exportBasePath, 'ExportOptions.plist');
675
686
  const method = 'development';
@@ -694,30 +705,30 @@ export async function buildIOSApp(options, deps) {
694
705
  deps.writeFileSync(exportOptionsPlistPath, exportOptionsPlistContent, 'utf8');
695
706
  if (!deps.existsSync(exportOptionsPlistPath)) {
696
707
  const errorMessage = `ExportOptions.plist 文件创建失败: ${exportOptionsPlistPath}`;
697
- logs.push(errorMessage);
708
+ deps.log(errorMessage);
698
709
  return {
699
710
  success: false,
700
711
  error: errorMessage,
701
- logs
712
+ logs: []
702
713
  };
703
714
  }
704
- logs.push(`ExportOptions.plist 文件已创建: ${exportOptionsPlistPath}`);
705
- logs.push('开始导出 IPA');
706
- logs.push(`Archive 路径: ${archivePath}`);
707
- logs.push(`导出路径: ${exportBasePath}`);
708
- logs.push(`ExportOptions.plist 路径: ${exportOptionsPlistPath}`);
709
- logs.push(`ExportOptions.plist 内容:\n${exportOptionsPlistContent}`);
715
+ deps.log(`ExportOptions.plist 文件已创建: ${exportOptionsPlistPath}`);
716
+ deps.log('开始导出 IPA');
717
+ deps.log(`Archive 路径: ${archivePath}`);
718
+ deps.log(`导出路径: ${exportBasePath}`);
719
+ deps.log(`ExportOptions.plist 路径: ${exportOptionsPlistPath}`);
720
+ deps.log(`ExportOptions.plist 内容:\n${exportOptionsPlistContent}`);
710
721
  const exportCommand = `xcodebuild -exportArchive -archivePath "${archivePath}" -exportPath "${exportBasePath}" -exportOptionsPlist "${exportOptionsPlistPath}"`;
711
- logs.push(`执行导出命令: ${exportCommand}`);
712
- logs.push('注意:如果导出失败,请检查上面的日志输出,特别是 "导出标准输出" 和 "导出错误/警告输出" 部分');
722
+ deps.log(`执行导出命令: ${exportCommand}`);
723
+ deps.log('注意:如果导出失败,请检查上面的日志输出,特别是 "导出标准输出" 和 "导出错误/警告输出" 部分');
713
724
  const exportResult = await new Promise((resolve) => {
714
725
  const child = deps.exec(exportCommand, (error, stdout, stderr) => {
715
726
  const allOutput = stdout + (stderr ? '\n' + stderr : '');
716
727
  if (stdout) {
717
- logs.push(`导出标准输出:\n${stdout}`);
728
+ deps.log(`导出标准输出:\n${stdout}`);
718
729
  }
719
730
  if (stderr) {
720
- logs.push(`导出错误/警告输出:\n${stderr}`);
731
+ deps.log(`导出错误/警告输出:\n${stderr}`);
721
732
  }
722
733
  const hasError = allOutput.toLowerCase().includes('error:') ||
723
734
  allOutput.toLowerCase().includes('failed') ||
@@ -726,7 +737,7 @@ export async function buildIOSApp(options, deps) {
726
737
  allOutput.toLowerCase().includes('export succeeded') ||
727
738
  allOutput.toLowerCase().includes('exportarchive succeeded');
728
739
  if (error) {
729
- logs.push(`导出命令执行错误: ${error.message}`);
740
+ deps.log(`导出命令执行错误: ${error.message}`);
730
741
  const errorDetails = hasError
731
742
  ? allOutput.split(/error:/i).slice(1).join('error:').split('\n').slice(0, 10).join('\n')
732
743
  : (stderr || stdout || error.message);
@@ -747,15 +758,15 @@ export async function buildIOSApp(options, deps) {
747
758
  return;
748
759
  }
749
760
  if (hasSuccess) {
750
- logs.push('导出命令执行成功(检测到成功标志)');
761
+ deps.log('导出命令执行成功(检测到成功标志)');
751
762
  resolve({ success: true });
752
763
  }
753
764
  else if (!hasError && allOutput.trim().length > 0) {
754
- logs.push('导出命令执行完成(未检测到错误,假设成功)');
765
+ deps.log('导出命令执行完成(未检测到错误,假设成功)');
755
766
  resolve({ success: true });
756
767
  }
757
768
  else if (!hasError) {
758
- logs.push('导出命令执行完成(无错误无输出,假设成功)');
769
+ deps.log('导出命令执行完成(无错误无输出,假设成功)');
759
770
  resolve({ success: true });
760
771
  }
761
772
  else {
@@ -778,17 +789,17 @@ export async function buildIOSApp(options, deps) {
778
789
  return {
779
790
  success: false,
780
791
  error: errorMessage,
781
- logs
792
+ logs: []
782
793
  };
783
794
  }
784
795
  let ipaPath;
785
796
  try {
786
797
  if (deps.existsSync(exportBasePath)) {
787
798
  const topLevelFiles = deps.readdirSync(exportBasePath);
788
- logs.push(`导出目录内容: ${topLevelFiles.join(', ')}`);
799
+ deps.log(`导出目录内容: ${topLevelFiles.join(', ')}`);
789
800
  }
790
801
  else {
791
- logs.push(`警告: 导出目录不存在: ${exportBasePath}`);
802
+ deps.log(`警告: 导出目录不存在: ${exportBasePath}`);
792
803
  }
793
804
  const findIpaFile = (dir, depth = 0) => {
794
805
  if (depth > 3) {
@@ -798,11 +809,11 @@ export async function buildIOSApp(options, deps) {
798
809
  return undefined;
799
810
  }
800
811
  const files = deps.readdirSync(dir);
801
- logs.push(`搜索目录 (深度 ${depth}): ${dir}, 文件数: ${files.length}`);
812
+ deps.log(`搜索目录 (深度 ${depth}): ${dir}, 文件数: ${files.length}`);
802
813
  const ipaFile = files.find(f => f.toLowerCase().endsWith('.ipa'));
803
814
  if (ipaFile) {
804
815
  const foundPath = deps.join(dir, ipaFile);
805
- logs.push(`找到 IPA 文件: ${foundPath}`);
816
+ deps.log(`找到 IPA 文件: ${foundPath}`);
806
817
  return foundPath;
807
818
  }
808
819
  for (const file of files) {
@@ -825,7 +836,7 @@ export async function buildIOSApp(options, deps) {
825
836
  ipaPath = findIpaFile(exportBasePath);
826
837
  }
827
838
  catch (error) {
828
- logs.push(`查找 IPA 文件时出错: ${error instanceof Error ? error.message : String(error)}`);
839
+ deps.log(`查找 IPA 文件时出错: ${error instanceof Error ? error.message : String(error)}`);
829
840
  }
830
841
  if (!ipaPath) {
831
842
  const listDirectory = (dir, prefix = '') => {
@@ -859,22 +870,22 @@ export async function buildIOSApp(options, deps) {
859
870
  };
860
871
  const dirStructure = listDirectory(exportBasePath);
861
872
  const errorMessage = `导出成功但未找到 IPA 文件,导出路径: ${exportBasePath}`;
862
- logs.push(errorMessage);
863
- logs.push('导出目录结构:');
864
- logs.push(...dirStructure);
865
- logs.push('请检查 xcodebuild 导出日志,确认是否有错误');
873
+ deps.log(errorMessage);
874
+ deps.log('导出目录结构:');
875
+ dirStructure.forEach(msg => deps.log(msg));
876
+ deps.log('请检查 xcodebuild 导出日志,确认是否有错误');
866
877
  return {
867
878
  success: false,
868
879
  error: errorMessage,
869
- logs
880
+ logs: []
870
881
  };
871
882
  }
872
- logs.push('iOS 离线打包完成');
873
- logs.push(`IPA 文件已生成: ${ipaPath}`);
883
+ deps.log('iOS 离线打包完成');
884
+ deps.log(`IPA 文件已生成: ${ipaPath}`);
874
885
  return {
875
886
  success: true,
876
887
  outputPath: ipaPath,
877
- logs
888
+ logs: []
878
889
  };
879
890
  }
880
891
  catch (error) {
@@ -882,7 +893,7 @@ export async function buildIOSApp(options, deps) {
882
893
  return {
883
894
  success: false,
884
895
  error: `打包过程中发生异常: ${errorMessage}`,
885
- logs
896
+ logs: []
886
897
  };
887
898
  }
888
899
  }