Error: Cannot read property 'replace' of undefined when building iOS Cordova

Error: Cannot read property 'replace' of undefined when building iOS Cordova

我使用 cordova create project hello com.hello Hello 创建了一个 cordova 项目。

并使用 cordova platform add iOS 添加了 iOS 平台。 并尝试在 cordova build ios.

之后执行 cordova run ios

但它向我显示了这个错误(我使用 --d/ --verbose 来获取详细信息)。

/usr/bin/codesign --force --sign - --timestamp=none /Volumes/Untitled/Plot/PlotReel/platforms/ios/build/emulator/PlotReel.app /Volumes/Untitled/Plot/PlotReel/platforms/ios/build/emulator/PlotReel.app: replacing existing signature

** BUILD SUCCEEDED **

No scripts found for hook "before_deploy". Error: TypeError: Cannot read property 'replace' of undefined

at remove (/Volumes/Untitled/Plot/test/platforms/ios/cordova/node_modules/ios-sim/src/lib.js:282:70)
at Array.forEach (native)
at Object.getdevicetypes (/Volumes/Untitled/Plot/test/platforms/ios/cordova/node_modules/ios-sim/src/lib.js:292:22)
at Object.listEmulatorImages [as run] (/Volumes/Untitled/Plot/test/platforms/ios/cordova/lib/list-emulator-images:34:29)
at deployToSim (/Volumes/Untitled/Plot/test/platforms/ios/cordova/lib/run.js:146:50)
at /Volumes/Untitled/Plot/test/platforms/ios/cordova/lib/run.js:88:20
at _fulfilled (/Volumes/Untitled/Plot/test/platforms/ios/cordova/node_modules/q/q.js:834:54)
at self.promiseDispatch.done (/Volumes/Untitled/Plot/test/platforms/ios/cordova/node_modules/q/q.js:863:30)
at Promise.promise.promiseDispatch (/Volumes/Untitled/Plot/test/platforms/ios/cordova/node_modules/q/q.js:796:13)
at /Volumes/Untitled/Plot/test/platforms/ios/cordova/node_modules/q/q.js:604:44

我已经尝试卸载并重新安装cordova,但问题仍然存在。

请帮帮我。

我有同样的错误。对我来说,我将其追溯到 platforms/ios/cordova/node_modules/ios-sim/src/lib.js

中的一个错误
getdevicetypes: function(args) {
...
    list.devicetypes.forEach(function(device) {
        name_id_map[ filterDeviceName(device.name) ] = device.id;
    });

    list = [];
    var remove = function(runtime) {
        // remove "iOS" prefix in runtime, remove prefix "com.apple.CoreSimulator.SimDeviceType." in id
        list.push(util.format('%s, %s', name_id_map[ deviceName ].replace(/^com.apple.CoreSimulator.SimDeviceType./, ''), runtime.replace(/^iOS /, '')));
    };

错误总是出现在 "TypeError: Cannot read property 'replace' of undefined" in lib.js:289

list.push(util.format('%s, %s', name_id_map[ deviceName ].replace(/^com.apple.CoreSimulator.SimDeviceType./, ''), runtime.replace(/^iOS /, '')));

所以我插入了一些调试代码:

    list.devicetypes.forEach(function(device) {
        console.log('test 1 ' + device.name);
        console.log('test 2 ' + filterDeviceName(device.name));
        name_id_map[ filterDeviceName(device.name) ] = device.id;
    });

这对我有用。祝你好运。

    list = [];
    var remove = function(runtime) {
        // remove "iOS" prefix in runtime, remove prefix "com.apple.CoreSimulator.SimDeviceType." in id
        console.log('remove 1 ' + runtime);
        console.log('remove 2 ' + deviceName);
        console.log('remove 3 ' + name_id_map[ deviceName ]);
        list.push(util.format('%s, %s', name_id_map[ deviceName ].replace(/^com.apple.CoreSimulator.SimDeviceType./, ''), runtime.replace(/^iOS /, '')));
    };

并得到以下输出:

test 1 iPhone 5
test 2 iPhone 5
test 1 iPad Pro (9.7-inch)
test 2 iPad Pro (9.7 inch)
remove 1 iOS 10.2
remove 2 iPhone 5
remove 3 com.apple.CoreSimulator.SimDeviceType.iPhone-5
remove 1 iOS 10.2
remove 2 iPad Pro (9.7-inch)
remove 3 undefined

注意 filterDeviceName 如何在填充散列时删除减号。再次检索该值时,不会应用筛选器,程序会失败。

错误修复:在写入和读取哈希时应用过滤器。

 list.push(util.format('%s, %s', name_id_map[ filterDeviceName(deviceName) ].replace(/^com.apple.CoreSimulator.SimDeviceType./, ''), runtime.replace(/^iOS /, '')));

新解

此问题已在最新版本的 "ios-sim" 软件包中得到解决(因此现在这可能是更简单的解决方案 - 与下面列出的旧解决方案相比)。为了将 "ios-sim" 包更新到最新版本 运行 这在你的 terminal/cmd:

cd platforms/ios/cordova/node_modules/
sudo npm install -g ios-sim@latest

旧解

问题是 name_id_map[deviceName] returns undefined for "iPad Pro (12.9-inch)" and “iPad 专业版(10.5 英寸)”。

你可以用console.log('name_id_map[ deviceName ]: ' + name_id_map[ deviceName ]);检查一下。

我通过添加一个 if 语句修复了这个错误,该语句检查设备是否在“platforms/ios/cordova/node_modules/ios-sim/src/lib.js:282”中定义。

我替换了这个:

list = [];
        var remove = function(runtime) {
            // remove "iOS" prefix in runtime, remove prefix "com.apple.CoreSimulator.SimDeviceType." in id
            list.push(util.format('%s, %s', name_id_map[ deviceName ].replace(/^com.apple.CoreSimulator.SimDeviceType./, ''), runtime.replace(/^iOS /, '')));
        };

有了这个:

list = [];
        var remove = function(runtime) {
            // remove "iOS" prefix in runtime, remove prefix "com.apple.CoreSimulator.SimDeviceType." in id
            if (name_id_map[deviceName] && runtime) {
                list.push(util.format('%s, %s', name_id_map[deviceName].replace(/^com.apple.CoreSimulator.SimDeviceType./, ''), runtime.replace(/^iOS /, '')));
            }
        };

"iPad Pro (10.5-inch)" 模拟器不会出现在列表中(但它可能无论如何都不能工作 - 没有检查)。

关于 github 的错误报告:https://github.com/phonegap/ios-sim/issues/210

Github 上有一个 PR 解决了我的问题: https://github.com/phonegap/ios-sim/pull/213

刚刚在我的项目根目录中调用了以下内容

nano platforms/ios/cordova/node_modules/ios-sim/src/lib.js

并添加了过滤设备名称的功能,如下所示: https://github.com/phonegap/ios-sim/pull/213/files

在您的项目文件夹根目录中,执行 cd platforms/ios/cordova && npm install ios-sim

我最近升级到 xcode 8.3.3 and ionic 3.4.0

我已经从 myApp/platforms/ios/cordova/node_modules 中删除了 ios-sim 目录,现在可以使用了。

另一种选择是使用 cordova-ios 版本并已实施 ios-sim 补丁

cordova platform add https://github.com/apache/cordova-ios.git#4.4.0-ios-sim

请注意,这不是 Apache Cordova 的正式版本,它将包含在下一个 4.4.1 版本中。

我有 运行 以下命令,它解决了我的问题:

cd project_dir

sudo npm install ios-sim@latest

我刚刚 运行 加入了这个,我想我应该添加一些对我有用的东西 - 解决方案 npm install ios-sim 没有。

我所做的只是打开 XCode,它指向 Generic iOS Device 从我上次使用它来测试应用程序时物理设备。我刚刚将 iOS 模拟器更改为 iOS 模拟器列表中的任何内容,重试后效果非常好!

希望这对处于相同情况的其他人有所帮助。

npm install ios-sim@latest 更新 ios-sim 版本对我没有用。但是,如果在 Github.

上找到了一个简单易行的解决方案
  1. 打开/platforms/ios/cordova/node_modules/ios-sim/src/lib.js
  2. 使用代码编辑器搜索 deviceName
  3. name_id_map[ deviceName ]替换为name_id_map[filterDeviceName(deviceName)]

您可以找到 Github post here