我目前正在使用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);
调用函数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,并从头开始重做所有内容:
然后我在我的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()被调用了!
但是,我收到以下消息:“错误:尝试在'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);
在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,它仍会使用它。
我会让你及时了解:)
答案 0 :(得分:8)
很抱歉回答我自己的问题。
这是我在上次编辑中的想法: 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的一切。
相反,我在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不擅长这样做(或者我不知道如何使用它)。
经历这很可怕。我很高兴它结束了:)
无论如何,我希望这对某人有用。
答案 1 :(得分:8)
在 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]);
};
});
希望有所帮助:)
答案 2 :(得分:2)
更新到Cordova-2.4.0,您可以使用RequireJS对其进行延迟加载 - 正如他们在博客上提到的发布说明:http://shazronatadobe.wordpress.com/2013/02/08/whats-new-in-cordova-ios-2-4-0/