2013-06-11 43 views
0

我在Sencha Touch 2.1中編寫了一個應用程序,其中我將一個包構建嵌入到Cordova/PhoneGap 2.5.0中,並在xCode中編譯以在iOS Simulator/iOS上運行。我已經加入了PGSQLite插件的PhoneGap,並建立了自己的PhoneGap/SQLite的代理爲煎茶,我在我的幾個店鋪的使用*確保在Sencha加載器之前加載phonegap和插件

問題:當我嵌入包建成的PhoneGap和運行在iOS Simulator中,我看到Cordova在Sencha初始化之前不會加載。我看到這個是因爲我在我的代理初始化過程中在我的Sencha應用中創建的Cordova.exec的調用導致錯誤,告訴我無法找到Cordova對象。

我以後在我的應用程序中成功使用Cordova.exec來運行諸如PhoneGap的Childbrowser插件之類的東西,並且它可以工作。但是,在應用程序執行的早期階段使用Cordova.exec,即初始化過早,不能保證科爾多瓦對象將被實例化。

已經嘗試過:我已經嘗試以下方法:

  1. 我試圖簡單地嵌入我的煎茶應用到的PhoneGap的開發版本。雖然這有效,但我不想將我的開發版本部署爲我的發佈應用程序,因爲它效率低下並佔用大量空間。然而,我從這個實驗中瞭解到,Sencha Touch小型裝載機在包裹和生產版本上工作的方式在Sencha之後加載PhoneGap。在Sencha加載到包構建後檢查DOM時,可以清楚地看到這一點。

  2. 我已經配置了我的app.json文件,在我的插件app.js和Sencha Touch框架之前包含了PhoneGap和 。播放 與我的JS文件引用順序在我的app.json沒有 似乎影響加載順序。

  3. 我也嘗試創建一個腳本加載器,如here (StackOverflow)所述。然後我爲Cordova運行腳本加載器,並在 的回調中爲我的插件運行了腳本加載器,然後,最後在回調中爲此運行了Sencha Touch microloader。這導致了一個錯誤。此外,在Sencha構建我的 包後,我不得不 手動設置在我的index.html文件中。這似乎是不可接受的。

我在尋找:我尋找答案如下:

  1. 是否有配置煎茶的微加載或一般我的煎茶的應用程序的方式,這樣科爾多瓦保證在Sencha的小型裝載機運行之前裝載?

  2. 有沒有一種方法來設置這個,以便使用Sencha Cmd仍然有效,並且在構建應用程序之後我不必在我的index.html文件中進行破解?

注: *請不要建議我使用現有的,所謂,SQLite的代理爲煎茶。我特別選擇了我的方法,因爲雖然我讚賞Sencha Touch 2的SQLite代理(即this)上的現有工作,但它實際上是一種WebSQL代理,它本身並不存儲在iOS上的SQLite中。我的代理使用PhoneGap的PGSQLite插件將數據本地存儲在iOS上的SQLite中。我打算在我有機會清理它並從我的代碼中解開它時開源。

回答

0

我最終通過構建自定義加載程序來解決這個問題。我不確定是否有更多Sencha-ish的方式來做到這一點,但這裏是我所做的細節,哪些是有效的,以防其他人想要確保PhoneGap完全被加載到包中,並且生成之前生成在Sencha運行任何東西。 (在PhoneGap打包Sencha應用程序的所有情況下,情況可能如此)。

我的index.html文件:

<!DOCTYPE HTML> 
<html manifest="" lang="en-US"> 
<head> 
    <!-- Load Cordova first. Replace with whatever version you are using --> 
    <script type="text/javascript" src="cordova.js"></script>  
    <script type="text/javascript" charset="utf-8"> 
     function onBodyLoad() { 
      // Check for whatever mobile you will run your PhoneGap app 
      // on. Below is a list of iOS devices. If you have a ton of 
      // devices, you can probably do this more elegantly. 
      // The goal here is to only listen to the onDeviceReady event 
      // to continue the load process on devices. Otherwise you will 
      // be waiting forever (literally) on Desktops. 
      if ((navigator.platform == 'iPad') || 
       (navigator.platform == 'iPhone') || 
       (navigator.platform == 'iPod') || 
       (navigator.platform == 'iPhone Simulator') || 
       (navigator.platform == 'iPadSimulator') 
       ) { 
       // Listening for this event to continue the load process ensures 
       // that Cordova is loaded. 
       document.addEventListener("deviceready", onDeviceReady, false); 
      } else { 
       // If we're on Desktops, just proceed with loading Sencha. 
       loadScript('loader.js', function() { 
        console.log('Finished loading scripts.'); 
       }); 
      } 
     }; 

     // This function is a modified version of the one found on 
     // StackOverflow, here: http://stackoverflow.com/questions/756382/bookmarklet-wait-until-javascript-is-loaded#answer-756526 
     // Using this allows you to wait to load another script by 
     // putting the call to load it in a callback, which is 
     // executed only when the script that loadScript is loading has 
     // been loaded. 
     function loadScript(url, callback) 
     { 
      var head = document.getElementsByTagName("head")[0]; 
      var script = document.createElement("script"); 
      script.src = url; 

      // Attach handlers for all browsers 
      var done = false; 
      script.onload = script.onreadystatechange = function() 
      { 
       if(!done && (!this.readyState 
          || this.readyState == "loaded" 
          || this.readyState == "complete")) 
       { 
        done = true; 

        // Continue your code 
        callback(); 
       } 
      }; 

      head.appendChild(script); 


     } 

     function onDeviceReady() { 
      console.log("[PhoneGap] Device initialized."); 
      console.log("[PhoneGap] Loading plugins."); 

      // You can load whatever PhoneGap plugins you want by daisy-chaining 
      // callbacks together like I did with pgsqlite and Sencha. 
      loadScript('pgsqlite_plugin.js', function() { 
       console.log("[Sencha] Adding loader."); 

       // The last one to load is the custom Sencha loader. 
       loadScript('loader.js', function() { 
        console.log('Finished loading scripts.'); 
       }); 
      }); 

     }; 
    </script> 

    <meta charset="UTF-8"> 
    <title>Sencha App</title> 
</head> 
<!-- Don't forget to call onBodyLoad() in onLoad --> 
<body onLoad="onBodyLoad();"> 
</body> 
</html> 

接下來,在你的文檔根目錄創建loader.js定製裝載機,沿着您的index.html。這個主要基於Sencha自帶的開發小型裝載機。很多道具對他們說:

console.log("Loader included."); 

(function() { 
    function write(content) { 
     document.write(content); 
    } 

    function meta(name, content) { 
     write('<meta name="' + name + '" content="' + content + '">'); 
    } 

    var global = this; 

    if (typeof Ext === 'undefined') { 
     var Ext = global.Ext = {}; 
    } 

    var head = document.getElementsByTagName("head")[0]; 

    var xhr = new XMLHttpRequest(); 
    xhr.open('GET', 'app.json', false); 
    xhr.send(null); 

    var options = eval("(" + xhr.responseText + ")"), 
     scripts = options.js || [], 
     styleSheets = options.css || [], 
     i, ln, path; 

    meta('viewport', 'width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no'); 
    meta('apple-mobile-web-app-capable', 'yes'); 
    meta('apple-touch-fullscreen', 'yes'); 

    console.log("Loading stylesheets"); 
    for (i = 0,ln = styleSheets.length; i < ln; i++) { 
     path = styleSheets[i]; 

     if (typeof path != 'string') { 
      path = path.path; 
     } 

     var stylesheet = document.createElement("link"); 
     stylesheet.rel = "stylesheet"; 
     stylesheet.href = path; 

     head.appendChild(stylesheet); 
    } 

    for (i = 0,ln = scripts.length; i < ln; i++) { 
     path = scripts[i]; 

     if (typeof path != 'string') { 
      path = path.path; 
     } 

     var script = document.createElement("script"); 
     script.src = path; 
     head.appendChild(script); 
    } 

})(); 

請注意,您的index.html文件不包含#microloaderscript元素。那是因爲你應該把它拿出來並使用你的自定義加載器。

隨着所有這些,你將能夠順利地航行,知道整個PhoneGap環境在你的Sencha javascript開始做事之前已經到位。

+0

加載速度有多快? – fct