【问题标题】:Cordova 2.2.0 on iOS - RequireJS won't load Cordova correctlyiOS 上的 Cordova 2.2.0 - RequireJS 不会正确加载 Cordova
【发布时间】:2012-11-05 13:40:40
【问题描述】:

我目前正在使用 Cordova (Phonegap)、Backbone 和 JQtouch 开发一个 web 应用程序。 除其他外,我需要在用户日历中添加事件。

在 Android 上一切正常。我仍在使用 Cordova 2.0.0。 (我没有升级到最新版本)。滚动有效,导航正常,我可以在我的日历中添加事件!

在 iPhone 上,情况有所不同。由于我希望我的应用程序在 iOS 6 上运行,我在我的 Mac 上安装了 Cordova 2.2.0。从那以后,我不能再在日历中添加事件了。 它与cordova 2.0.0一起工作(在iphone上),但现在不行。

经过调查,发现cordova.exec()是未定义的

我搜索了很多关于这个问题的信息,但似乎除了我之外没有人遇到过这个问题。

以下是适用于 Cordova 2.0.0 但不适用于 Cordova 2.2.0 的代码示例:

calendar.js,Cordova 的日历插件。我没有写。在 Android 上,我收到消息“cordova.exec 已定义”,而在 iOS 上,我收到另一个消息。

// Cordova Calendar Plugin
// Author: Felix Montanez 
// Created: 01-17-2012
// Contributors:
// Michael Brooks    

function calendarPlugin()
{
}

calendarPlugin.prototype.createEvent = function(title,location,notes,startDate,endDate)
{
    if('function' == typeof(cordova.exec)) {
        alert("cordova.exec is defined");
    } else {
        alert("cordova.exec is not defined");
    }
    cordova.exec(null,null,"calendarPlugin","createEvent", [title,location,notes,startDate,endDate]);
};

calendarPlugin.install = function()
{
    if(!window.plugins)
    {
        window.plugins = {};
    }    
    window.plugins.calendarPlugin = new calendarPlugin();
    return window.plugins.calendarPlugin;
};

cordova.addConstructor(calendarPlugin.install);

调用函数 createEvent 的代码(它正在工作,因为我收到了上一个警报)

if (confirm('Do you want to add this event in your calendar?')) 
{ 
    calendarPlugin.prototype.createEvent('<%= paramEvent_map %>', 'Geneva', 
        'Convocation', '<%= paramEvent_startDate %>', '<%= paramEvent_endDate %>'); 
}

这个问题的一个可能来源可能是我从 Cordova 2.0.0 升级到 Cordova 2.2.0 的方式:我只是按照教程“Upgrading Cordova 2.1.0 projects to 2.2.0”进行操作。我应该先“从 2.0.0 到 2.1.0”然后“从 2.1.0 到 2.2.0”吗?

如果有任何建议,我将不胜感激,因为我真的不想重新安装 phonegap。

在 Mac 上,我正在使用 Mountain Lion 10.8 和 xCode 4.5,我正在 iOS 4 和 6 上测试我的应用程序。 在 PC 上,我正在使用 Aptana studio 3 和 Eclipse 3.7.1,我正在 Android 2.3 上进行测试。

--- 编辑:重新安装 Cordova 2.1.0 然后升级到 2.2.0 ---

我刚刚删除了我的项目,卸载了 Cordova,然后“从头开始”重做一切:

  • 我从 their website 安装了 Cordova 2.1.0。
  • 我将 xcode 升级到 4.5.2(按照推荐)
  • 我创建了一个 xcode 项目,在其中复制了部分代码。
  • 我关注 their tutorial 从 Cordova 2.1.0 升级到 Cordova 2.2.0
  • 我将“架构”设置为“armv7, armv7s”,将“仅构建活动架构”设置为“是”
  • 我添加了日历插件所需的框架:EventKit 和 EventKitUI

然后我在我的 iPhone 3(iOS 6)上编译并启动我的项目,cordova.exec 仍然没有定义

--- 编辑:将我的日历插件声明为模块 ---

我直接在cordova-2.2.0.js中添加了一些日历插件的代码(我绝望了)。

现在在 cordova-2.2.0.js 中,我有以下几行:(I got them from here)

define("cordova/plugin/calendarplugin", function(require, exports, module) {
    var exec = require('cordova/exec');

    var calendarPlugin = function() {};

    calendarPlugin.prototype.createEvent = function(title,location,notes,startDate,endDate) {
         exec(null, null, 'calendarPlugin', 'createEvent', [title,location,notes,startDate,endDate]);
    }

    var myCalendarPlugin = new calendarPlugin();
    module.exports = myCalendarPlugin;
});

所以我不再使用 cordova.exec() 了,而是这个:

var exec = require('cordova/exec');

我的日历“插件”文件现在只包含以下行:

var mycalendarplugin = cordova.require("cordova/plugin/calendarplugin");

这就是我使用新“模块”的方式:

window.mycalendarplugin.createEvent('<%= paramEvent_map %>', 'Geneva', 
'Convocation', '<%= paramEvent_startDate %>', '<%= paramEvent_endDate %>');

而且,令人惊讶的是,函数 exec() 被调用了!

但是,我收到以下消息:“ERROR: Attempting to call cordova.exec() before 'deviceready'. Ignoring.”当“deviceReady”没有触发时应该出现。 p>

遗憾的是,此事件 NEVER 触发。所以我的问题现在略有不同,但仍然存在。

--- 编辑:与 Android 的比较 ---

我在 Android 和 iOS 中添加了几行来监听事件:

window.addEventListener('load', function () {
     alert("load triggered");
     document.addEventListener('deviceready', function () {
            alert("PhoneGap is now loaded!");
     }, false);
}, false);

在 iOS 上,我收到“加载已触发”消息,但没有收到“PhoneGap 现已加载”的消息。之后,我仍然无法使用 exec()。

在 Android 上,我根本没有收到任何消息。但是我可以毫无问题地使用cordova.exec()。

--- 编辑:从头开始重做项目 ---

我没有使用cordova 2.1.0 创建我的项目然后升级到cordova 2.2.0,而是尝试直接使用cordova 2.2.0 创建一个示例项目,然后在其中包含日历插件(原始版本)。

而且效果很好!使用 iOS 6 的更多代码(需要用户明确授权),我可以在我的日历中添加事件。

但是,一旦我添加了项目的其余部分(html、css、js 文件),我就会收到同样的错误:cordova.exec 未定义。

责任者可能是RequireJS,它可能以不同的方式加载cordova-2.2.0.js。它适用于cordova 2.0.0,但似乎不适用于2.2.0。

我会尝试看看是否可以在 RequireJS 之前加载 cordova-2.2.0.js,并且在加载 cordova 后仍然使用它。

我会及时通知你:)

【问题讨论】:

  • 你在plist文件中包含插件了吗?
  • 你必须先从 2.0 迁移到 2.1
  • JPK:是的,插件包含在 plist 文件中,它在我切换到 cordova 2.2.0 之前就可以使用。
  • Christian Kuetbach:谢谢,我今天就试试。
  • Christian Kuetbach:从我帖子的编辑部分可以看出,重做 2.1.0 安装然后正确升级到 2.2.0 并没有改变我的问题:(

标签: cordova ios6 requirejs phonegap-plugins


【解决方案1】:

很抱歉回答我自己的问题。

这是我在上次编辑中的想法:RequireJS 正在与 Cordova 2.2.0 混淆

之前,我使用这段代码来加载cordova:

require.config({
  paths: {
    cordova: 'libs/cordova/cordova-2.2.0', ...

在我的任何使用cordova的脚本之前,我在写:

define([
  'jquery',
  'cordova',
  ...
], function($) { ... }

在我的 index.html 中,我有:

<script data-main="js/main" src="js/libs/require/require-jquery.js"></script>

它与cordova 2.0.0 配合得很好!但是使用cordova 2.2.0,这是错误的

解决我的问题:

我在前面几行中删除了关于cordova的所有内容。

  • require.config 中不再有cordova。
  • 定义部分不再有cordova 我的 js 函数。

相反,我只在 index.html 中添加了一行:

<script type="text/javascript" src="libs/cordova/cordova-2.2.0.js"></script>
<script data-main="js/main" src="js/libs/require/require-jquery.js"></script>

一切正常!我可以再次调用cordova.exec()! (在 iOS 4、iOS 6 和 iPhone 5 上测试)

说实话,我不太了解这一切是如何运作的。我只是假设需要先加载cordova(比如jquery),而RequireJS不擅长这样做(或者我不知道如何使用它)。

经历这一切真是太糟糕了。我很高兴一切都结束了:)

无论如何,我希望这对某人有用。

【讨论】:

  • 我使用的是 Cordova 2.0.0rc1。日历插件工作正常。现在我在 Cordova 2.2.0 中使用相同的 iOS 类、index.html 和 Javascript 文件。你能把你的javascript和html代码贴在这里吗?我没有任何 requireJS,但 cordova.exec 没有调用我的原生函数。
  • 我的 javascript 和 html 代码有点庞大。另外,我认为您的问题可能出在其他地方。您是否检查过您的插件密钥是否出现在您的 plist 文件中?当您选择cordova 2.2.0 时,您是否按照所有步骤升级您的xcode 项目?
【解决方案2】:

在您的 require.config 对象中,您需要通过 shim 属性导出 cordova

require.config({
   baseUrl: 'js',
   paths: {
      cordova: '../lib/cordova/cordova-2.2.0'
   },
   shim: {
      cordova: {
         exports: 'cordova'
      }
   }
});

最好定义一个模块来访问cordova的exec模块

/*global define */

define(['cordova'], function (cordova) {
   'use strict';

   return cordova.require('cordova/exec');
});

现在创建自定义插件很容易:

/*global define */

define(['plugins/cordovaExec'], function (cordovaExec) {
   'use strict';

   return function showToast(callback, message) {
      cordovaExec(callback, function (error) {}, "Toaster", "show", [message]);
   };
});

您只能在一个模块中完成:

/*global define */

define(['cordova'], function (cordova) {
   'use strict';

   var exec = cordova.require('cordova/exec');

   return function showToast(callback, message) {
      exec(callback, function (error) {}, "Toaster", "show", [message]);
   };
});

希望有帮助:)

【讨论】:

    【解决方案3】:

    更新到 Cordova-2.4.0,您可以使用 RequireJS 延迟加载它 - 正如他们博客上的发布说明中提到的那样:http://shazronatadobe.wordpress.com/2013/02/08/whats-new-in-cordova-ios-2-4-0/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-16
      • 2021-03-05
      • 1970-01-01
      相关资源
      最近更新 更多