I had to display the weather – specifically a 5-day forecast – in an app I’m working on here at the college. Instead of rolling my own, I went looking to see if anyone had already done this. The only code I found for Titanium was GWeather (by Bob Sims). This uses Google weather, however, Google has recently pulled their weather API for developers, which essentially means, I’m going to have to roll my own. I was on a quest for another weather service and looked at many different APIs that were available. I settled on Yahoo Weather, they have a json feed, and its super simple, just swap in the zipcode in the url and you have your feed. Granted its not as robust as Google’s once was, but all I really wanted was a 5 day forecast and this had it.
I figured from the outset that I would build a tutorial around this (eventually) and especially share the code, so I commented like crazy as I went. That also meant that I would have to build a self contained app that pulled and displayed the weather. I also wanted to implement whatever I came up with into the app for the college easily (remember the original purpose for this?), so that’s what I did.
TiWeather is a full working app (on iOS, haven’t debugged pull to refresh for Android yet – initial app works fine), and it had a hard coded zipcode (changeable in app.js, or pass it in from elsewhere in your own app). Using that, it hits Yahoo’s API and pulls back the current conditions and 5-day forecast in nicely structured JSON. While JSON is simple to parse in Titanium – JSON.parse(this.responseText) – I had a good ‘ol time splitting up the individual data elements the way I wanted (see details of this in FirstView.js around line 55) when I render them to the screen. Anyway, after the JSON is parsed, I save the data in a table on the device for caching purposes which also double for offline usage. I also keep track of the last time weather was fetched, so if you close and open the app or navigate around to other fictional areas of the app, it won’t go pull it again right away. This time limit is currently 900 seconds (15 minutes) and also configurable from within app.js.
Included Features / Cool Stuff?
Since I knew other developers would be looking and critiquing my code, I figured I could throw out some cool features to distract them from comparing my code to theirs.
- Since the weather feed didn’t change all that often while I was testing code, it was near impossible to tell if the refresh function was actually working, other than a small timestamp in the feed itself. So I have some code in the app that alternates between 2 zipcodes each time you refresh. Obviously you wouldn’t have this in your app, but I needed a way to prove it was doing what I was expecting. I alternate between 17019 -Dillsburg, PA where I live and 14424 – Canandaigua, NY – where I grew up. I figured the weather in those two locations were different enough you can see the screens change. This block of code is located in FirstView.js around line 300.
- I think the refresh circle arrow icons are a thing of the past, so I’ve implemented ‘Pull To Refresh’ which is what most apps do now anyway. I have some logging that happens, so if you have Titanium Studio visible when you run the app, you can see it working when you refresh. After a second or two the display updates, in this case, the weather for the alternate zipcode displays.
What do I hope you get out of it?
I hope this code can be of use, whether in whole – to actually pull a weather feed, or as an academic example on how to fetch some JSON from a server somewhere. The major bits of functionality you can hack out are -
- storing a variable in the device properties
- display a spinner and message while loading data
- pulling and parsing a JSON feed
- saving data to a local database
- pulling data from a database
- some interesting use of .split to pull apart data elements
- table row construction with various pieces per row
- implementation of pull to refresh (which totally kicks-ass) including a hidden pull message and rotating arrow
- refresh a tableView with completely new data
- a good laugh at some probably really stupid things I did
Other tid bits of note
This was built with the Single Window Titianium Studio template, so the display code is located in /ui/common/FirstView.js Also in that common directory is my first ‘fetch-every-time-the-page-loads-version’ (json_parse_FirstView.js), as well as the save-to-database version before I had the pull to refresh (json_pulled_from_database_FirstView.js). Both are documented and I left them there so hopefully they’ll be use to someone, and so you can hack up the code easily.
The meat and potatoes (or salad of you’re a vegetarian) is contained in getWeather.js located in the root of Resources. Here you’ll see the code that checks to see if an update is needed, pulls and parses the feed, saves it to the database, yada, yada, yada.
Feel free to send me comments, questions and any changes you think would make it rock. Its not AppStore bound, however, it can still be a cool demo app… my personal kitchen sink.