Connectico iPhone Voice Over IP App26 July 2015
Posted by : Gareth Shapiro
Connectico is a voice over IP (VOIP) iOS app. The thing that makes it different from similar well knowns apps, which provide functionality such as calling other people in your address book and displaying a list of recent calls, is that you can easily rent local numbers in many international markets and use them immediately. Managing local numbers overseas is seamless and all done from inside the app. This means people can call you on a number local to them and the call gets routed to the app on your iPhone and the same in reverse, you can choose a number based almost anywhere in the word to call from, all from within the app.
Specific telephony functionality is supplied by two static linked libraries supplied by a third party developer which provide C and Objective-C wrappers around the ubiquitous PJSIP library. For most of the project I did not have much to do with these apart from a few sit down talks squaring up to XCode to ensure everything compiled across all of the chip sets.
Towards the end of the project I extended the C library, which is not a core skill of mine, but I was able to add mute / unmute functionality and DTMF tones, which are the sounds you hear when you are navigating a menu on your phone.
Voice over IP apps have unique background status on iOS allowing them to execute more code while they are in the background than other apps. This requires some work and a strategy to keep the connection alive with the server is needed while the app is not being used. Once this is in place NSLocalNotifications are used to make the phone ring when a call is received and the user is not activity using the app.
Getting more from StoreKit
In addition to purchasing numbers from within the app users can purchase call credit. Naturally this In App Purchase functionality was executed using StoreKit framework with the products added to iTunes Connect. The UX for In App Purchases within Connectico can be interrupted and automatically continued, for instance should the user encounter a network failure, which is an improvement on standard StoreKit functionality which requires the app to be restarted.
In terms of the basic architecture, data is supplied from a REST API using AFNetworking and locally via CoreData or the user's Address Book. I used two CoreData tools QueryKit and Mogenerator to cut down on the query and boiler plate CoreData code.
Make peace with the server guys
As usual one of the first tasks at the beginning of mobile application production is to stub out local versions of the API which can be used by OHTTPStubs to mimic JSON responses from the backend. This allows iOS development to be decoupled from the server while the API spec is been designed and the backend developers are working on the server. This is a massive productivity gain as it side steps potential bottlenecks and timeline dependancies between the front and back end. A second, and no less important, advantage to working this way is backend failures can be tested in a systematic way again without even engaging the backend team.
Views were created with Autolayout in Interface Builder and some UIViewControllers have further code based NSLayoutConstraints. For the most part the Views are based on UITableView and the Key Pad View, think phone dialler, is the most customised. As this is reused in a few situations, and everything works across 4s/5/6/6+ devices I first attempted creating it with CoreGraphics but programmed NSLayoutConstraints won out in the end.
Tricks of the trade
Application architecture and navigation logic is provided by my own view stack utility, SimpleIOSViewStack - which I am currently converting to Swift. This utility promotes a much more decoupled MVC architecture than iOS apps often tend to have and allows fantastic flexibility to be realised very easily.
All the app text is delivered by a localisable string file making it trivial to convert to another language.
This project involved some unique information architecture in that telephone numbers can be delivered, like any user generated content, in wide variety of formats. It can be quite tricky to match up a number in a local address book with an an incoming number when they have been formatted differently. Using a combination of UX and application architecture Connectico copes more gracefully than many similar applications.
The philosophy with this app is that much complexity is hidden away from the user and for the most part things "just work". It did mean more planning and development work but the value delivered was obvious and ultimately the whole process, which took 3 months, was largely stress free and very rewarding.
Other tools used : Testflight, Crashlytics, Basecamp, BitBucket, Git.