当前位置:   article > 正文

react native (Error: Unable To Find Utility “Instruments“, Not A Developer Tool)_unable to find utilty

unable to find utilty

问题原因

在使用 yarn ios --device 'xxx的iPhone' 或者 react-native run-ios --device 'xxx的iPhone' 时,出现 (Error: Unable To Find Utility "Instruments", Not A Developer Tool) 等等关键字信息的错误提示,

正如错误提示的,因为没有 Instruments 这个工具了,在xcode12的版本,Instruments已经被废弃,但是老版本的React Native库里使用的还是 Instruments 这个命令用于查找当前电脑可用设备

所以这是RN的版本和XCode的版本不兼容了,但是此时又不想升级RN的版本,担心或者已经遇到很多兼容性的问题,那么可以通过修改 @react-native-community 包中代码,修改使用这个命令的地方,换成新版本的查找设备的命令即可。

修改1: node_modules/@react-native-community/cli-platform-ios/build/commands/runIOS/index.js

在这个js中,我们找到名为runIOS的方法,

然后我们可以找到如下这么一行关键代码:

  1. const devices = (0, _parseIOSDevicesList.default)(_child_process().default.execFileSync('xcrun', ['instruments', '-s'], {
  2. encoding: 'utf8'
  3. }));
  4. 复制代码

也就是说,在低版本的RN里,查找设备列表是用的 xcrun instruments -s,我们直接在命令行输入这行看看会出现什么:

即出现了RN命令运行时的错误,也就是说当前的系统已经不支持这个命令了(笔者此时的XCode是14版本),

那我们看一下高版本的RN,可以正常运行的,它的库中使用的查找设备列表的命令代码是什么:

同样的路径同样的方法,我们可以看到查找设备列表的命令已经变成了:xcrun xctrace list devices

然后在控制执行该命令发现可以列出当前设备列表。

也就是说,RN其实只是用JS代表帮我们调用XCode提供的命令,找到了这个问题我们对低版本的RN代码进行微调即可,此时我们现将查找设备的命令更改成可以正常运行的,

也就是说我们将,

  1. const devices = (0, _parseIOSDevicesList.default)(_child_process().default.execFileSync('xcrun', ['instruments', '-s'], {
  2. encoding: 'utf8'
  3. }));
  4. 复制代码

改为

  1. const devices = (0, _parseIOSDevicesList.default)(_child_process().default.execFileSync('xcrun', ['xctrace', 'list', 'devices'], {
  2. encoding: 'utf8'
  3. }));
  4. 复制代码

是不是就可以了,笔者试了一下这么直接用不行,在新版本的代码中使用了 execa 这个库执行命令:

  1. const out = execa.sync('xcrun', ['xctrace', 'list', 'devices']);
  2. 复制代码

因此我们需要在老版本的代码中引入 execa 去执行命令:

我们参考 _child_process 的定义,再定义一个 _execa,然后使用 _execa 执行命令:

  1. const devices = (0, _parseIOSDevicesList.default)(_execa().default.sync('xcrun', ['xctrace', 'list', 'devices']));
  2. 复制代码

到了这一步,查找设备的命令可以正常执行了,但是还有一个问题,就是对设备列表的结果解析,笔者试了一下直接用老版本的解析代码,也就是 _parseIOSDevicesList.default 对新版本命令的结果输出是不行的,因此还需要修改一下 _parseIOSDevicesList 方法,如何修改看下一步。

修改2: node_modules/@react-native-community/cli-platform-ios/build/commands/runIOS/parseIOSDevicesList.js

这一步的修改比较简单,主要是将正则表达式换一下就可以了:

(老版本的代码):

(改过后的代码):

  1. function parseIOSDevicesList(text) {
  2. const devices = [];
  3. text.stdout.split('\n').forEach(line => {
  4. const device = line.match(
  5. /(.*?) ((([0-9.]+)) )?(([0-9A-F-]+))( (Simulator))?/i,
  6. )
  7. if (device) {
  8. const [, name,, version, udid, isSimulator] = device;
  9. const metadata = {
  10. name,
  11. udid
  12. };
  13. if (version) {
  14. metadata.version = version;
  15. metadata.type = isSimulator ? 'simulator' : 'device';
  16. } else {
  17. metadata.type = 'catalyst';
  18. }
  19. devices.push(metadata);
  20. }
  21. });
  22. return devices;
  23. }
  24. 复制代码

收工

最后就可以直接通过 yarn ios --device 'xxx的iPhone' 或者 react-native run-ios --device 'xxx的iPhone' 直接运行了,如果提示找不到设备就多运行几次,因为新命令不知道是因为我的硬件问题还是怎么回事,一会输出有我的iphone一会没有,所以提示找不到就在xcode中判断是不是连上了,如果连上了,就多试几次命令就可以了。

两个文件的完整代码我上传到了github上:github.com/qiaomengnan…

感谢这两篇文章给的提示:

gankrin.org/how-to-fix-…

github.com/react-nativ…

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/382916
推荐阅读
相关标签
  

闽ICP备14008679号