Archive for December, 2010

Published by Rolf on 28 Dec 2010

Deploying the first Titanium app to an iPhone

As might be expected, deploying a Titanium app to an iPhone was pretty easy. For the most part, just follow this video. However, there were these gotchas:

Disabled Install Now button

As per this post, it wasn’t obvious why the Install Now button was disabled. But clicking the “Upload” link next to the Upload Development Provisioning Profile line brought up a file dialog, where you navigate to your Mobile Provisioning file. By following the directions in the video, mine went to ~/Downloads/ when previously downloaded from Safari. Upload this file, quit and restart Titanium Developer, and you should see that it’s now detected the WWDR certificate and the Install Now button is enabled. After waiting a bit, the application will be pushed to iTunes.

iTunes needs to be able to sync to the phone

In my case, I use iTunes on my PC to sync ordinarily. So the Mac install of iTunes didn’t recognize my phone. So I had to do the following:

  1. First I wanted to ensure it wouldn’t try to sync anything automatically.
  2. Then I had to Authorize the Mac
  3. Use iTunes to back up the phone, specifically the applications since I don’t want or need it to sync the music, movies, etc..
  4. Then take a deep breath and click Sync – it will sync the apps now.
  5. Check your new app (which will not have been synced by default), and sync again.

You’ll now see the new app on your Home screen. Of course all the other apps will be out of order but that’s a minor problem…

“Test & Package” tab can go AWOL

I have no idea what caused this but at some point this tab completely disappeared from Titanium Developer, from all projects. I tried launching it with the –debug flag, but nothing untoward appeared in the log. So eventually I deleted the contents of /Library/Application Support/Titanium/modules/ and relaunched Titanium Developer. This triggered a reload of the modules it needed from the Appcelerator website, and after doing so the “Test & Package” tab mysteriously returned. If you do this, you’ll have to reinstall any 3rd-party modules you have to /Library/Application Support/Titanium/modules so it’s a good idea to back those up first.

Published by Rolf on 28 Dec 2010

Deploying a Titanium project to an Android phone for the first time

This took several hours, with multiple dead ends, but here’s my story of getting my first Titanium app deployed to an Android device, using Windows 7 64-bit Ultimate.

First, which phone to get? Obviously I want the cheapest possible, with no commitment. It doesn’t need to even be activated, since I won’t be making any calls with it; it’ll just be used as a test platform over wifi and USB. And for a realistic scenario, I want the lowest-end OS possible (Android 2.1 in this case). So I got a no-contract Samsung Intercept, over Virgin Mobile, from BestBuy for $169. I realize that eventually I’ll need to get a real developer phone (like a Nexus S) but that shouldn’t be necessary initially. Turns out it isn’t, fortunately.

  1. First set up device for wifi.
    1. Good idea to write down the battery serial # first in case you need it later: XXXXXXXXX/XXX
    2. Install the battery. Strangely with no directions in the package this took a bit to figure out (I did end up googling for and downloading these manuals here and here. Eventually I used my fingernail to pop off the back cover, which was pretty flimsy.
    3. Once it’s charged, go to the home screen, scroll to Settings and tap.
    4. Check Wi-Fi to turn it on.
    5. Click “Wi Fi Settings” / Add Wi-Fi Network and enter your key. Now you’re connected and can browse the web.
  2. Set up the phone for debugging.
    1. When I plugged the USB into my PC for the first time, it got a “driver install failed” error, which I ignored. Turns out I shouldn’t have. Read on.
    2. In Titanium Developer, load your Titanium Project and confirm the Android SDK version is low enough for the device. You can find the Android version from the phone by going to Settings / About Phone. In my case it’s “2.1update1” and 2.2 is not out just yet.
    3. Go to Run on Device tab, then click the gray “Install Now” button. The yellow alert box in the upper right will say “Installing app to device”, but goes away after maybe a minute. That was easy!
    4. I check my phone though, and my app is not there. This sort of thing has been reported before. So I realize this could be a USB driver missing problem.
  3. Get the proper drivers for this phone.
    1. I unplug and then plug in the USB, and it tries again to install the drivers for Samsung Intercept and fails.
    2. Switch to Googling mode. I look online at Samsung.com for the driver, since maybe for some reason Windows doesn’t know about it. Searching by device name doesn’t work (pretty lame website there) so I have to find the Samsung model number, which isn’t anywhere in the packing materials, but I discover is SPH-M910 from looking under Settings / About Phone.
    3. I try to download the latest manual and driver but discover it’s only for XP/Vista, and won’t install on Windows 7 at all. Amazing for a phone that was released just a few months ago (see forums about lacking Win 64-bit drivers here and here).
    4. I google further, and find the unrecognizability in Windows 7 64-bit was related to USB debugging being enabled.
    5. So I disable the USB debugging:
      1. Leave USB unplugged.
      2. Now go to Settings / Applications on phone.
      3. Check “Unknown sources”
      4. Go to Development and check “Stay Awake” and “Allow Mock Locations”.
      5. Turn off phone
      6. Plug USB back in.
      7. Turn on phone
      8. It should now show up in devices in Windows (Control Panel / Hardware and Sound / Devices and Printers) as SAMSUNG_Android.
    6. On the phone, set it to be mountable as a drive.
      1. You should see the little USB symbol at the top of your Android screen.
      2. Touch the top of the screen and scroll it down – you will see “USB Storage” – tap on that.
      3. A new menu will pop up and you should see “Mount” and select it.
    7. Try to install the app again in Titanium, wait a minute for Installing alert to subside, but still same result.
    8. I decide to eliminate Titanium as a possible variable, so I it’s time to back up and see if I can build a simple HelloAndroid app with Eclipse. It builds and runs fine in the emulator. OK, that’s something.
    9. Follow the directions to install the Google USB driver, but this doesn’t work in my case since the Samsung Intercept is not part of the driver INF file. So I add the entries, noting that I also need to add “\” to each lines which was a typo in the post.
    10. Try to update the Samsung device using the new modified INF file via the Device Manager, but Windows claims the most recent version of the driver has already been installed. Strange.
    11. Maybe the INF settings need tweaking so I unplug the phone from USB.
    12. Download, unzip and run the usbdeview utility and try to re-install the INF via that. No difference.
    13. Maybe the Device ID in the INF is incorrect, so find Samsung ID here. I confirm the Device ID’s are correct so that’s not the issue.
    14. Finally a bit of luck, via Google I stumble across this page on a heretofore unknown Samsung mobile developer site. What’s interesting about the developer guide is that even though the page is all about the Galaxy Tab, there’s a download for Samsung Mobile USB drivers that I hadn’t seen anywhere else.
    15. So I created a Samsung developer account needed to download the “Samsung USB Driver for Mobile Phones”.
    16. I uneventfully install this new MSI.
    17. With the phone plugged in, I get an alert saying the driver was installed. So now the moment of truth – can I use USB debugging now?
    18. Unplug phone from USB.
    19. Check “USB Debugging” on phone.
    20. Plug phone into PC.
    21. Now, Windows installs a set of 4 Samsung drivers (specifically USB Composite device, Android USB Mode, USB Mass Storage Device, and (the kicker!) Android Composite ADB Interface.
    22. That looks much better. Check to see if it appears as an ADB device now:
      c:\Program Files (x86)\Android\android-sdk-windows\platform-tools> adb devices
      List of devices attached
      emulator-5560   device
      M9101f380ce9    device

      Yay – there it is!

  4. Now back to Eclipse. Rebuild the HelloAndroid project in Eclipse, and as per these directions, choose to Run at the new device instead of the Emulator. Boom, it gets pushed to the phone and launches automatically.
  5. Now try Titanium Developer. Click install now, wait about 45 seconds, and boom, it’s installed.

I’ve read reports that this is easier on a Mac (deploying to Android “just works”), and probably one of the more expensive phones supported by Google’s USB driver would have made life easier. But now I can say that I have a Titanium app running on a realistic end-user phone.

Next up, deploying to iPhone.

Published by Rolf on 22 Dec 2010

Getting up and running on Titanium

Today I got started on the Titanium platform. Being a newbie to native mobile development, there were a couple hiccups along the way. In retrospect this would have been much easier on a Mac I’m sure, but just to make it difficult (touch of sarcasm) I tried it on Windows 7 64-bit. My goal was to set up an environment to run the Kitchen Sink demo described on the Getting Started page.

  1. I had installed the JRE and JDK at some point in the past few months to the default location C:\Program Files (x86) – this would come back to bite me.
  2. I installed Titanium Developer and the Android SDK as instructed; everything went to the default locations.
  3. I downloaded the KitchenSink project from the GitHub link provided, extracted it, imported it, and then tried to test it in the emulator. Here was the first error, described in this post. Sadly, adding C:\Program Files (x86)\Android\android-sdk-windows\platform-tools to the PATH didn’t seem to have an effect, so instead I used the hammer: I copied adb.exe from C:\Program Files (x86)\Android\android-sdk-windows\platform-tools to C:\Program Files (x86)\Android\android-sdk-windows\tools (Windows of course doesn’t have symlinks and I didn’t want to deal with a hardlink).
  4. Still errors. Next step was to install every conceivable Android SDK version (maybe that was the problem), so from the SDK manager, I installed Android SDK Tools, SDK Platform Tools, and all SDK Platform Android X.X’s.
  5. I tried to launch KitchenSink demo again, and get this error: [ERROR] JDK version 'javac' is not recognized as an internal or external command. Hmm.. According to this link, the default location for the JDK C:\Program Files (x86)\Java doesn’t work because of the spaces in the name. So I moved jsk1.6.0_21 to a different directory without spaces, and then reset my JAVA_HOME environment variable to point to this. Also had to add %JAVA_HOME%\bin to the PATH.
  6. Trying again, now I get: [TRACE] E/PackageManager( 67): Package com.appcelerator.kitchensink requires unavailable shared library com.google.android.maps; failing!. According to this post, that means I have to switch to the “APIs 2.3” SDK. That’s not an option for me so I go back to the SDK manager and install Google API’s, Android API 9 (under Third Party Add-ons). Launch Developer again and now “APIs 2.3″ is an option, so I select it.
  7. Try again. That error is gone now, but now I get [ERROR] Failed installing com.appcelerator.kitchensink: pkg: /data/local/tmp/app.apk and [TRACE] Failure [INSTALL_FAILED_MISSING_SHARED_LIBRARY]. Argh. At this point I am convinced that there’s some missing dependency for this sample KitchenSink project in particular, so maybe a simpler one would work.
  8. Try to create a New Project in the Titanium Developer and launch that. Success!

OK, I can now build an Android app, so I am halfway there; now on to the iOS side. I dig up an old Mac Mini, upgrade it to Snow Leopard, and install the latest XCode (3.2.5) and iOS SDK (4.2) off the Apple site. Then:

  1. Verify I can build a new project in XCode. Check.
  2. Install the latest Titanium Developer (version 1.2.2) from the Appcelerator site, which automatically installs a Titanium SDK which I would assume to be the latest (but it isn’t, read on..).
  3. Create a new Titanium project. Go to “Test and Package” tab, and the SDK poplist is hung on “loading…”. Odd – but other folks have reported this (here and here). But since I know I have a complete XCode and iOS SDK environment here, maybe it doesn’t mean anything, so I try to launch:
    [INFO] Compiling JavaScript...one moment
    [INFO] No JavaScript errors detected.
    [INFO] One moment, building ...
    [INFO] Performing full rebuild. This will take a little bit. Hold tight...
    [DEBUG] copy resources from /Users/NAME/Documents/TitaniumiPhoneSample/Resources to /Users/NAME/Documents/TitaniumiPhoneSample/build/iphone/tmp
    [DEBUG] copying: /Users/NAME/Documents/TitaniumiPhoneSample/Resources/app.js to /Users/NAME/Documents/TitaniumiPhoneSample/build/iphone/tmp/app.js
    [DEBUG] copying: /Users/NAME/Documents/TitaniumiPhoneSample/Resources/KS_nav_ui.png to /Users/NAME/Documents/TitaniumiPhoneSample/build/iphone/tmp/KS_nav_ui.png
    [DEBUG] copying: /Users/NAME/Documents/TitaniumiPhoneSample/Resources/KS_nav_views.png to /Users/NAME/Documents/TitaniumiPhoneSample/build/iphone/tmp/KS_nav_views.png
    [DEBUG] copying: /Users/NAME/Documents/TitaniumiPhoneSample/Resources/iphone/appicon.png to /Users/NAME/Documents/TitaniumiPhoneSample/build/iphone/tmp/iphone/appicon.png
    [DEBUG] copying: /Users/NAME/Documents/TitaniumiPhoneSample/Resources/iphone/Default.png to /Users/NAME/Documents/TitaniumiPhoneSample/build/iphone/tmp/iphone/Default.png
    [DEBUG] copy resources from /Users/NAME/Documents/TitaniumiPhoneSample/Resources/iphone to /Users/NAME/Documents/TitaniumiPhoneSample/build/iphone/tmp
    [DEBUG] copying: /Users/NAME/Documents/TitaniumiPhoneSample/Resources/iphone/appicon.png to /Users/NAME/Documents/TitaniumiPhoneSample/build/iphone/tmp/appicon.png
    [DEBUG] copying: /Users/NAME/Documents/TitaniumiPhoneSample/Resources/iphone/Default.png to /Users/NAME/Documents/TitaniumiPhoneSample/build/iphone/tmp/Default.png
    [DEBUG] compile checkpoint: 22.64 seconds
    [INFO] Executing XCode build...
    [INFO] Executing XCode Compiler [toggle output]
    [INFO] Compile completed in 5.984 seconds
    [DEBUG] executing command: /usr/bin/killall iPhone Simulator
    [INFO] Launching application in Simulator
    Unknown or unsupported SDK version: loading...
    [DEBUG] Simulator SDK Roots:
    [DEBUG] 'Simulator - iOS 3.2' (3.2)
    /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.2.sdk
    [DEBUG] 'Simulator - iOS 4.0' (4.0)
    /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.0.sdk
    [DEBUG] 'Simulator - iOS 4.1' (4.1)
    /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.1.sdk
    [DEBUG] 'Simulator - iOS 4.2' (4.2)
    /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.2.sdk
    [INFO] Launched application in Simulator (34.06 seconds)
    [INFO] Application has exited from Simulator
  4. OK, that’s bad. So maybe iOS 4.2 isn’t supported, as someone suggested. So I look in the Titanium directories listed in that post to see what mobile SDK was installed, and it seems an old (1.2.0) version was installed, while the latest version on the Appcelerator build server is 1.6. That’s probably not a good sign, which means that whatever the latest Titanium Developer installs is not really the latest and best version.
  5. So deleted everything related to Titanium, as described in that post, tried to download and install the latest Titanium mobile SDK first off the build server. Sadly I have no idea where to install it manually and don’t see anything on the developer docs about this scenario. Dead end.
  6. I don’t see any older (and thus maybe more stable) versions of Titanium Developer anywhere on the Appcelerator site, so I installed the current version again, hoping something has changed. When I launch it, now I notice a quick popup alert that a new mobile SDK is available (1.5, not 1.6, but a lot better than the 1.2 I seem to currently have). Quickly I click that link to install it (since I didn’t see it the first time, only an alert relating to an update to the Desktop SDK which I don’t care about). I walk away and it installs. When I get back, it’s apparently installed, although I didn’t see any confirmation dialog.
  7. Now I create a project again, still get the same error as above. I restart Titanium, thinking maybe it needed to reload to get the changed SDK, and now I see a new option in the SDK poplist, for 1.5! After I select it I go to the Test and Package tab and suddenly, it’s found the iOS 4.2 SDK (as well as 4.1, 4.0, and 3.2). Much better. So I launch my project with the 4.2 SDK selected, and get this error:
    [INFO] Compiling JavaScript...one moment
    [INFO] No JavaScript errors detected.
    [INFO] One moment, building ...
    [INFO] Titanium SDK version: 1.5.1
    [INFO] iPhone Device family: iphone
    [INFO] iPhone SDK version: 4.2
    [INFO] Performing full rebuild. This will take a little bit. Hold tight...
    [INFO] Skipping JS compile, running from simulator
    [INFO] Performing clean build
    [ERROR] Error: Traceback (most recent call last):
    File "/Library/Application Support/Titanium/mobilesdk/osx/1.5.1/iphone/builder.py", line 1003, in main
    execute_xcode("iphonesimulator%s" % iphone_version,["GCC_PREPROCESSOR_DEFINITIONS=__LOG__ID__=%s DEPLOYTYPE=development TI_DEVELOPMENT=1 DEBUG=1 TI_VERSION=%s" % (log_id,sdk_version)],False)
    File "/Library/Application Support/Titanium/mobilesdk/osx/1.5.1/iphone/builder.py", line 925, in execute_xcode
    output = run.run(args,False,False,o)
    File "/Library/Application Support/Titanium/mobilesdk/osx/1.5.1/iphone/run.py", line 31, in run
    sys.exit(rc)
    SystemExit: 1

    I try all the other iOS SDK versions, same result. I think, OK, maybe the project is just shot and the “clean build” it claimed to do wasn’t good enough.
  8. So I create another project (1.5 Titanium SDK) and launch it with the iOS 4.2 SDK. This one finally compiles and builds, and for the first time I am running a Titanium iPhone app in the emulator.
  9. Now that this is working, let me see if I can duplicate the Android setup experience on the Mac as well. I confirm the JRE and JDK both version 1.6 (good enough), then download the Mac version of the Android SDK and install all the same packages as I did previously on the PC. I create a new Project, then am told that Developer cannot find my Android SDK. I navigate to the directory I put it (/Libraries/) but get this error:
    Couldn't find adb or android in your SDK's "tools" directory. You may need to install a newer version of the SDK tools..
  10. Perhaps it’s the same type of error I dealt with on the PC, so I make a symlink:
    $ cd /path/to/android/sdk/tools
    $ ln -s ../platform-tools/adb

    Then restart Titanium and try to create a new project. I got the alert saying the SDK can’t be found and so browse to the same SDK directory again, but now it can find what it needs.

  11. Launch again, using the earliest Android SDK version for simplicity (1.5) and the default HVGA screen, and get this:

    [TRACE] W/PackageParser( 633): /data/app/vmdl30760.tmp (at Binary XML file line #7): Requires newer sdk version #4 (current version is #3)
    [TRACE] D/AndroidRuntime( 696): Shutting down VM
    [TRACE] D/dalvikvm( 696): DestroyJavaVM waiting for non-daemon threads to exit
    [TRACE] D/dalvikvm( 696): DestroyJavaVM shutting VM down
    [TRACE] D/dalvikvm( 696): HeapWorker thread shutting down
    [TRACE] D/dalvikvm( 696): HeapWorker thread has shut down
    [TRACE] D/jdwp ( 696): JDWP shutting down net...
    [TRACE] D/dalvikvm( 696): VM cleaning up
    [TRACE] D/dalvikvm( 696): LinearAlloc 0x0 used 627404 of 4194304 (14%)
    [ERROR] Failed installing com.onme: pkg: /data/local/tmp/app.apk
  12. Not good. OK, now try the latest Android SDK verison (2.3) and it works, I see the app running in the emulator. Hooray!

So as I said, there were a few hiccups. But now that I have a working development environment (Android on the PC and iOS+Android on the Mac), I am really excited to get going on the Titanium platform, so kudos to the Appcelerator folks for a really ambitious undertaking. I’ll be cheering for them.

Published by Rolf on 18 Dec 2010

Recovering your iTunes playlists after a computer crash

I had a computer crash recently, but thanks to Windows Backup I was able to recover Windows from a month-old system image. Since I fortunately keep all my documents and music on a separate physical drive, not C:, in the end I didn’t lose too much.

One thing I did lose, though, were the iTunes playlists I’d created in the past month, since the iTunes database is stored on the C: drive by default. Since my iPhone is still working fine, it’s just a matter of getting that information off it. Fortunately, there are steps to follow:

  1. Make sure iTunes has auto-sync disabled (on Windows, it’s under Preferences->Device). Do not plug your iPhone into your PC until after you’ve confirmed this, or it will get wiped.
  2. Follow the directions here to create a new playlist on your iPhone that simply consists of all the songs on the playlist you want to save.
  3. If you need to rescue the music files as well from your iPhone, you can use the excellent and free app SharePod to get them.

Enjoy.

Published by Rolf on 16 Dec 2010

CodeMirror syntax highlighting support for TinyMCE

The TinyMCE Javascript WYSIWYG widget has become the industry-standard plugin due to its stability and customizability. The one thing it’s missing, in my opinion, is syntax-highlighting in the code editor. A few people have tried integrating CodePress or CodeMirror into plugins but nothing has really taken off. So for now I just hacked the existing TinyMCE HTML editor to add CodeMirror support (which gives, in particular, a text wrapping option which CodePress does not). A TinyMCE developer would no doubt be able to convert this into a clean plugin, but this works for now.

Steps (the following are for TinyMCE version 3.3.9.2):

1) Hack /themes/advanced/source_editor.html in the HEAD tag to add a reference to the codemirror script, in my case to /js/codemirror/, as well as a few minor styles to make it prettier.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<title>{#advanced_dlg.code_title}</title>
	<script type="text/javascript" src="../../tiny_mce_popup.js"></script>
	<script type="text/javascript" src="js/source_editor.js"></script>
    <script type="text/javascript" src="/js/codemirror/js/codemirror.js"></script>
    <style type="text/css">
        div.CodeMirror-wrapping { background-color: #fff; border: 1px solid #ccc }
        div.CodeMirror-line-numbers {
            width: 2.2em;
            color: #aaa;
            background-color: #eee;
            text-align: right;
            padding-right: .3em;
            font-size: 10pt;
            font-family: monospace;
            padding-top: .4em;
        }
    </style>
</head>
...

2) Hack /themes/advanced/js/source_editor.js to use CodeMirror:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
tinyMCEPopup.requireLangPack();
tinyMCEPopup.onInit.add(onLoadInit);
 
var editor;
 
function saveContent() {
tinyMCEPopup.editor.setContent(editor.getCode());
tinyMCEPopup.close();
}
 
function onLoadInit() {
tinyMCEPopup.resizeToInnerSize();
 
// Remove Gecko spellchecking
if (tinymce.isGecko)
document.body.spellcheck = tinyMCEPopup.editor.getParam("gecko_spellcheck");
 
document.getElementById('htmlSource').value = tinyMCEPopup.editor.getContent({ source_view: true });
 
if (tinyMCEPopup.editor.getParam("theme_advanced_source_editor_wrap", true)) {
document.getElementById('wraped').checked = true;
}
 
resizeInputs();
 
editor = CodeMirror.fromTextArea('htmlSource', {
path: '/js/codemirror/js/',
parserfile: ["parsexml.js"],
stylesheet: "/js/codemirror/css/xmlcolors.css",
textWrapping: true,
lineNumbers: true
});
}
 
function toggleWordWrap(elm) {
editor.setTextWrapping(elm.checked);
}
 
function resizeInputs() {
 
var vp = tinyMCEPopup.dom.getViewPort(window), el;
 
el = document.getElementById('htmlSource');
 
if (el) {
el.style.width  = (vp.w - 20) + 'px';
el.style.height = (vp.h - 65) + 'px';
}
 
}

3) Copy the codemirror directory, in my case, to /js/codemirror/.

Instantiate TinyMCE as usual; now when you click the HTML button you’ll get CodeMirror HTML syntax highlighting.

Next »