Building an iBeacon-based app

I spent a big chunk of my free time in the last couple of months to build an iOS app. The app’s primary feature is to connect with people who are in your close (close as in Bluetooth) range. Here’s what I’ve learned in the process.

Handling permissions – your users will see lots of dialogs

Running anything in the background in iOS is painful. From Apple’s point of view this is perfectly reasonable – they don’t want you to drain their devices’ precious battery. On the other hand the UX is terrible. You’ll only get one shot to convince your users to give you the desired permission. If they don’t do it then comes the “leave the app and change the settings” scenario. Instant churn.

The Location Services background permission is a special case. Apple will constantly ask the user in random intervals if they are aware that your app does location scans in the background. This can quickly lead your users to disable it as it was some kind of malware.

Then there are some badly worded system dialogs – my favorite is the “Turn on Bluetooth” dialog which has two buttons: OK and Settings. You’d assume that the OK button would turn on Bluetooth but it just closes the dialog. It’s really nice since users generally don’t read these at all, just bluntly hit OK and expect the problem to go away.

The background settings are brittle at best. There’s an app level permission, and there’s a permission for the whole system (parental lock excluded). It again makes sense from the user’s side, but from the app’s side it’s disastrous. The API calls will just return that there’s no required permission to run, but they won’t tell you why. It’s quite hard to guide the user through the problem if you don’t know the cause.

BLE is special

In a bad way. First there’s no way to tell if the device Bluetooth is turned off, or is not supported at all (aka iPhone 4). Now I lied, you can deduce this with checking various constants, but if you’d like to do this cleanly using the API you’re doomed.

Then there’s the plist fun when you need to add the keys to support background Bluetooth running. You can also have a lot of fun with events not firing, or firing with a huge (40 secs) of latency. In a real time app like mine, this is a huge deal.

Broadcasting iBeacons in the background – confusion overload

The short answer is that it’s impossible. You will only be able to broadcast iBeacons when your app is in the foreground. The problem is that there are tons of resources (mostly stackoverflow users in despair) who claim otherwise or offer creative ways around the problem. But nothing works. What works is a UX which rewards the user for opening and engaging with the app. Forget everything else.

Background Bluetooth scanning – even more confusion

Ranging or geofencing (region entering and leaving)? What constitutes a region? What can I do in the background?

I was really confused at first. Region entering can run in the background, but with a limited set of regions (I remember 20 for the whole device). Ranging cannot run when you’re in the background. The problem is when you use iBeacons you’d like to identify them (major/minor anyone?). Region entering won’t do this for you, you’ll need ranging.

But a little creativity goes a long way. Entering a region will wake up your app and you’ll have 5 seconds to do what you need. Now you can use these 5 seconds for ranging, since you’re not in the background anymore. Problem solved.

So what’s the conclusion?

If I were to start again this app I’d do it on Android. I finished it because the emotional investment was huge. On iOS you’d get seriously hindered functionality when you try to be creative with iBeacons. They seem to be a perfect fit for indoor navigation but when you try to do something different you’d hit into way too much barriers.

Oh, the app is waiting for review right now. I’m very interested to see if Apple approves it. I’ll post about it when it’s done.

Mobile event viewer: User Interface

This is the second post of a series of tutorials for creating an event viewer for iOS. You can find the first post, which deals with basic architecture an network connections, here.

There’s also an accompanying Github project.

This post will be about the user interface. Since no built-in control exist for mimicking the calendar day view in iOS (neither in Android) and I’m not very great drawing controls, I started checking for open source implementations. There’s a very easy to use project on Github by muhku, called calendar-ui.

What we need from it is the MADayView class, along with MAEvent. MADayView, as the name suggests provides a view which renders the calendar day view. It has a delegate and a datasource property. In my example, I rigged both, but only used the datasource. Here’s how I set up the view.

EventListViewController.h changed a little:

As you can see, I imported MADayView.h, and added its datasource and delegate protocols to the header. I also added an IBOutlet for MADayView, and connected it to its counterpart in EventListViewController.xib. Basically the UITableView implementation was replaced to an MADayView implementation. In EventListViewController.m there are some changes too:

The main change here is that instead of UITableView I use MADayView. Its datasource protocol is very easy to satisfy, only a method with the signature: (NSArray*)dayView:(MADayView*)dayView eventsForDate:(NSDate*)startDate needs to be implemented.

This method unfortunately needs to return an array of MAEvent objects. I like to separate third party code from my, so I created a mapper which maps my own Event class to an MAEvent (a variant of the Adapter pattern). This way, if the very unlikely day would come when I want to change the UI in this tutorial, I could do with minimal changes. There are also two callback methods from MADayView which I put in there for paging: nextDate and previousDate. These should be the part of the delegate protocol, but I was sloppy and just use two selectors for the effect.

What may be interesting in these methods are the [actualDate yesterday] and [actualDate tomorrow] calls. These are implemented in a category on NSDate. The code looks like the following:

It simply uses NSDateComponents to increment or decrement the date on which it’s called (thus working with daylight saving times, leap years, etc.).

In the following post, I’ll show how to scroll between days to implement a truly native experience.

Mobile event viewer: basic architecture and retrieving events

This is the first post of a series of tutorials for creating an event viewer for iOS and Android. In this post, we’ll examine the high-level application architecture. The project is located at https://github.com/gergelykoncz/Events.iOS.

The objective of the app is to display events in a view similar to the built-in daily calendar view. Since there are no public APIs for this neither on iOS nor on Android, we’ll roll out our own solutions, but first let’s plan the application.

We’ll work with only one entity (for now), which I decided to call Event. The event class looks like this:

As you can see, it has an identifier, a start and end date, a summary, a description, and a flag indicating if it’s an all day event. Nothing particularly difficult.

Events will come from a web service in JSON format, but it’s an implementation detail. I don’t really care where they come from at this point, but I’ve a firm belief that every class should do one and only one thing (the Single Responsibility Principle), so there should be a class that I can call and it gives me back some events. This is in fact an already named pattern, called Repository. Thus I created a class named EventRepository, which will serve my events whatever way it finds best.

Note: I don’t want to get too enterprisey at this point, but if we’d have more sources for our events, then we could create some more repositories (one for each source, with a common interface/base class), and use a Facade as a coordinator class which would delegate the event retrieval for based on whatever logic we find best.

So let’s review this EventRepository. As I stated before, the events come from a web service, in JSON format. Since it uses the network and this can (and will) introduce so much delay that our app would be very unresponsive if we would want to wait until data is loaded (if it’ll be loaded at all). That’s why I use NSURLConnection in an asynchronous fashion. When someone calls EventRepository to load the dates, it builds an NSURLConnection, set its delegate to itself and fires the request. After this the main thread is free to do whatever meaningful work instead of waiting for the request to complete.

There are two common cases at this point: the request fails, or it succeeds. In both cases we should notify the caller, but first let’s see the cases in detail.

If the request succeeds, we parse the result as JSON, using the NSJSONSerialization class. Since our API returns an array of events, we iterate over each JSON object in the array, and create an instance of Event using a different class, EventMapper. As its name suggests, EventMapper is a mapper. You can find this concept under many names (here is a discussion on the topic, and here’s a recent post of mine regarding mappers), the gist of it is that it is a class that it builds entities based on some input.

After we have our collection of events, we simply notify the caller through a delegate. If anything goes wrong, we use the same delegate as well. There are multiple ways of doing this, we could have used the NSNotificationCenter, but the Cocoa framework uses the Delegation pattern more extensively, and I got very used to it. The concept is exactly the same as with EventRepository and NSURLConnection. EventRepository simply delegates the task of retrieving events to NSURLConnection, and provides a way (in this case, a reference) to NSURLConnection to notify it when it’s done.

EventRepository offers this thing in its loadEventsForDate method. It accepts a date, naturally, and a delegate object which it’ll notify if it has a result (or any error occurs in the process).

Here’s the protocol (EventsDelegate) that is being used:

And we’re almost done! There’s a final piece without our work does nothing: we need a ViewController. And our ViewController has to implement the EventsDelegate so that it can be notified by EventRepository. The example class EventListViewController is for demonstration purposes only. It won’t render our shiny events in the promised daily calendar view format (that is the topic of an upcoming post), rather it uses a mere UITableView. Here is the source:

As you can see, by using the right patterns and careful delegation, we ended up with a short and maintainable view controller. In fact, less than ten lines (blanks included) are responsible for loading events and  reporting errors. Most of the class deals with the UITableView delegates.

I hope that I managed to emphasize how clean your design can become when you use the appropriate patterns and concepts. I think that by creating smaller classes with only truly one goal you can end up with a more maintainable (and thus, cost-effective) codebase. Of course there are some vital functions missing here, like error handling and logging, but I tried to make the examples more concise.

But don’t forget that the point of this is not the admiration of patterns and best practices, but to make an app that works. I’ll follow up this post (and the GitHub project) when I implemented the view I promised.

Tutorial: creating a mobile event viewer

Before I moved to the Czech Republic I did some freelancing. One of my project was an event viewer for iOS and Android. It was like the daily view of the respective system’s calendar with data from web services in its own application. Now the work was done but the customer vanished, so I ended up with these two applications. I thought they would be worth sharing and I intend to create a set of blog posts as a tutorial for them. However, I can’t just push them to GitHub, there are lots of client-specific stuff in it, and tons of anonymization need to be done.

Long story short, I decided to rewrite the whole stuff to avoid any leakage. The iOS version can be found at https://github.com/gergelykoncz/Events.iOS. It’s just a stub yet, but I plan to evolve it with and adding further posts. The first is coming soon.