title: Cordova 2.2.0 on iOS - RequireJS won't load Cordova correctly
body: <p>I'm currently developing a webapp using Cordova (Phonegap), Backbone and JQtouch.
  Among other things, I need to add events in the user calendar.</p>
  
  <p>Everything works fine on Android. I'm still using Cordova 2.0.0. (I didn't upgrade to the latest version). The scrolling works, navigation is OK, and I can add events in my calendar!</p>
  
  <p>On iPhone, it is different. As I want my app to work on iOS 6, I got Cordova 2.2.0 on my Mac. Since then, I can't add events in the calendar anymore.
  It worked (on iphone) with cordova 2.0.0, but not now.</p>
  
  <p>After investigation, I found out that <strong>cordova.exec() is undefined</strong>.</p>
  
  <p>I searched a lot about this issue but it seems nobody, except me, met that problem for now.</p>
  
  <p>Here are samples of code that are working with Cordova 2.0.0 but not with Cordova 2.2.0:</p>
  
  <p>calendar.js, a calendar plug-in for Cordova. I did not write it. On Android I get the message "cordova.exec is defined" while on iOS I get the other one.</p>
  
  <pre><code>// 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);
  </code></pre>
  
  <p>The code which call the function createEvent (it's working, as I got the previous alert)</p>
  
  <pre><code>if (confirm('Do you want to add this event in your calendar?')) 
  { 
      calendarPlugin.prototype.createEvent('&lt;%= paramEvent_map %&gt;', 'Geneva', 
          'Convocation', '&lt;%= paramEvent_startDate %&gt;', '&lt;%= paramEvent_endDate %&gt;'); 
  }
  </code></pre>
  
  <p>A possible source of this problem may be the way I upgraded from Cordova 2.0.0 to Cordova 2.2.0: I just followed the tutorial "<a href="http://docs.phonegap.com/en/2.2.0/guide_upgrading_ios_index.md.html">Upgrading Cordova 2.1.0 projects to 2.2.0</a>". Should I have done "From 2.0.0 to 2.1.0" then "Form 2.1.0 to 2.2.0"?</p>
  
  <p>I'd appreciate any suggestion about this, as I really don't want to restart my installation of phonegap.</p>
  
  <p><em>On Mac, I'm working with Mountain Lion 10.8 and xCode 4.5, and I'm testing my app on iOS 4 and 6.
  On PC, I'm working with Aptana studio 3 and Eclipse 3.7.1, and I'm testing on Android 2.3.</em></p>
  
  <p>--- <strong>EDIT: Reinstall Cordova 2.1.0 then upgrade to 2.2.0</strong> ---</p>
  
  <p>I just erased my project, uninstall Cordova, and redo everything "from scratch":</p>
  
  <ul>
  <li>I installed Cordova 2.1.0 from <a href="http://incubator.apache.org/cordova/">their website</a>.</li>
  <li>I upgraded xcode to 4.5.2 (as recommended)</li>
  <li>I created a xcode project in which I copied parts of my code.</li>
  <li>I followed <a href="http://docs.phonegap.com/en/2.2.0/guide_upgrading_ios_index.md.html">their tutorial</a> to upgrade from Cordova 2.1.0 to Cordova 2.2.0</li>
  <li>I set "Architectures" to "armv7, armv7s" and "Build Active Architecture Only" to "Yes"</li>
  <li>I added the frameworks I needed for the calendar plug-in: EventKit and EventKitUI</li>
  </ul>
  
  <p>Then I compiled and launch my project on my iPhone 3 (with iOS 6), and <strong>cordova.exec is still not defined</strong>!</p>
  
  <p>--- <strong>EDIT: Declare my calendar plugin as a module</strong> ---</p>
  
  <p>I added some code for the calendar plug-in directly in cordova-2.2.0.js (I'm desperate).</p>
  
  <p>Now in cordova-2.2.0.js, I have the following lines: (<a href="https://github.com/phonegap/phonegap-plugins/wiki/Defining-Your-Cordova-Plugin-As-A-Cordova-Module">I got them from here</a>)</p>
  
  <pre><code>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;
  });
  </code></pre>
  
  <p>So I don't use cordova.exec() anymore, but this instead:</p>
  
  <pre><code>var exec = require('cordova/exec');
  </code></pre>
  
  <p>My calendar "plug-in" file now just contains the following line:</p>
  
  <pre><code>var mycalendarplugin = cordova.require("cordova/plugin/calendarplugin");
  </code></pre>
  
  <p>And this is how I'm using my new "module":</p>
  
  <pre><code>window.mycalendarplugin.createEvent('&lt;%= paramEvent_map %&gt;', 'Geneva', 
  'Convocation', '&lt;%= paramEvent_startDate %&gt;', '&lt;%= paramEvent_endDate %&gt;');
  </code></pre>
  
  <p>And, surprisingly, the function exec() is called!</p>
  
  <p>However, I got the following message: "<strong>ERROR: Attempting to call cordova.exec() before 'deviceready'. Ignoring.</strong>" which should appears when "deviceReady" has not fired.</p>
  
  <p>Sadly, this event <strong>NEVER</strong> fires. So my problem is slightly different now, but still remains.</p>
  
  <p>--- <strong>EDIT: Comparison with Android</strong> ---</p>
  
  <p>I added a few lines to listen to events, both in Android and iOS:</p>
  
  <pre><code>window.addEventListener('load', function () {
       alert("load triggered");
       document.addEventListener('deviceready', function () {
              alert("PhoneGap is now loaded!");
       }, false);
  }, false);
  </code></pre>
  
  <p>On iOS, I get the message "load triggered" but not "PhoneGap is now loaded". After that, I still can't use exec().</p>
  
  <p>On Android, I get no message at all. But I can use cordova.exec() with no problem.</p>
  
  <p>--- <strong>EDIT: Redo the project from scratch</strong> ---</p>
  
  <p>Instead of creating my project with cordova 2.1.0 then upgrading to cordova 2.2.0, I tried to create a sample project directly with cordova 2.2.0 then include the calendar plug-in (original version) in it.</p>
  
  <p>And it works perfectly fine! With a little more code for iOS 6 (which needs an explicit autorisation from the user), I can add events in my calendar.</p>
  
  <p>However, as soon as I add the rest of my project (html, css, js files), I get the same error: cordova.exec is undefined.</p>
  
  <p>The responsible could be <strong>RequireJS</strong>, which may load cordova-2.2.0.js in a different way. It worked well with cordova 2.0.0 but seems not to with 2.2.0.</p>
  
  <p>I'll try to see if I can load cordova-2.2.0.js before RequireJS, and still use it once cordova is loaded.</p>
  
  <p>I'll keep you up to date :)</p>