I am using Sencha Touch 2.3.1 with Sencha CMD 4.0.2.67 in conjunction with Cordova 3.4.
The purpose of my doing is to know how to use Sencha tools to create the mobile app and then using Sencha CMD + Cordova to build and run on Android and Windows Phone 8 platforms.(I have set up both environment on my PC and managed to build and run my mobile app just with Cordova for Android and WP8).
Now, I followed the tutorial on Sencha about creating the 1st app(http://docs.sencha.com/touch/2.3.0/#!/guide/first_app), encountered many odd crashes but fortunately, I somehow fixed all of them(I'm surprised by myself). The learning procedure is very exciting for me so far and I found that Sencha CMD and even starts WP and Android emulators!
Now the problem is, when I execute the command sencha app build -run native
, both platforms have my app generated and run, but the panels I created under Sencha, do not show up. What I get is the launching screen with 4 flashing dots.
It supposes to show a UI which has 3 tabPanels.
Here is my app.js:
launch: function () {
// Destroy the #appLoadingIndicator element
Ext.fly('appLoadingIndicator').destroy();
Ext.create("Ext.tab.Panel", {
fullscreen: true,
tabBarPosition: "bottom",
items: [
{
title: 'Home',
iconCls: 'home',
cls: 'home',
html: [
'<img src="http://staging.sencha.com/img/sencha.png" />',
'<h1>Welcome to Sencha Touch</h1>',
"<p>You're creating the Getting Started app. This demonstrates how ",
"to use tabs, lists, and forms to create a simple app.</p>",
'<h2>Sencha Touch</h2>'
].join("")
},
{ // the 2nd item}, {// the 3rd one}
And here is what the Sencha generated under MyApp/cordova/platforms/wp8 in index.html
<!DOCTYPE HTML>
<html manifest="" lang="en-US">
<head>
<meta charset="UTF-8">
<title>MySenCha</title>
<style type="text/css">
/**
* Example of an initial loading indicator.
* It is recommended to keep this as minimal as possible to provide instant feedback
* while other resources are still being loaded for the first time
*/
html, body {
height: 100%;
background-color: #1985D0;
}
#appLoadingIndicator {
position: absolute;
// many lines of generated css
}
}
</style>
<!-- The line below must be kept intact for Sencha Command to build your application -->
<script type="text/javascript">(function(e){var c=e.document.head||e.document.getElementsByTagName("head")[0],b=e.Ext;if(typeof b=="undefined"){e.Ext=b={}}function d(f){document.write(f)}function a(f,g){var h=document.createElement("meta");h.setAttribute("name",f);h.setAttribute("content",g);c.appendChild(h)}b.blink=function(q){var k=q.js||[],o=q.css||[],m,n,p,h,l,g;if(navigator.userAgent.match(/IEMobile\/10\.0/)){var j=document.createElement("style");j.appendChild(document.createTextNode("@media screen and (orientation: portrait) {@-ms-viewport {width: 320px !important;}}@media screen and (orientation: landscape) {@-ms-viewport {width: 560px !important;}}"));document.getElementsByTagName("head")[0].appendChild(j)}a("viewport","width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no");a("apple-mobile-web-app-capable","yes");a("apple-touch-fullscreen","yes");b.microloaded=true;var f=window.Ext.filterPlatform=function(u){var D=false,s=navigator.userAgent,w,A;u=[].concat(u);function z(E){var i=/Mobile(\/|\s)/.test(E);return/(iPhone|iPod)/.test(E)||(!/(Silk)/.test(E)&&(/(Android)/.test(E)&&(/(Android 2)/.test(E)||i)))||(/(BlackBerry|BB)/.test(E)&&i)||/(Windows Phone)/.test(E)}function y(i){return !z(i)&&(/iPad/.test(i)||/Android|Silk/.test(i)||/(RIM Tablet OS)/.test(i)||(/MSIE 10/.test(i)&&/; Touch/.test(i)))}var r=window.location.search.substr(1),t=r.split("&"),v={},B,x;for(x=0;x<t.length;x++){var C=t[x].split("=");v[C[0]]=C[1]}B=v.platform;if(B){return u.indexOf(B)!=-1}for(w=0,A=u.length;w<A;w++){switch(u[w]){case"phone":D=z(s);break;case"tablet":D=y(s);break;case"desktop":D=!z(s)&&!y(s);break;case"ios":D=/(iPad|iPhone|iPod)/.test(s);break;case"android":D=/(Android|Silk)/.test(s);break;case"blackberry":D=/(BlackBerry|BB)/.test(s);break;case"safari":D=/Safari/.test(s)&&!(/(BlackBerry|BB)/.test(s));break;case"chrome":D=/Chrome/.test(s);break;case"ie10":D=/MSIE 10/.test(s);break;case"windows":D=/MSIE 10/.test(s)||/Trident/.test(s);break;case"tizen":D=/Tizen/.test(s);break;case"firefox":D=/Firefox/.test(s)}if(D){return true}}return false};for(m=0,n=o.length;m<n;m++){p=o[m];if(typeof p!="string"){h=p.platform;g=p.exclude;l=p.theme;p=p.path}if(h){if(!f(h)||f(g)){continue}if(!b.theme){b.theme={}}if(!b.theme.name){b.theme.name=l||"Default"}}d('<link rel="stylesheet" href="'+p+'">')}for(m=0,n=k.length;m<n;m++){p=k[m];if(typeof p!="string"){h=p.platform;g=p.exclude;p=p.path}if(h){if(!f(h)||f(g)){continue}}d('<script src="'+p+'"><\/script>')}}})(this);Ext.blink({id:"19f378b6-7681-4874-9579-87ab900c2cde",js:[{path:"cordova.js",remote:true},{path:"app.js",update:"delta"}],css:[{path:"resources/css/app.css",update:"delta"}]});</script>
</head>
<body>
<div id="appLoadingIndicator">
<div></div>
<div></div>
<div></div>
</div>
</body>
</html>
As you can see here "Ext.Blink(id......., .... ,...., js:[xxxx,'app.js'])".
So here is the app.js under wp8/www folder
(function(){var global=this,...many code more than 570000 letters, so I have to cut the m down..................if(window.scrollY!==0){window.scrollTo(0,0)}}})}}});Ext.define("Ext.viewport.WindowsPhone",{requires:[],alternateClassName:"Ext.viewport.WP",extend:Ext.viewport.Default,config:{translatable:{translationMethod:"csstransform"}},initialize:function(){var a=function(d){var c=d.srcElement.nodeName.toUpperCase(),b=["INPUT","TEXTAREA"];if(b.indexOf(c)==-1){return false}};document.body.addEventListener("onselectstart",a);this.callParent(arguments)},supportsOrientation:function(){return false},onResize:function(){this.waitUntil(function(){var c=this.windowWidth,f=this.windowHeight,e=this.getWindowWidth(),a=this.getWindowHeight(),d=this.getOrientation(),b=this.determineOrientation();return((c!==e&&f!==a)&&d!==b)},function(){var b=this.getOrientation(),a=this.determineOrientation();this.fireOrientationChangeEvent(a,b)},Ext.emptyFn,250)}});Ext.define("Ext.viewport.Viewport",{constructor:function(b){var c=Ext.os.name,d,a;switch(c){case"Android":d=(Ext.browser.name=="ChromeMobile")?"Default":"Android";break;case"iOS":d="Ios";break;case"Windows":d=(Ext.browser.name=="IE")?"WindowsPhone":"Default";break;case"WindowsPhone":d="WindowsPhone";break;default:d="Default";break}a=Ext.create("Ext.viewport."+d,b);return a}});Ext.define("MySenCha.view.Main",{extend:Ext.tab.Panel,xtype:"main",config:{tabBarPosition:"bottom",items:[{title:"My Home",iconCls:"home",styleHtmlContent:true,scrollable:true,items:{docked:"top",xtype:"titlebar",title:"Welcome to Sencha Touch 2"},html:["You've just generated a new Sencha Touch 2 project. What you're looking at right now is the ","contents of <a target='_blank' href=\"app/view/Main.js\">app/view/Main.js</a> - edit that file ","and refresh to change what's rendered here."].join("")},{title:"Get Started",iconCls:"action",items:[{docked:"top",xtype:"titlebar",title:"Getting Started"},{xtype:"video",url:"http://av.vimeo.com/64284/137/87347327.mp4?token=1330978144_f9b698fea38cd408d52a2393240c896c",posterUrl:"http://b.vimeocdn.com/ts/261/062/261062119_640.jpg"}]}]}});Ext.application({name:"MySenCha",views:["Main"],icon:{"57":"resources/icons/Icon.png","72":"resources/icons/Icon~ipad.png","114":"resources/icons/Icon@2x.png","144":"resources/icons/Icon~ipad@2x.png"},isIconPrecomposed:true,startupImage:{"320x460":"resources/startup/320x460.jpg","640x920":"resources/startup/640x920.png","768x1004":"resources/startup/768x1004.png","748x1024":"resources/startup/748x1024.png","1536x2008":"resources/startup/1536x2008.png","1496x2048":"resources/startup/1496x2048.png"},launch:function(){Ext.fly("appLoadingIndicator").destroy();Ext.create("Ext.tab.Panel",{fullscreen:true,tabBarPosition:"bottom",items:[{title:"Home",iconCls:"home",cls:"home",html:['<img src="http://staging.sencha.com/img/sencha.png" />',"<h1>Welcome to Sencha Touch</h1>","<p>You're creating the Getting Started app. This demonstrates how ","to use tabs, lists, and forms to create a simple app.</p>","<h2>Sencha Touch</h2>"].join("")},{xtype:"nestedlist",title:"Blog",iconCls:"star",displayField:"title",store:{type:"tree",fields:["title","link","author","contentSnippet","content",{name:"leaf",defaultValue:true}],root:{leaf:false},proxy:{type:"jsonp",url:"https://ajax.googleapis.com/ajax/services/feed/load?v=1.0&q=http://feeds.feedburner.com/SenchaBlog",reader:{type:"json",rootProperty:"responseData.feed.entries"}}},detailCard:{xtype:"panel",scrollable:true,styleHtmlContent:true},listeners:{itemtap:function(e,d,a,c,b){this.getDetailCard().setHtml(b.get("content"))}}},{title:"Contact",iconCls:"user",xtype:"formpanel",url:"contact.php",layout:"vbox",items:[{xtype:"fieldset",title:"Contact Us",instructions:"(email address is optional)",height:285,items:[{xtype:"textfield",label:"Name"},{xtype:"emailfield",label:"Email"},{xtype:"textareafield",label:"Message"}]},{xtype:"button",text:"Send",ui:"confirm",handler:function(){this.up("formpanel").submit()}}]}]})},onUpdated:function(){Ext.Msg.confirm("Application Update","This application has just successfully been updated to the latest version. Reload now?",function(a){if(a==="yes"){window.location.reload()}})}});
I finally found where my code, as you might see that my code has been included in the app.js under wp8/www folder.
But when I tried to run from the index.html or deploy the app onto my device, I only got Cordova splash screen and a blue screen, no my tab panels at all.
I also checked the log generated during building and running my app and found that when running WP8 app, it said:
[TypeError: undefined is not a function]
Then I when to the generated index.html and did find many of them.
Incidentally, I ran my app on 3 browsers: IE10, Chrome (latest), Firefox (just downloaded). Only Firefox can run the Sencha Touch app successfully. The rest of others just can show the blue screen in the demo without characters and pic, no tab panels docked at the bottom either.
I feel like I am very close to the final success of my learning.
File : MySenCha/app.js
Ext.application({
name: 'MySenCha',
requires: [
'Ext.MessageBox'
],
views: [
'Main'
],
icon: {
'57': 'resources/icons/Icon.png',
'72': 'resources/icons/Icon~ipad.png',
'114': 'resources/icons/Icon@2x.png',
'144': 'resources/icons/Icon~ipad@2x.png'
},
isIconPrecomposed: true,
startupImage: {
'320x460': 'resources/startup/320x460.jpg',
'640x920': 'resources/startup/640x920.png',
'768x1004': 'resources/startup/768x1004.png',
'748x1024': 'resources/startup/748x1024.png',
'1536x2008': 'resources/startup/1536x2008.png',
'1496x2048': 'resources/startup/1496x2048.png'
},
launch: function () {
// Destroy the #appLoadingIndicator element
Ext.fly('appLoadingIndicator').destroy();
Ext.create("Ext.tab.Panel", {
fullscreen: true,
tabBarPosition: "bottom",
items: [
{
title: 'Home',
iconCls: 'home',
cls: 'home',
html: [
'<img src="http://staging.sencha.com/img/sencha.png" />',
'<h1>Welcome to Sencha Touch</h1>',
"<p>You're creating the Getting Started app. This demonstrates how ",
"to use tabs, lists, and forms to create a simple app.</p>",
'<h2>Sencha Touch</h2>'
].join("")
},
{
xtype: 'nestedlist',
title: 'Blog',
iconCls: 'star',
displayField: 'title',
store: {
type: 'tree',
fields: [
'title', 'link', 'author', 'contentSnippet', 'content', { name: 'leaf', defaultValue: true }
],
root: { leaf: false },
proxy: {
type: 'jsonp',
url: 'https://ajax.googleapis.com/ajax/services/feed/load?v=1.0&q=http://feeds.feedburner.com/SenchaBlog',
reader: {
type: 'json',
rootProperty: 'responseData.feed.entries'
}
}
},
detailCard: {
xtype: 'panel',
scrollable: true,
styleHtmlContent: true
},
listeners: {
itemtap: function (nestedList, list, inde, element, post) {
this.getDetailCard().setHtml(post.get('content'));
}
}
},
{
title: 'Contact',
iconCls: 'user',
xtype: 'formpanel',
url: 'contact.php',
layout: 'vbox',
items: [
{
xtype: 'fieldset',
title: 'Contact Us',
instructions: '(email address is optional)',
height: 285,
items: [
{
xtype: 'textfield',
label: 'Name'
},
{
xtype: 'emailfield',
label: 'Email'
},
{
xtype: 'textareafield',
label: 'Message'
}
]
},
{
xtype: "button",
text: 'Send',
ui: 'confirm',
handler: function () {
this.up('formpanel').submit();
}
}
]
}
]
});
//// Initialize the main view
//Ext.Viewport.add(Ext.create('MySenCha.view.Main'));
},
onUpdated: function () {
Ext.Msg.confirm(
"Application Update",
"This application has just successfully been updated to the latest version. Reload now?",
function (buttonId) {
if (buttonId === 'yes') {
window.location.reload();
}
}
);
}
});
File : app.json
{
/**
* The application's namespace, used by Sencha Command to generate classes
*/
"name": "MySenCha",
/**
* The file path to this application's front HTML document, relative to this app.json file
*/
"indexHtmlPath": "index.html",
/**
* The absolute URL to this application in development environment, i.e: the URL to run this application
* on your web browser during development, e.g: "http://localhost/myapp/index.html".
*
* This value is needed when build to resolve your application's dependencies if it requires server-side resources
* that are not accessible via file system protocol.
*/
"url": "http://localhost:1841/index.html",
/**
* List of all JavaScript assets in the right execution order.
* Each item is an object with the following format:
* {
* "path": "path/to/script.js" // Path to file, if local file it must be relative to this app.json file
* "remote": true // (Optional)
* // - Defaults to undefined (falsey) to signal a local file which will be copied
* // - Specify true if this file is a remote file which will not to be copied
* "update": "delta" // (Optional)
* // - If not specified, this file will only be loaded once, and
* // cached inside localStorage until this value is changed.
* // - "delta" to enable over-the-air delta update for this file
* // - "full" means full update will be made when this file changes
* "x-bootstrap": true // (Optional)
* // Indicates a development mode only dependency.
* // These files will not be copied into the build directory or referenced
* // in the generate app.json manifest for the micro loader.
*
* }
*/
"js": [
{
"path": "cordova.js",
"remote": true
},
{
"path": "touch/sencha-touch.js",
"x-bootstrap": true
},
{
"path": "bootstrap.js",
"x-bootstrap": true
},
{
"path": "app.js",
"bundle": true, /* Indicates that all class dependencies are concatenated into this file when build */
"update": "delta"
}
],
/**
* List of all CSS assets in the right inclusion order.
* Each item is an object with the following format:
* {
* "path": "path/to/item.css" // Path to file, if local file it must be relative to this app.json file
* "remote": true // (Optional)
* // - Defaults to undefined (falsey) to signal a local file which will be copied
* // - Specify true if this file is a remote file which will not to be copied
* "update": "delta" // (Optional)
* // - If not specified, this file will only be loaded once, and
* // cached inside localStorage until this value is changed to either one below
* // - "delta" to enable over-the-air delta update for this file
* // - "full" means full update will be made when this file changes
*
* }
*/
"css": [
{
"path": "resources/css/app.css",
"update": "delta"
}
],
/**
* Used to automatically generate cache.manifest (HTML 5 application cache manifest) file when you build
*/
"appCache": {
/**
* List of items in the CACHE MANIFEST section
*/
"cache": [
"index.html"
],
/**
* List of items in the NETWORK section
*/
"network": [
"*"
],
/**
* List of items in the FALLBACK section
*/
"fallback": []
},
/**
* Extra resources to be copied along when build
*/
"resources": [
"config.xml",
"resources/images",
"resources/icons",
"resources/startup"
],
/**
* File / directory name matchers to ignore when copying to the builds, must be valid regular expressions
*/
"ignore": [
"\.svn$"
],
/**
* Directory path to store all previous production builds. Note that the content generated inside this directory
* must be kept intact for proper generation of deltas between updates
*/
"archivePath": "archive",
/**
* List of package names to require for the cmd build process
*/
"requires": [
],
/**
* Uniquely generated id for this application, used as prefix for localStorage keys.
* Normally you should never change this value.
*/
"id": "19f378b6-7681-4874-9579-87ab900c2cde"
}
Here is the log for running: cordova run --device.
F:\Workplace\TestSenchaApp\cordova>cordova run --device
Preparing wp8 project
[TypeError: undefined is not a function]
Running command: cmd args=["/c","F:\\Workplace\\TestSenchaApp\\cordova\\platforms\\wp8\\cordova\\run","--device"]
WARNING: [ --debug | --release | --nobuild ] not specified, defaulting to --debug.
Cleaning cordova project...
Building Cordova-WP8 Project:
Configuration : Debug
Directory : F:\Workplace\TestSenchaApp\cordova\platforms\wp8
Building the projects in this solution one at a time. To enable parallel build, please add the "/m" switch.
TestSenchaApp -> F:\Workplace\TestSenchaApp\cordova\platforms\wp8\Bin\Debug\com.test.myApp.dll
Begin application manifest generation
Application manifest generation completed successfully
Begin Xap packaging
BUILD SUCCESS.
Deploying to device ...
Connecting to device :: 30F105C9-681E-420b-A277-7C086EAD8A4E : Device
Installing app on Device
Launching app on Device
EXIT
F:\Workplace\TestSenchaApp\cordova>
Here are commands I ran to generate app and deploy on my device:
Ran step 8, still got the same issue.
Finally, I spotted the culprit of this problem.
It was because I have a messy cordova at .cordova/lib. So what I did was deleted the entire .cordova under C:\Users\\
And reinstalled cordova.
Then the problem solved :)
For more detailed information please see here : http://www.sencha.com/forum/showthread.php?282942-App-runs-but-stuck-at-the-loading-screen(3-dots-screen)
At #15
Hope it helps, cheers