TiShadow
Quick Titanium previews across devices
Install / Use
/learn @dbankier/TiShadowREADME
TiShadow
TiShadow provides Titanium developers the ability to deploy apps, run tests or execute code snippets live across all running iOS and Android devices.
There are three parts to TiShadow: the TiShadow server, TiShadow app and TiShadow CLI which are all need.
~~Have a look at this presentation (July 2012) given at the TiLondon meetup for a look at most of what you can do with TiShadow.~~ (Outdated)
Go to the new project website
Join the discussion on the Google Group. You can also find some TiShadow related blog posts here
Getting Started
TiShadow Install
TiShadow NPM Package
TiShadow is built on node.js and is required.
TiShadow can be installed via npm using the following command:
$ npm install -g tishadow
PLEASE NOTE: The package installs titanium hooks in the post install.
If you install with sudo and get the error Unable to write config file... use the following command:
$ sudo npm install -g tishadow --unsafe-perm
Or if you want to use the master version directly from GitHub:
npm install -g dbankier/TiShadow
Using the Appcelerator CLI
By default TiShadow uses the (free) titanium and alloy cli's under the hood. If you are using the (paid) appc cli then
use the following command after installation:
$ ts config --use-appc-CLI
NEW DUMMY'S PATH: TiShadow Express
You can do a lot with TiShadow. Keep reading this README to find out more. But if it is all too much at the moment and you just want to use it for live reload you can do the following.
During install a titanium cli plugin/hook was installed for you. From your project you can just use the following command:
titanium build -p android -T device --shadow
This will launch your app in the simulator and reload with any code/style/localisation changes.
Under the hood it:
- starts the tishadow server -
tishadow server - creates and launches an appified version of your app -
tishadow appify(with extra flags) - watches your code and push on any changes -
tishadow @ run --update
MAC: If you get the error EMFILE: Too many opened files., this is because of your system's max opened file limit. For OSX the default is very low (256). Increase your limit temporarily with ulimit -n 8192, the number being the new max limit.
TiShadow App
To create a new titanium project use the following command:
tishadow app -d [destination folder]
e.g.
mkdir ~/tishadowapp
tishadow app -d ~/tishadowapp
NOTE: In general upgrade the server side and app at
the same time (using the tishadow app command).
You can upgrade an existing tishadow app using the --upgrade flag.
Start the TiShadow Server
The server can be started by typing the following command:
tishadow server
The following options are available:
-h, --help output usage information
-p, --port <port> server port
-l, --long-polling force long polling
-i, --internal-ip <internal-ip> internal ip to bind to
-s, --screenshot-path <screenshot-path> path to save screenshot (defaults to /tmp)
-z, --manage-versions manage and automatically update bundles
If --manage-versions is enabled, then bundle versions are tracked and
devices that connect with an older version will automatically be
updated. When using this mode, you can use the tishadow deploy command
to send a new bundle to the server without pushing it to connected
devices.
Remote Server Mode and Private Rooms
The TiShadow Server supports remote hosting with configurable http ports. It also allow for private "rooms" (much like chat rooms) so that the TiShadow server can be shared.
The tishadow log command is
available to tail remote server logs (in the default or selected room).
The tishadow config command is available to set the default host, port
and room for all the relevant command below.
Start the TiShadow App
Once the server is running launch the app. For example, to launch the app in the iPhone simulator using the Titanium CLI:
cd ~/tishadowapp
titanium build -p iphone
From the app just enter the ip address or hostname of the computer running the server and hit connect. (There are also more advanced connection settings that can be used for remote server connections.)
What you can do with TiShadow
Full Application Deployment
Go to the root folder of your project and enter the following command to deploy an app:
tishadow run
If the app has been deployed and you want to push minor updates, use the following command:
tishadow run --update
Here are full list of options:
-h, --help output usage information
-u, --update only send recently changed files
-a, --patch patch updated files without causing app restart
-i, --inspector enable automatic inspection and spies
-l, --locale <locale> set the locale in in the TiShadow app
-j, --jshint analyse code with JSHint
-t, --tail-logs tail server logs on deploy
-o, --host <host> server host name / ip address
-p, --port <port> server port
-r, --room <room> server room
-s, --skip-alloy-compile skip automatic alloy compilation
-f, --alloy-compile-file <filename> compile only one alloy file
-P, --platform <platform> target platform
-D, --include-dot-files includes dot files in the bundle (defaults to false)
-T, --target <app_name> target TiShadow app (defaults to name on tiapp.xml or moduleid on manifest)
-c, --ticommonjs support for applications using the ti-commonjs library
The app is then cached on the device. If you need to clear the cache, use the following command:
tishadow clear
Some notes and limitations
- Only files in the Resources directory will be sent to the device using TiShadow. That said, localisation files are supported. (see options above).
- Native modules can be supported if built into the TiShadow app first. (I.e., add them to the tiapp.xml of the TiShadow app.)
- Custom fonts will be loaded if placed in the
Resources/fontsdirectory for iOS only. - If there any errors about a Titanium SDK command not being found, add them to the Includes.js files and clean and build the TiShadow app. (I will gradually be adding commands.)
- Any Ti.API logs will be redirected to the server logs and webpage.
Testing / Assertions
TiShadow supports Jasmine BDD tests. (Insipration taken from these two projects: titanium-jasmine and jasmine-titanium)
Include your specs in the spec path of your project. Ensure
the files are ending in _spec.js. (Note: simply write the spec without any including/requiring the jasmine library.)
To execute the tests enter the following command:
tishadow spec
Here are a full list of options:
-h, --help output usage information
-u, --update only send recently changed files
-l, --locale <locale> set the locale in in the TiShadow app
-o, --host <host> server host name / ip address
-p, --port <port> server port
-r, --room <room> server room
-t, --type <type> testing library
-j, --jshint analyse code with JSHint
-x, --junit-xml output report as JUnit XML
-P, --platform <platform> target platform
-s, --skip-alloy-compile skip automatic alloy compilation
-f, --alloy-compile-file <filename> compile only one alloy file
-D, --include-dot-files includes dot files in the bundle (defaults to false)
-T, --target <app_name> target TiShadow app (defaults to name on tiapp.xml or moduleid on manifest)
-C, --clear-spec-files clears only the spec files from the cache
-c, --coverage <report_types> runs code coverage, for available report_types see https://github.com/gotwarlost/istanbul#the-report-command```
NEW: You can now select the testing library to use jasmine, mocha-should or mocha-chai.
The default library is jasmine to change that use, e.g. tishadow config -t mocha-should.
NEW: test coverage reports using instanbul is also available using the --coverage <report_types> flag.
The test results will be returned to the server/cli output:

See the included example project or this blog post.
Alternatively (yet not preferred/depcrecated)
TiShadow also supports the use of assertions and the results are returned either to the browser or server logs.
For example:
assert.isNumber(6, "Testing if 6 is a number");
assert.isArray([1,2,3,4], "Testing if it is an array");
The following assertion are supported: 'equal', 'strictEqual', 'deepEqual', 'isTrue', 'isFalse', 'isEmpty', 'isElement', 'isArray','isObject', 'isArguments', 'isFunction', 'isString', 'isNumber'
