When we vacationed on Curaçao in 2010 and 2014, and at times in between when i looked at the weather forecast for the island on my iPhone, i noticed one thing: the information sucked. Essentially, the app reports "it will rain" every single day, and that is it.
When we move here, i decided, i am going to fix that, and write a proper app that provides proper and accurate weather information from the local source.
So early this year, a few weeks after moving onto the island for good, i reached out to the good folks at the official Meteorological Department Curaçao (Meteo), asking whether i could have access to their data to write an app. The answer came promptly and excitedly: "We should talk!".
Talk we did, and soon we decided to collaborate together on creating not a decent weather app for the island, but the official weather app. The scope for what i had originally intended increased manifold over night, but i was excited about the project and eager to get started.
The plan became to build an app for both iOS (my intent originally) and Android, developed in several steps, with an initial app out soon, and more extended features to be added over time.
The first fruits of that labor between myself and my friend Haime over at Meteo can be seen now: Version 1.0 of Curaçao Weather, the official app for iPhone and iPad is out now, available on the iOS App Store. It's free, without in-app purchases, and without ads, and we hope you love it! The Android version is in the works, and will be out later this year, probably in the third quarter.
Tools and Architecture
Of course, i'm a developer, so i want to talk a bit about how the app was designed and created.
It goes without saying that the app is written in 100% Elements code; i chose Swift, but i could have just as easily picked Oxygene or C#. This applies to all parts: the server infrastructure (.NET based): Swift. The iOS app? Swift, of course. The Android app: also Swift. Every single line was written in Fire, my Mac IDE and day-job project.
It's been an exciting effort to do this because it gave me a bigger-than-ever chance to really dog-food not just Fire (i do that all day every day) and Swift, but also the cross-platform capabilities of Elements and Sugar. A particular challenge (for me) was the Android part: iOS i'm deeply familiar with and code in my sleep, and i know my way around .NET as well. Android is new to me, and this was (is) my first actual Android project.
Sugar has really made all the difference in being able to share a lot of code between the different parts of the app. In fact, working on this project has driven a lot of progress for Sugar over the past few months, such as improving Json support, adding TimeZone and Locale support, and more.
The application consists of three main projects (and some ancillary ones): There's of course the two core apps for (1) iOS and (2) Android. And then there's (3) a server component.
I decided early on that for this app i did not want to worry about scalability and server maintenance, so i wanted to create an architecture that required no live connection between server code and clients. I've leveraged Amazon S3, EC2 and (using that for the first time) SNS, to achieve this.
The server component is a simple console tool that does not need to run 24/7 or accept any incoming network connections. All it does is get invoked at regular intervals, and do some processing. There's an EC2 instance that (on the side) runs this tool every 15 minutes via scheduled task.
When run, the tool goes out to the servers of Meteo, grabs the most recent weather data, and packages it up in a well defined format.
Initially, the tools scrapped most data from the HTML on the Meteo website, but it has since been updated to use more official and better structured data sources, reading most data as XML files. The result of its processing is dumped into S3, into a world-readable bucket that the client apps have access to.
This way, the clients can just grab all the data via HTTP, without worrying about server uptime and scalability. S3 is has more 9s on uptime than you can count, and it's pretty hard to imagine that more people will use this app than S3 can handle ;).
Registration for Push Notifications is handled via Amazon SNS, where the client apps use Amazon's excellent client SDK that wraps that functionality. Again, the upside is that my server does not need to be running for clients to register.
As mentioned before, the server is .NET based, which means i can run it on Windows or Linux EC2 instances in the cloud (right now, it's running on one of the several Windows EC2s we have up anyways, as it adds very little load and does not warrant its own instance), and i can also run it locally on my Mac, for development purposes, and debug it right inside Fire.
The server contains some code that is only needed in the server, some of which is .NET specific (such as the code to talk to S3, or to pre-process Satellite and Radar images), some of which is not (such as the data processing, which is leveraging
Sugar.XmlDocument heavily). There's also code that's share between both the server and the clients, in a Shared Project. Chief among that are the data model classes that contain and define the various sets of weather data. There's one single set of Swift files that the server uses to populate and save as Json (then pushed to S3) and the client uses to load back from Json, after getting the files via HTTP or local caches.
Data Model code, written in Swift, and shared between .NET, iOS and Android. We truly live in the future ;)
Moving on the the client apps, there's actually three main apps: iOS, tvOS and Android (and later on there'll be watchOS as well). All three apps pull in the same Shared Project as the server does, and they also share a second Shared Project with client code.
This project contains all the application logic that needed in both (or all three) client apps: management of local data (downloading as needed, caching, etc), management of images both for radar/satellite overlay and for the dynamic photography that freshens up the app's UI, working with location data, and so forth.
This shared code is a combination of platform agnostic code (large portions of it, such as the data downloading and management), as well as some
#ifdef'ed classes that abstract various platform capabilities (such as Push Notifications, working with location and map data, etc).
Of course on top of this sits the UI, handcrafted for each platform. You'd expect nothing else from me. The iOS app is pure native UIKit. Mostly focused around table views and MapKit (which looks just stunning with embedded satellite and radar overlays), this is is a state of the art iOS user interface.
Conversely, the Android app uses Androids native XML layouts, and implementation details aside, is also designed significantly different, to fit in nicely. For example, where the iOS uses a standard tab view to switch between views, the Android app averages the "Hamburger Menu" UI more common on that platform, and so on.
As an additional level of abstraction, the whole client app code is written without knowing anything about "Curaçao", except for one partial
RegionMetaData class that injects region-specific information (such as what map rectangle to show per default, what timezone to use for "local" data, and what URL to get data at, etc). This keeps the app open so that, in theory, 99% of the code base could be reused for a different island or region.
Having the intermediate server that processes the data into Json files that the apps get from S3, opposed to the apps getting data direct from the source, greatly helps with being flexible to adjust for data changes without needing to update the app. For example, during the development process, different sources got switched over from HTML scraping to processing more official XML files, piecemeal. This could all be handled just by updating the server, and the client apps on testers devices were not affected. The same remains true if data formats at the source should change in the future.
Get it now!
As mentioned above, Version 1.0 of the iOS app is available on the App Store now, for free. It works on iPhone and iPad. A (for now very simple) Apple TV companion app is finished as well, and should be out soon (i'm fighting with iTunes Connect to not crash on submission, on Apple's side ;).
I'm now fully diving into fishing the Android app, which we hope to have available in Q3. I'm already making great progress, and am amazed now much functionality i already wrote for iOS use falls into place, thanx to Sugar!
And then there's additional functionality we want to add, such as the ability for users to report weather conditions via in-app feedback, and more, in the future.
As a final note, the app is published under the banner of Warsaw/Willemstad, a new company i am in the process of co-founding with my friend and colleague Dana. W/W will focus on building sophisticated mobile solutions for its clients and for itself, based on RemObjects and AWS technologies. Essentially, it will be an outlet for those who want apps like Curaçao Weather built for them.