Skypanther® Studios » Skypanther® Studioshttp://skypanther.com
Empowering a mobile worldMon, 16 Dec 2013 13:42:50 +0000en-UShourly1Easy Genymotion builds with Ti 3.2 RChttp://skypanther.com/2013/12/easy-genymotion-builds-with-ti-3-2-rc/
http://skypanther.com/2013/12/easy-genymotion-builds-with-ti-3-2-rc/#commentsThu, 12 Dec 2013 16:51:52 +0000http://skypanther.com/?p=117Update:An hour or so after I posted this, Appcelerator posted an entry on their Developer’s Blog describing how to use Genymotion with the 3.2 CLI. I encourage you to check out that official solution. — Tim

I’ve started using the blazing-fast Genymotion emulator for my Android development. Unfortunately, the Titanium/Appcelerator tooling doesn’t support directly installing builds to your Genymotion emulator. That will come with a future version of the tooling. Till then, you have to resort to some command-line operations.

Perhaps you read Fokke Zandbergen’s article about using the Genymotion emulator. In it, he states you can use the following commands to build your (Alloy) project then install it to your running Genymotion emulator:

ti build -p android -b
adb install -r build/android/bin/app.apk

I used these commands so often, I created an alias, which worked great. By adding the following to my .bash_profile file, all I had to do was type genny (in my app’s directory) to build and install the app.

The problem is that the RC builds (and presumably the final build) of Titanium 3.2 no longer builds a file called app.apk. It now names that file after your app’s name. That breaks my alias. Fortunately, bash supports functions. Here’s how I updated my .bash_profile file:

The ${PWD##*/} within that function will be replaced by the name of your current directory, which is typically matches your app’s name. Now, I can again simply type genny and it will build and install my app!

To wrap this all into a set of steps you can follow, enter these commands at your OS X terminal:

cd ~
touch .bash_profile
open .bash_profile

Paste in the function and alias statement above, save your changes, then open a new terminal window. You should be all set.

(Credit to http://stackoverflow.com/a/4060984 for the bash function solution.)

]]>http://skypanther.com/2013/12/easy-genymotion-builds-with-ti-3-2-rc/feed/0Custom app names in Android projectshttp://skypanther.com/2013/11/custom-app-names-in-android-projects/
http://skypanther.com/2013/11/custom-app-names-in-android-projects/#commentsMon, 18 Nov 2013 13:19:02 +0000http://skypanther.com/?p=109A few weeks back, I showed how you can tweak the name of your Titanium iOS app. By using the internationalization (i18n) feature of Titanium, I was able to configure an app named TestApp to show on the home screen as “My Cool App”.

We can do the same thing for a Titanium Android app, however the process is a little different. To modify the app’s name, we’ll have to use the native Android strings files instead of Titanium’s i18n files. We’ll also need to tweak the manifest, which means a bit of XML tweaking in the tiapp.xml file.

Let me lay out the steps we’ll take first, then I’ll go through them in more detail:

Build your app for Android once to create the stock AndroidManifest.xml file.

Copy values from the stock AndroidManifest.xml to tiapp.xml.

Edit the tiapp.xml to enable the native strings.

Step 1: Create the strings file

Start by creating the folder structure: in your project’s directory, create the platform/android/res folders and then inside, create a folder denoting the target language. For example, for US English, the folder would be values-en. Inside that folder, we’ll need to create the native strings file. You can use the app.xml file you created for iOS but you’ll need to rename it to strings.xml. If you haven’t created the iOS version, see the past blog post for the file’s XML structure.

Step 2: Build your app

We’ll need entries from the generated AndroidManifest.xml file. To get those, you’ll need to build your app once. There’s no sense in installing the app yet. At the command-line, from within your project’s folder, issue this command:

ti build -p android -b

That will generate the /build/android/AndroidManifest.xml file. Open that file in a text editor (like Studio).

Step 3. Update the tiapp.xml

Open tiapp.xml in Studio and switch to the XML view. Locate the <android> tag and remove the “/” from the end of it. Add a closing </android> tag.

Next, from the generated AndroidManifest.xml file, copy the entire <manifest>...</manifest> block of tags. Paste them into the tiapp.xml between the opening and closing <android> tags.

Step 4. Enable the native string

Finally, we need to tweak the code you just pasted into the tiapp.xml. You need to replace the hard-coded app name with @string/appname, which is a “variable reference” to the string’s value in your language file. Most likely, you’ll find multiple references to your app’s name throughout the activities of your app. Make sure you change all the references.

Finally, you need to build and install your app. You can do so from Studio. Or, if you’re using the speedy new Genymotion Android emulator like me, issue these two commands:

ti build -p android -b
adb install -r build/android/bin/app.apk

]]>http://skypanther.com/2013/11/custom-app-names-in-android-projects/feed/0Working with databases created by the iOS Simulatorhttp://skypanther.com/2013/11/working-with-databases-created-by-the-ios-simulator/
http://skypanther.com/2013/11/working-with-databases-created-by-the-ios-simulator/#commentsTue, 12 Nov 2013 13:24:27 +0000http://skypanther.com/?p=104Quick post for today, but a tip I find indispensable. When working with a database-driven app, I often find the need to directly access the database — to confirm that queries worked, to examine the data that was inserted, to tweak records for testing purposes, etc. To do this, we have to find the database.

The iOS simulator creates a series of folders buried deep inside the Library/Application Support/iPhone Simulator folder. In there, you’ll find a confusing list of simulator versions and app GUID folders. One of those holds your app and its database. Which one? You could hunt & peck till you find it. Or, use Simulator Folders from Nimbleworks.

This cool tool hangs in your Mac’s menu bar. Click it, select the simulator version and app, and click Go. It opens a Finder window to that app’s folder. Then, simply open the Library, Private Documents folder to find your database file.

You’ll need a SQLite-compatible database management tool. There are many. Personally, I use the sqlite-manager extension for Firefox. It works, though it has some quirks and will hang occasionally (forcing you to Force Close Firefox). Another limitation with that utility is that I can’t simply double-click the database file to open sqlite-manager.

Instead, with the extension open open, I click its open button. Then, I bring my Finder window forward and drag and drop the Private Documents folder onto the sqlite-manager’s open dialog box. That redirects it to the correct folder. You’ll have to select All Files from the Format drop down before you can select and open the database file. It sounds like a lot of steps, but once you get the hang of it you’ll perform them in no time.

When you create a new Titanium Mobile project, you cannot enter spaces in the name. Renaming Titanium projects is possible, though a bit tricky. There’s an easier way to solve these problems: internationalization.

You would typically internationalize the name of the app to target multiple languages. The Titanium guide on internationalization gives just such an example. But you can also use the i18n features to modify your app’s name.

Internationalizing an app’s name (click to enlarge)

In the example above, check out the project name: TestApp. This would be the app’s name if I didn’t take the next steps. That is, I created the i18n/en directories with the app.xml within. In that file, I added the XML code you see above. I cleaned the project and built it. The result is that on my home screen, my app is called My Cool App.

What about on the app store?

An app’s name in the app store doesn’t come from your project or i18n files. Instead, you specify the name for your app when you create your app’s entry in the iTunesConnect portal. In fact, choosing the right name can help your SEO.

Users on mobile devices will see up to 32 characters when browsing the App Store (desktop users see more). Be descriptive and be sure to say what your app does. Make sure, though, that the app store name and the name shown on the user’s home screen are close so they don’t forget which app is yours!

]]>http://skypanther.com/2013/09/ios-app-names-in-titanium-projects/feed/0Breakpoint debugging an Alloy apphttp://skypanther.com/2013/02/breakpoint-debugging-an-alloy-app/
http://skypanther.com/2013/02/breakpoint-debugging-an-alloy-app/#commentsThu, 28 Feb 2013 21:23:44 +0000http://skypanther.com/?p=83Today’s tip came out of a chat I had with the brilliant Aaron Saunders (@aaronksaunders). Thanks Aaron!

First, a little backstory. Appcelerator’s new Alloy framework provides an MVC-like development architecture for your Titanium mobile app development projects. In essence, Alloy is a preprocessor. You create views (in XML and CSS-like files), controllers, and models, which are all parsed and processed when you build your app. During the build process, the Alloy preprocessor creates the kind of “traditional” Titanium code you might have written in the past. That generated code is what ends up running inside your app.

The lines on which you set your breakpoint (in the source Alloy files) don’t correspond to the actual Titanium JavaScript that ultimately runs within your app. And without jumping through enormous hoops, you can’t set breakpoints in the generated code and run that code. In my testing, setting a breakpoint on an Alloy source file results in the debugger stepping line by line through your entire app’s code. Not very helpful.

Cue Aaron’s tip. You can add a statement to your code that will be treated like a breakpoint. Here’s an example:

With that debugger statement in your code, do a debug build. Click this button:

Your app will compile and load into the simulator/emulator. When you click a row in the table, the debugger statement will be hit, the app will stop and the Studio debugger view will be activated. From there, you’ll have access to all the normal breakpoint debugging features offered by Studio. Key point: the correct line in the source file is highlighted! Breakpoint debugging is back with Alloy.

]]>http://skypanther.com/2013/02/breakpoint-debugging-an-alloy-app/feed/0Titanium graphs with a WebViewhttp://skypanther.com/2013/02/titanium-graphs-with-a-webview/
http://skypanther.com/2013/02/titanium-graphs-with-a-webview/#commentsFri, 15 Feb 2013 14:27:34 +0000http://skypanther.com/?p=73Got data to graph in Titanium? On its own, Ti doesn’t provide a graphing component. There is an iOS-only module in the Marketplace. But if you also need to support Android or want other graph types, you’re out of luck.

Fortunately, we can use the WebView, a suitable HTML graphing library, and some app-level events to rig up live graphs in our Titanium apps. The example shown here isn’t super-pretty, but it demonstrates the basic concept.

Let’s get started. First we’ll need a graphing library. Older versions of the Android browser don’t support the Canvas element. You’re probably wise to steer clear of the many Canvas-based graphing libraries (even though many of them offer stunning graphs). Instead, you’ll want to use something like flot, jqPlot, or Sparklines.

The example I’m showing here uses jqPlot. For my example, we have three TextFields in a Titanium native view. The graph is in a local HTML page loaded in a WebView. Clicking the Update button uses an app-level event to pass the fields’ data to the WebView, where local JavaScript on the page updates the graph. I’m going to assume you know the Titanium basics for creating those fields and views.

WebViews in Titanium have no direct access to the Titanium API. And the reverse is generally true. Titanium native components don’t have direct access to objects or variables defined in a WebView. We’ll use Titanium App-level events to communicate between these contexts. Let’s look first at the web view controller code:

In that code, $.submit is our update button. When clicked, it calls the updateWebView() function, which fires an app-level event named updateGraph, passing in the values of the three text fields. (As an aside, the value of the third text field is calculated such that the sum of the three add up to 100. That’s just to make the pie chart lay out as you’d expect.)

Next, let’s look to the HTML code. Most of the contents of the app/assets/graph.html file are lifted straight from the jqPlot example. I’ve added an event listener in the head section, as shown here:

This code listens for that same updateGraph event. It receives the event data in the e object, then uses it to call the jqPlot replot() function. Again, most of this is taken from the jqPlot example code.

With this in place, enter numbers in the text fields, click Update, and the graph is redrawn with your new data. The illustrated code works in both iOS and Android (both 2.x and 4.x).

One last WebView tidbit. We can use the meta viewport tag to control scaling and “zoomability” of the web view. In my case, I wanted the HTML content to fill its parent container (the WebView), be zoomed to 100%, and not let the user zoom in or out. Check out the head section and you’ll see the meta tag I used:

You can grab the full code, which I wrote for the Titanium Certified Developer course, from the Appcelerator S3 bucket. It’s an Alloy-based project. So you’ll need a recent build of Titanium Studio and the 3.0.0.GA SDK. Look to the project’s app directory for the relevant code.

As a final tip, use your mobile device to determine if a graphing library is going to work for you. Open up your device’s browser and visit the library’s samples page. If their samples display on all your target devices, you can use it in a WebView in your app.

]]>http://skypanther.com/2013/02/titanium-graphs-with-a-webview/feed/0See the Mac Console for full error detailshttp://skypanther.com/2013/01/see-the-mac-console-for-full-error-details/
http://skypanther.com/2013/01/see-the-mac-console-for-full-error-details/#commentsThu, 10 Jan 2013 18:45:02 +0000http://skypanther.com/?p=56I got a (probably not so) bright idea about how to do a bulk update of my app’s database as part of a version upgrade. I could generate a SQL file containing all the statements that needed to be run by exporting from my desktop DB tool. Then I’d package the file with my app upgrade, read it from the file system, pass it to dbconn.execute() and boom, updated database. Well, not so fast. You see, I got the error you see at the right.

Unfortunately, the error message extends of the top of the screen and the Studio console messages didn’t help much either. See below.

Here’s where the difference between a simulator and emulator comes in handy. The “iOS simulator” means that your code actually runs on your OS X computer as an OS X process. We can get info and output from the simulator via the operating system’s tools. I opened up the Console (Applications, Utilities, Console) and was able to find this:

Ah, I was trying to pass multiple SQL statements in a single SQL query, something SQLite doesn’t like. I can fix that, now that I know what I’m fixing.

Back to the simulator/emulator difference, the “Android emulator” means your app code runs inside a virtual computer which is running on your desktop. You can’t use operating system tools (like Mac Console) to peek inside. You’ll have to turn to dedicated platform debugging tools. The point of the post is not that one is better/worse, just that there is a difference. (Oh, and using the Console is pretty darned handy when error messages are truncated.)

]]>http://skypanther.com/2013/01/see-the-mac-console-for-full-error-details/feed/0Split window editing in TiStudiohttp://skypanther.com/2013/01/split-window-editing-in-tistudio/
http://skypanther.com/2013/01/split-window-editing-in-tistudio/#commentsThu, 03 Jan 2013 14:36:13 +0000http://skypanther.com/?p=50Yes, you can edit the same file in two tiled windows in Titanium Studio! Today I figured out how to do this and whipped up this short tutorial video just for you.

]]>http://skypanther.com/2013/01/split-window-editing-in-tistudio/feed/0Delete a member of an arrayhttp://skypanther.com/2012/09/delete-a-member-of-an-array/
http://skypanther.com/2012/09/delete-a-member-of-an-array/#commentsWed, 19 Sep 2012 23:28:37 +0000http://skypanther.com/?p=44Here’s a quickie: Need to delete a member of an array in JavaScript? The traditional way is with the splice() method. Here’s an alternative using filter():

The filter() method examines each member of your array and applies the function you pass as its argument. In this case, our function returns the member only when it doesn’t match the value we want to remove. You could also use filter() to manipulate each array member in another way, say to multiply by some value.

]]>http://skypanther.com/2012/09/delete-a-member-of-an-array/feed/0Web site relaunchhttp://skypanther.com/2012/09/hello-world/
http://skypanther.com/2012/09/hello-world/#commentsThu, 13 Sep 2012 18:28:35 +0000http://skypanther.com/?p=1I’ve set up WordPress as part of an overall site refresh. I migrated a few of my past Tumblr posts, the ones that were worth keeping. Much of my former site’s contents are gone. Sorry for the 404s but a lot of that content has been around for so many years that it is totally worthless.
]]>http://skypanther.com/2012/09/hello-world/feed/0