I’ve been asked a couple of times about how to track an adobe AIR application you’ve developed without disclosing personal information or requiring user interaction.
My answer to this is always the same: I usually store a randomly generated key in the SQLite database when the application is first run.
I’ve decided to upload some code to demonstrate *my* approach to synchronous database connections in Adobe AIR. The version of the code provided is a bit stripped down from what I usually use (my main code provides for both synchronous and asynchronous connectivity but I stripped a lot out for this example and will provide a seperate example for asynch at some point int he future.)
To reiterate: This code may be overkill for some people and uses my custom namespaces.
Now that I’ve got that out of the way:
Download: SQLiteExample.air OR SQLiteExample.zip
License: Creative Commons Attribution 3.0 United States License (Please keep or attribute name in code comments etc.)
Quick and dirty explanation:
Since this is a lightweight application I use my trusty airDB javascript namespace. airDB is just a wrapper I wrote to simplify synchronous SQLite connections to the air database. Three main methods are really all you need to understand to get started (see code as well method list below). Those are airDB.init(), airDB.fetchRS and airDB.execute. If you’re just looking for an explanation of how to connect / work with a SQLite database in AIR read the documentation here or check out my source file ns.airDB.js (I’ve heavily commented it hopefully to help explain things but frankly I’m bad at that so the official Adobe help is probably the way to go).
Within the startup method in the index.html file you’ll find that I’m calling airDB.init with an object passed in.
// initiate db connection / test schema etc
// see init in ns.airDB.js for more information
airDB.init({
databaseName: 'example.db', // name of our database
fetchJSArray: 1, // force fetchRS to return a javascript array
openImmediately: 1, // open the database on init
testSchema: 1, // test the database on init
traceLog: 1 // verbose log to air.trace
});
A little information about ns.airDB.js:
- airDB.init (options)
- performs initial setup of connection variables needed to access the SQLite database in synchronous modeSee the init method for default options and their use
- Returns: null
- airDB.open()
- opens the database connection. Requires that airDB.init has specified a filename to connect to
- [Optional]; can be called directly from init if openImmediately is passed in as 1.
- Returns: null
- airDB.close()
- closes the database connection
- Returns: null
- airDB.test(forceFail)
- performs a basic schema test to see if the database is setup. (set forceFail = true to recreate the database regardless of test results).
- Note: This method should be rewritten to each specific application as schema will vary per application. The provided one is super simple for examples sake.
- [Optional]: can be called directly from init if testSchema is passed in as 1.
- Returns: null
- airDB.connected
- Returns: boolean (whether connection is present or not)
- airDB.fetchRS(sqlStatement)
- airDB.execute(sqlStatement)
- executes a sql statement (insert / update / delete / drop etc.)
- Returns: null
- airDB.sqlText(string)
- replaces any single quotes in a string with double quotes
- Returns: string
- airDB.sqlNumber(number)
- ensures that a number passed in is numeric / ok to execute in a sql statement
- Returns: number (returns 0 if number is not numeric)
After init in the “startup” function I call airKey.init airKey is a javascript namespace solely created for generating a random string of however many characters you wish and storing that in the local database. I won’t go into too much detail here because it’s super easy to understand (generate a key if one isn’t present and store it in the database, if one is already present, retrieve it.) (see ns.airKey.js)
I then call a custom function called “getNames()”. getNames is just an example of how to call a select statement and use the custom JS array to output data. In the example provided I fetch the column names as well as the values to generate the table of “names” within the main air window. When looking at the function you might ask why I’m using a custom javascript recorset that fetchRS returns rather than the standard flash.data object. 1 : my custom object returns the number of rows as a static int, so that I never have to calculate that. 2 : I also don’t want to pass flash objects around because it’s caused memory leaks for me in the past that were a pain. (However if that’s your thing, remember you can just set fetchJSArray = 0 (or not pass in that option at all) in init to just use standard access methods. (I do this for large databases because transforming the data on large recordsets is a bad idea)
Other than that, this example is pretty basic. Adding a name using airDB.execute as well as rebuilding the database from scratch is included in the example.
Finally: a bit more about airKey. by storing a random string I can test against that when the application performs URLRequests against an owned web service. This lets me generate reports (or turn off a particular app) without having to be too intrusive to the user. To make this more robust I highly recommend using the local Encrypted Store available to you in AIR applications. (If you’re worried about piracy of your application the encrypted store will help a little but frankly right now AIR is not the platform (for HTML/JS applications) to use if that’s your concern as source code is freely available to the user.)
If you have any questions feel free to ask in the comments and I’ll answer.