iOS上的Cordova 2.2.0 - RequireJS无法正确加载Cordova

Gan*_*esh 10 requirejs phonegap-plugins cordova ios6

我目前正在使用Cordova(Phonegap),Backbone和JQtouch开发webapp.除此之外,我需要在用户日历中添加事件.

在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);
Run Code Online (Sandbox Code Playgroud)

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

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

这个问题的一个可能来源可能是我从Cordova 2.0.0升级到Cordova 2.2.0的方式:我只是按照教程" 将Cordova 2.1.0项目升级到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,并从头开始重做所有内容:

  • 我从他们的网站上安装了Cordova 2.1.0 .
  • 我将xcode升级到4.5.2(推荐)
  • 我创建了一个xcode项目,我在其中复制了部分代码.
  • 我按照他们的教程从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中,我有以下几行:( 我从这里得到它们)

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;
});
Run Code Online (Sandbox Code Playgroud)

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

var exec = require('cordova/exec');
Run Code Online (Sandbox Code Playgroud)

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

var mycalendarplugin = cordova.require("cordova/plugin/calendarplugin");
Run Code Online (Sandbox Code Playgroud)

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

window.mycalendarplugin.createEvent('<%= paramEvent_map %>', 'Geneva', 
'Convocation', '<%= paramEvent_startDate %>', '<%= paramEvent_endDate %>');
Run Code Online (Sandbox Code Playgroud)

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

但是,我收到以下消息:" 错误:尝试在'deviceready'之前调用cordova.exec().忽略. "这应该在"deviceReady"未触发时出现.

可悲的是,这个事件永远不会发生.所以现在我的问题略有不同,但仍然存在.

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

我添加了几行来收听Android和iOS中的事件:

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

在iOS上,我收到消息"load triggered"但没有"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,它仍然会使用它.

我会告诉你最新的:)

Gan*_*esh 8

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

这是我在上一次编辑中的想法:RequireJS正在搞乱Cordova 2.2.0!

之前,我使用此代码加载cordova:

require.config({
  paths: {
    cordova: 'libs/cordova/cordova-2.2.0', ...
Run Code Online (Sandbox Code Playgroud)

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

define([
  'jquery',
  'cordova',
  ...
], function($) { ... }
Run Code Online (Sandbox Code Playgroud)

在我的index.html中,我有:

<script data-main="js/main" src="js/libs/require/require-jquery.js"></script>
Run Code Online (Sandbox Code Playgroud)

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

解决我的问题:

我在之前的几行中摆脱了关于cordova的一切.

  • 在require.config中没有更多的cordova.
  • 我的js函数的define部分中没有更多的cordova.

相反,我在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>
Run Code Online (Sandbox Code Playgroud)

一切正常!我可以再次拨打cordova.exec()!(在iOS 4,iOS 6和iPhone 5上测试过).

说实话,我不太清楚这一切是如何运作的.我只是假设cordova需要在其他所有东西之前加载(比如jquery),而且RequireJS不擅长这样做(或者我不知道如何使用它).

通过这个很可怕.我很高兴它结束了:)

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


asg*_*oth 8

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

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

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

/*global define */

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

   return cordova.require('cordova/exec');
});
Run Code Online (Sandbox Code Playgroud)

现在可以轻松创建自定义插件:

/*global define */

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

   return function showToast(callback, message) {
      cordovaExec(callback, function (error) {}, "Toaster", "show", [message]);
   };
});
Run Code Online (Sandbox Code Playgroud)

您只能在一个模块中执行此操作:

/*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]);
   };
});
Run Code Online (Sandbox Code Playgroud)

希望有帮助:)