CFBundleIdentifier在React Native上不存在。

4
这里有一个简单的赏金任务,不一定需要任何React Native经验。问题似乎在于开源代码中,该代码已经公开发布:
更新了Xcode,现在当我尝试通过以下命令运行我的React Native应用程序时:react-native run-ios,我遇到了一个错误:

处理命令时遇到错误(域=NSPOSIXErrorDomain,代码=2): 未能安装请求的应用程序 提供的路径上没有找到应用程序包。 请提供所需应用程序包的有效路径。 打印:条目“:CFBundleIdentifier”不存在 错误命令:/usr/libexec/PlistBuddy -c Print:CFBundleIdentifier DerivedData/Build/Products/Debug-iphonesimulator/MyAppName.app/Info.plist 打印:条目“:CFBundleIdentifier”不存在

调试错误: 命令失败: /usr/libexec/PlistBuddy -c Print:CFBundleIdentifier DerivedData/Build/Products/Debug-iphonesimulator/MyAppName.app/Info.plist 打印: 条目 ":CFBundleIdentifier" 不存在 在 checkExecSyncError (child_process.js:616:11) 在 Object.execFileSync (child_process.js:634:13) 在 runOnSimulator (project-root-dir/node_modules/@react-native-community/cli/build/commands/runIOS/runIOS.js:181:45)
在这些错误之前,该命令会打印成功构建的信息,并且表明它正在安装构建:
信息 ** BUILD SUCCEEDED ** 信息 安装 DerivedData/Build/Products/Debug-iphonesimulator/MyAppName.app 因此,似乎构建是成功的,但当它尝试安装应用程序时失败了?
我认为我已经尝试了其他类似错误消息的问题所提供的所有内容,但对我来说都没有起作用。
一些规格:
react-native:0.59.10 react:16.8.3 xcode-version:版本12.2(12B45b)

我知道stackoverflow上有类似的问题。但是由于那里提供的解决方案都不适用于我,并且我希望能够解决这个问题,所以我提出了这个单独的问题。

我不知道它试图查找的Info.plist文件在哪里:DerivedData/Build/Products/Debug-iphonesimulator/MyAppName.app/Info.plist

在我的ios文件夹中,有一个名为DerivedData的文件夹,但是里面没有名为Build的文件夹。所以我认为它可能正在从错误的位置查找?

更新:

我已经能够确定cli启动失败的位置: https://github.com/react-native-community/cli/blob/ba298d9c47af522f0377325bebc6c2075d41790a/packages/platform-ios/src/commands/runIOS/index.ts#L378

如果我更改那一行let buildPath = build/${scheme}/Build/Products/${configuration}-${device}/${appName}.app

build/${scheme}/Build/Products/${configuration}-${device}/MyAppRealName.app 转换为:

然后开发启动工作正常,没有问题。因此似乎获取应用程序名称出现了问题。应用程序名称在此处解析:https://github.com/react-native-community/cli/blob/ba298d9c47af522f0377325bebc6c2075d41790a/packages/platform-ios/src/commands/runIOS/index.ts#L387

const productNameMatch = /export FULL_PRODUCT_NAME="?(.+).app"?$/m.exec(buildOutput);

我可以编写一个安装后的npm脚本来正确设置应用程序的名称,然后就大功告成了。但这是相当不正规的方法。我想知道是否有更好的替代方案?我注意到runIOS文件已经更新了很多,但getProductName函数仍然保持不变。所以我不确定仅更新cli是否会起作用,甚至是否可能,因为它可能需要更高版本的react-native,而这对我现在来说不是一个选择。
2个回答

10

@react-native-community/cli 的新版本在旧版本的 react-native 上无法正常工作,因为在新版本中它们将 getProductName 更改为 getPlatformName。如需更多详细信息,请阅读此PR摘要。

解决方法

作为本地解决方法,通过patch-package修补软件包 node_modules/@react-native-community/cli-platform-ios/build/commands/runIOS/index.js 并编辑 getProductName(第 362-365 行)以更改内容:

 function getProductName(buildOutput) {
   const productNameMatch = /export FULL_PRODUCT_NAME\\?="?(.+).app"?$/m.exec(buildOutput);
   return productNameMatch ? productNameMatch[1].replace(/(?:\\(.))/g, '$1') : null;
 }

很遗憾,我目前无法升级我的React-Native。但是,如果兼容较早版本的React-Native,我可能只能升级cli。我应该升级到哪个版本的React-Native-Community/cli最低版本? - Ville Miekk-oja
是的,但是这个命令:react-native upgrade会升级整个React Native吗? - Ville Miekk-oja
是的,您必须更新React Native或从此拉取请求中打补丁React Native。https://github.com/react-native-community/cli/commit/6526bdd834993267f6f3fed2f8521bf1a9b7b859 - Muhammad Numan
@VilleMiekk-oja,你可以直接将这6个文件更改为node_module https://github.com/react-native-community/cli/commit/6526bdd834993267f6f3fed2f8521bf1a9b7b859,并测试是否有效,然后你可以使用https://www.npmjs.com/package/patch-package。 - Muhammad Numan
我认为这是一个不完整的解决方案。我的项目根本没有使用@react-native-community/cli。我使用npx从CLI运行RN命令。尽管如此,当执行到将应用程序安装在模拟器上的时候,我仍然遇到了同样的问题。 - Mike S.
显示剩余3条评论

0

react-native run-ios 的结果是:DerivedData/Build/Products/Debug-iphonesimulator/MyAppName.app/Info.plist

正确的应该是:DerivedData/Build/Products/Debug-iphonesimulator/MyAppRealName.app/Info.plist

然后你可以通过编辑 Xcode 项目来修复它:

  1. 打开产品菜单(状态栏)
  2. Scheme -> Edit Scheme
  3. 在构建部分下,添加一个后置操作
  4. 在提供构建设置中选择您的应用程序的目标
  5. 使用脚本将 wrongname.app 复制到 realname.appcp ${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app ${BUILT_PRODUCTS_DIR}/real_name.app

或者您可以使用符号链接而不是复制。

enter image description here


如果你只运行react-native run-ios,我认为xcode的post action根本没有运行。所以这种方式感觉有点hacky,而且我必须始终从xcode运行应用程序。我更喜欢一些既不是hacky的,又可以进行版本控制的解决方案。 - Ville Miekk-oja
你试过了吗?即使从React Native的脚本触发构建步骤,它也应该被执行。 - nghiahoang
我仍然想知道是哪个错误的应用程序名称?这与正确的应用程序名称有关吗?你的项目是否包含任何应用程序扩展,例如NotificationService扩展、Share扩展等? - nghiahoang
错误的应用程序名称来自于此:const appName = await buildProject(xcodeProject, selectedSimulator.udid, scheme, args.configuration, args.packager, args.verbose, args.port);该函数有第254行:resolve(getProductName(buildOutput) || scheme);它无法使用getProductName函数找到产品名称,因此默认为变量scheme。而scheme变量值是错误的,不是应用程序的名称。因此,脚本将无法找到Info.plist文件,因为路径具有错误的应用程序名称。 - Ville Miekk-oja
在Xcode 13.2.1中,我的info.plist路径是../DerivedData/app-name/info.plist../Build/Products/Debug-iphonesimulator文件夹中没有info.plist。 - Mike S.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接