iOS Region Monitoring and Location Manager

One interesting feature in the new version of Watch Over Me app is Crime Zone. The main purpose of the crime zones is to notify the user of Watch Over me when he/she is passing the area. Watch Over Me app will ask if the user wants to be watched over during that time.

We have accumulated some trustable and reliable resources from various websites from the Internet to gather the crime zone areas in 7 major cities in 5 different countries (Malaysia, USA, UK, Australia, Thailand). These 7 cities are our test regions and we will be adding more regions in the future.

iOS Region Monitoring and Location Manager

I am using Region Monitoring from the Location Manager to implement this feature on the iOS Watch Over Me app. This particular module is not hard compare with getting the location in iOS 7 in background mode.

The maximum regions that an iOS device can monitor is only limited to 20. So, I have to come out with a good strategy to only get and monitor the regions that are useful to the users.

This is the logic we use for the region monitoring in iOS:-
1. Getting the current location from the user.
2. Send the current location to the server.
3. The server will return all the regions within a 20 km radius from the current location
4. If there are more than 20 regions, the server will only send the closest 20 regions from the current location.
5. After receiving the regions, the app will start to monitor the regions.

A Potential Bug for locationManager delegate method didEnterRegion

After the app has been released on the app store, we are still constantly in testing on the region monitoring on Kuala Lumpur (KL). We have 8 monitored regions in KL at the time of typing this article.

On one fine day, my colleague saw a bug with multiple region notifications triggered at the same time. The location of my colleague is at least 3000 meters away from the nearest region that we monitored. I have double checked on the radius and also the coordinate for all the regions that we monitor in KL, there wasn’t any discrepancy of the data.

Region Monitoring Bug
iOS Region Monitoring Bug
Region MonitoringiOS Region Monitoring


The screen on the Left shows the bug when 4 notifications triggered at the same time when the device is NOT even close to any of the regions.

The screen on the Right is a simple app that I made to stimulate the location of the device (Green Marker) and also the location (Red Marker) and the radius of each region (Red Circle). The Blue Circle is the estimation of the radius of the device when it triggered the notification for all 4 regions. The estimated radius for the device is about 4700 meters! It should not happen.

I have searched through various websites (StackOverFlow, Apple Developer Forum and etc.), I couldn’t find other developer faced the same issue like mine. I saw a lot of questions on NOT getting any notification when passing through a region, but my case is the entire opposite.

I am not sure if this is the fault on my code, on iOS system level or the problem on the local Telco in my country. I have posted a question on StackOverFlow for more than 1 week but I didn’t get any answer as well.

How to Fix this Bug?

Without much reliable information, I can only do trial and error in order to fix this bug. I have been trying a few different method on trying to fix the bug. This includes setting the distanceFilter = 10 for the locationManager. Previously, it was kCLDistanceFilterNone because I want the app to detect every single movement.

My colleague still saw this bug after a few days of testing. So, the above solution is no good.

After experimenting for sometimes, I found a solution that works good.

1. Whenever a user enters a monitored region, he/she will get a notification in the locationManager delegate method didEnterRegion. But due to the bug, this method is not reliable. I have to use a smart way to filter out the fake location.
2. I found a way to get the recent location of the user from locationManager.
3. After the app gets the user location, the app will make sure that the location is within the region before deciding to send the location notification to the device.

From my research, this location is not 100% reliable, especially if there isn’t any location based running at the background. But generally, it is good enough to filter out the bad location which may trigger multiple notifications for different regions.

Here are the example code:

Learning Unit Testing in XCode 5

I have been delaying in learning Unit Testing ever since the released of XCode 5 on September 2013. It is partly due to my busy schedule in rushing 2 complex projects back to back. Now the Second project – Watch Over Me 3.0 is under the beta testing stage, so, I have some time to pick up some skills that I have been wanting to learn.

What is Unit Testing?

Unit Testing is part of Agile Software Development Methodology to make the entire software development process more efficient, the development project to be easier to maintain, less crashes on deployed software and higher quality of code.

Automatic Unit testing, on the other hand, is a proactive way to test a small unit of codes (functions, classes) from time to time to make sure that they are always ready for production. You can host a test server (eg: OS X Server) together with Git repository server. On the test server, some bots will test the latest commits of the codes frequently.

Unit Testing in XCode 5

Apple has done a great job by providing us (The iOS developer) with good framework that can help us to implement unit testing easier on XCode 5. I have learned this unit testing through WWDC 2013 video – Testing in Xcode 5 by Mike Swingler.

From what I learned from the video, we all should start the Unit Testing from Model and Controller. XCode 5 has been designed to make the Testing between the Model and Controller really easy. The new framework for the testing is XCTest.framework. This framework is derived from OCUnit. The iOS developers have been using OCUnit framework prior to XCode5. So, the previous testing codes are compatible with XCTest framework. If you were using OCUnit, you only have to refactor your old code to make it running well with the new framework.

While I was trying to implement the Unit Testing on my old personal Calculator XCode project, I found this simple tutorial (CS305 Software Engineering – Unit Testing in iOS). It shows me some steps and codes using a different calculator project. I learned something new from it.

Be warned, this project is old and it is definitely not optimized for iOS 7.

Example of Unit Testing in Calculator App

I just implemented what I have learned from the video on an old Calculator app project that I have developed for fun some time ago. This is not a usual calculator that most people are familiar. This is a RPN (Reverse Polish notation) calculator.

For example, if you would like to calculate an operation such as 21 + 63, the steps that you have to follow are:-
1. Press 2 and 1
2. Press Enter
3. Press 6 and 3
4. Press Enter
5. Press +
6. Press Enter

You will then get the result showed like the screen below:-
Unit Testing on XCode 5 With Example Project

Unit Testing can be further divided into 2 parts:
1. Logic Unit Testing
– Test only the logic with fixed values and without human interaction
2. Application Unit Testing
– Simulate the user inputs by using user interface such as button and make sure that the app behaves the way it should.

To keep make thing simple, I will only implement Logic Unit Testing for now. I will add more examples when I learn deeper into this Unit Testing.

The Model of my calculator project is CalculatorBrain. It has 3 functions:-
1. pushOperand
2. performOperation
3. popOperand

So, I will perform the unit testing on these functions.

There are only 4 major operations:-
1. Addition (+)
2. Subtraction (-)
3. Production (*)
4. Division (/)

I will implement Logic Unit Testing for all these 4 operations but I will only show an example in this article.

When a user is trying to add 21 with 63, he/she should get the result as 84. Or else, this operation will fail. Here are the steps:-

1. I import CalculatorBrain.h into CalculatorTests.m.
2. I create an instance of CalculatorBrain and instantiate it in setUp method.
3. I create a method calls testAddition.
4. I push 2 numbers (21, 63) using pushOperand.
5. Then, I use performOperation to calculate the result.
6. Lastly, I compare the result with 84 using XCTAssertTrue.

If the logic testing is good, it will show you the following result on the command line:-

If the logic testing is wrong, it will show you something like:

You then will know that you have made a mistake somewhere in the code, you will have to find a way to fix it.

The screen below shows you the complete unit testing for all the 4 operations.
iOS Unit Testing by Example XCode 5

Final Thought

Unit Testing is really an interesting way that helps us to be more proactive in programming. This is especially true when we are able to implement the Bots that help us in testing the project automatically.

You can find the full source code for this simple Unit Testing that I uploaded to Github here: iOS Unit Testing By Using Calculator Project on XCode 5.

Enjoy!

My Experience in Developing WatchOverMe

In this post, I am going to share my Experience in Developing WatchOverMe (WOM). WatchOverMe is a mobile app developed and owned by Secq Me Sdn. Bhd. It is a Location based security Mobile App. You and your loved ones can use the app. You can share your location with your loved ones all the time. In case of an emergency, you can shake you phone and your loved ones will get notified by SMS/email. They will know your exact location and able to take some action in order to help you.

Watch Over Me Mobile App has many different “internal versions“. We call it “internal version” because it is different from the release version. The version for the release version is slightly messed up due to the lack of proper version control in the early stage of development (I haven’t join this company yet).

After I joined the company, I was involved in 3 different version (WOM 2.0, WOM 2.5, WOM 3.0). I involved in improving some features in WOM 2.0 by optimising it to support iOS 7 and also support a new language (Spanish).

I developed WOM 2.5 from scratch for about 2-3 weeks of time and the project has been completed about 70%. But, a decision has been made to cancel this project to push forward for WOM 3.0.

I am also the only iOS developer (Currently based in Singapore) who developed WOM 3.0. Some of the functions in WOM 3.0 are the same with Maxis Circle Watch. But, there are some new functions that are added to enhance the user experience and also user friendliness. WOM 3.0 has a total remade on the user Interface. It is so much polished compare with WOM 2.0.

Here are my experience and thoughts on each of the WOM internal versions.

Watch Over Me Version 2.0 (WOM 2.0)

WOM 2.0 has been there for about 3 years when James (my boss) developed it on his own. This project has at least 2 other programmers before I took over. I only involved in some slight improvements such as adding promotion screen during the year end and also add additional language support – Spanish.

Here are some user interfaces of WOM 2.0.

WOM2.0
WOM2.0
WOM2.0


Watch Over Me Version 2.5 (WOM 2.5)

WOM 2.5 is an improved version of WOM 2.0. There is a total User Interface remade for this app. In terms of functions wise, it shares a lot of similarities with WOM 2.0. But, the base of this app is based on Calendar framework. You can schedule an event using your local calendar on your mobile phone. If there is any event that you will do daily or weekly, you can put that on your calendar. The calendar reminder will prompt the message asking if you want to be watched over about 5 minutes before the event.

WOM2.5
WOM2.5
WOM2.5


From our internal research, we found out that the existing users (including paid users) do not use WatchOverMe as often as they should. So, the calendar reminder is actually very helpful to remind people to use WOM more often.

A decision has been made to cancel this project, so this project never goes live.

Watch Over Me Version 3.0 (WOM 3.0)

WOM is another complex project that I developed from scratch. I did utilise some existing codes from Circle Watch and Existing WOM 2.0. But, due to the the differences in navigation design and others, I still have to make some changes in order to properly place inside the app.

WOM3.0
WOM3.0
WOM3.0


Additional functions for WOM 3.0 are:-

Watch Over Me Event with Photo and Note
When you are running an WOM event, you can take photo and write note on your journey.

Share Journey
When you are running any event, you can share your journey to friends and family members.

Crime Zone (Region Monitoring)
If you have this app installed on your mobile phone and you are driving/walking past a crime zone area, the app will notify you to let you know that you are near a crime zone and ask you if you want to be monitored using the app.

Watch Over Me Event Demo
We have added a polished watch Over Me event demo that teaches the users on how to use the app more effectively.

Event history
You are able to look back all the historical events that you have launched so far.

Report Crime
You may report crime area with photo and information. The information will be kept in the server database and shared with other users of the app.

Map with Route
When you are running a Watch Over Me event, you will know your exact location on the map every minute. You see the path that you have been driving/walking.

WOM3.0
WOM3.0
WOM3.0


As of 18 March 2014, this project has been completed about 85-90%. We will deploy the app to the beta testers in a few days. The estimated date to launch this app is on late March.

WOM3.0
WOM3.0
WOM3.0


You may download Watch Over Me (iOS) From: Watch Over Me (iOS).

Here is the demonstration of the WOM 3.0 with XCode and Simulator

My Experience in Developing Maxis Circle Watch

Maxis Circle Watch is a mobile application project funded by Maxis Berhad and developed by SecqMe Sdn. Bhd. It is a location base security mobile apps. You can monitor the location of your family members on a map at any minute. If any of the family members is in trouble, he/she can trigger an emergency and you will receive the notification though the app/sms/email. I am the iOS developer for SecqMe Sdn. Bhd.

Maxis Circle Watch is the First major iOS mobile development project that I developed entirely by myself. It is a complex mobile Application. There are a lot of programming works required on both the server end and front end (mobile apps – iOS/Android).

MenuVC
Menu View Controller
MapVC
Map View controller
CircleVCCircle View controller

Maxis Circle Watch Project Complexity

– There are a lot of APIs call between the front end and the server end.
– Sometimes, we have to go through a lengthy discussion to decide whether a certain programming logic should be done on the Server end or the front end mobile application. The decision is important to make sure the consistency of the mobile application in future updates.
– Sometimes after I found a bug/crash, I could not pinpoint the exact location of the problem immediately. I have to do some steps-by-steps troubleshooting to diagnose the problem to see if it is my fault on the front end or the fault on the server end programming by my colleague.
– There are a few different types of membership with different access/function rights. (eg: Admin rights, Guardian rights, paid users (pay using mobile billing vs In App Purchase), trial users, Maxis users, non-maxis users, members using SSO, members without SSO, Android users, iOS users).
– Before calling any APIs. We have to check if the user has the rights to call.
– After an APIs is called, the information returned from the server could be currently used by a few current active view controllers. We will have to update those view controllers accordingly. (eg: When I add a new member into a circle, I call the addMember API and got the new circle list from the server. After I updated the latest circle list in a shareModel, I have to notify some active classes (Map and Circle Table) which are using those properties to reflect the latest changes.

WatchOverMeVCWatchOverMe View Controller
ShakeToTriggerVCShakeToTrigger View controller
EmergencyVC
Emergency View Controller

Project Planning and Development

The project was started about 3 months earlier before I joined SecqMe Sdn. Bhd on August 2013. So, the server end programming and also the Android project has started 3 months ahead of the iOS version.

The design for this app was done before the release of iOS 7. So, the current design for this app is really targeted only for iOS 6 and below.

My colleague and my boss have been very helpful, they have provided me a lot of resources in order to catch up with the Android development.

The iOS version has been released only about 2 weeks later than the Android version.

Circle Watch iOS Project Development and Technical Features

I have to make a few key decisions when developing Circle Watch.

Apple Map vs Google Map
One of them is choosing either the Apple Native Map or Google Map. I was new to location and map technology when I started. My colleague who was the Android developer was using Google map. After I did some research on Google Map for iOS, I learned that it had all the APIs and functions that were needed for the purpose of our project. During that time (August 2013), I believed that the Google Map technology was very stable and far more superior than Apple Map. So, I decided to use Google Map in this project.

Container View Controller
Circle Watch has been designed to have a unique navigation. There are at least 4 active view controllers at the same time. There are 5 active view controllers when “Shake to Trigger” is activated. It is not a common navigation that you see in most apps.

When I first started, I didn’t plan carefully on the navigation. I only utilised the default UINavigationController that is provided by Xcode. After about 2 weeks into developing the project, then only I realised my mistake. I quickly researched into other Xcode technology that can be used and I found Container View Controller.

I fall in love with Container View Controller every since. It is such a powerful technology that makes the complex navigations look like a child play.

Getting Location in iOS 7
Since the release of iOS 7, some well established iOS applications have problem with getting the location from the phone in the background continuously without being terminated by the OS. I have faced the same issue as well. After a few weeks of researching and trying different solutions to solve the issue, I found a solution to solve that problem. You can see the details here: Background Location Update Programming for iOS 7.

Battery Consumption
Before I found the solution stated above, one other solution that works well but it consumes more than 10% of battery per hour. The solution above only consumes about 5% of battery per hour.

I understand the solution that I applied on this project might not be the most elegant solution. I believe if I have time to learn more about multithreading and also the background services API in iOS 7, I definitely will be able to develop a better solution that consumes less battery.

CircleMembersVC
Circle Member View Controller
MemberDetailsVC
Member Details View controller
SafeZoneVC
SafeZone View Controller

Future Project Development for Circle Watch

Maxis Berhad has been going through a major company re-organization with a new CEO and a new team of management. Some employees have been laid off and some projects have been cancelled.

Circle Watch is one of the lucky few projects that is still alive and ongoing. However, they are not able to provide additional funding to develop additional features that are not planned during the initial project agreement.

Thus, the design for Circle Watch still looks like the design for iOS 6.

Maxis hasn’t start to market this app yet. So, We do not have a lot of downloads for Circle Watch yet. We were informed that it is under their marketing plan later this year (2014).

Final Thoughts

Thanks to my boss and colleague, the help that they have provided has enable me to learn and develop this complex project in a “fast tracking” way. Of course, I put a lot of effort myself as well by working voluntarily during the weekend and after office hours (without claiming any OT).

There are a lot of improvements can be done in the current project. For example: add extra animation when moving from one View Controller to another. Make the transition for different view controllers more smoothly. I didn’t have time to improve that because I have to work on another complex project (Watch Over Me 3.0) immediately when the Circle Watch was completed.

Circle Watch just had its soft launch. It is still too early to tell if this project will be successful or not. I personally think this project will see a higher chance to be successful if Maxis is willing to provide additional funding to enhance the design and also add additional social features.

With a more polished design, social features and also marketing campaigns, the chance for this app to reach users who are willing to pay to use this service will be greatly increased.

If you are from Malaysia, you should able to download the app from both the Apple Appstore and Google Playstore: Maxis Circle Watch.

Circle Watch Video Demonstration from the XCode with Simulator

Market Share for iOS 7

This is a follow up post from the previous post on Decision to optimize for older iOS versions.

Since the existence of iPhone and iOS in 2007, we do not have a way to confirm 100% on the percentage of different iOS versions in the market. We can only use some sample sizes by some famous mobile apps that share their statistics. From the statistics, we estimate the real distribution for different iOS versions.

A few months ago, Apple has updated its developer portal webpage by letting the developers know the current statistics distribution such as the market share for different iOS version and also the App Review status for both iOS and Mac. This is a great update from Apple as the iOS developers do not have to guess the real distribution of the iOS versions again by collecting sample and statistics.

As of 9 February 2014, 82% of the devices are using iOS 7, 15% of the devices are using iOS 6 and only 3% are still using iOS 5 and earlier versions.

Updated on June 2014, 89% of the devices are using iOS 7, Less than 11% of the devices are using iOS 6 and below. After iOS 8 is released, the marketshare for iOS 6 and below could drop to below 5%.

You may find the real iOS marketshare distribution from the Apple here: iOS market share distribution by Apple.
iOS 7 Market Share

Mobile Application development companies or developers now know that there are at least 82% of the entire iOS ecosystem is using iOS 7 since 9 Feb 2014. They could make the key decision not to spend time in optimizing the older version iOS such as iOS 6 and below.

For me, the current project that I handled, I already dropped the support for iOS 6 and below.

Background Location Update Programming for iOS 7 and iOS 8

Before iOS 7, I used some location update solutions found from stackoverflow. After the iOS 7 is released, the location update (especially on background) is not working well in iOS 7. There are many existing location based apps had the same problem. It was due to the background services in iOS 7 which kill the app when the app is in suspended state.

After a few weeks of trial and error in experimenting many different solutions, I finally found one solution that works well for the app that I need to develop.

Note: The solution might not be elegant. It works well for what I want to create. When I am free, I am still constantly looking for more elegant solutions by exploring the background services in iOS 7.

iOS Application States and Multitasking

Before I dig deeper into the location services, I would like to share a bit on the iOS app states. It is very important for iOS 7 and above because we have multitasking background services starting from this version.

iOS App States

 

There are basically 5 states:-
1. Inactive – The app is running on foreground but there is no activity at the moment.
2. Active – The app is running on foreground and there are some activities.
3. Background – The app is on the background and still executing code. The app can move to suspended mode anytime now. But, the app can request extra time in executing code for a short period of time.
4. Suspended – The app is on the background and not executing code. Normally, the system will move app from background mode to this state automatically without any notification. But the app is still in memory.
5. Not running – The app is either not running or has been terminated by the system during low memory condition.

Most of the solutions before iOS 7 work well because during that time the system does not have multitasking and the system does not automatically move the app from background mode to suspended mode.

So, if your app needs consistent location update from the device, you will have to implement a solution that constantly refresh the app when it is in background mode so that it has a short period of time in executing the code and send the location to your server.

For more information on App States and Multitasking, you can visit: Guidelines by Apple on App States and Multitasking.

Background Location Update Programming for iOS 7

Behaviour of the location service that the app I have to develop:-
1. During the normal time, the app has to send the location to the server every 3 minutes.
2. When the user is running event, the app has to send location to the server every 1 minute.
3. The location has work both in foreground and background.

So, this app will get the location from the phone all the time. I have tested many solutions and the solution below works exactly as I needed and it consumes about 5% of battery per hour.

First of all, if you are using storyboard, you will have to make sure that “location update” under the Background Modes is enable. Screen shot as below:-
iOS 7 Location Background Mode This is very important as without that your app will not be able to get location when it is in background.

I created a class just to handle the location service. The most important function from the locationManager delegate is didUpdateLocations. You will need to know how to handle this function properly. I have programmed to make the locationManager restarts every 1 minute. When the locationManager is started, it will only last for 10 seconds to receive locations update from the device. So basically, the location Manager is only turned on for 10 seconds for 60 seconds.

I have tested on my device and it only consumes about 5-6% of battery every hour. The most important function is listed below with some explanation.

Updated on February 2014: Added the solution on Github and post to the thread in stackoverflow.

Updated on April 2014: EC has found a fix for the location update for an extended period of time.

Updated on May 2014: I received some requests by some developers (through email contact and the comment area of this post) on the sample codes for sending the locations to server on a certain time interval. I have added the sample codes and I have integrated EC’s fix on BackgroundTaskManager.m too. Full Solution: Background Location Update for iOS 7 with Location Update to Server.

Updated on September 2014: I have updated the solution to work in iOS 8. A new key NSLocationAlwaysUsageDescription has been added to the PList. It is a requirement in iOS 8 to inform the users on the reasons you need the location update from their devices. [locationManager requestAlwaysAuthorization]; has to be called in iOS 8 as well when getting the location.

Getting Location Updates for iOS 7 and 8 when the App is Killed/Terminated/Suspended

I have promised to write an article related to getting Location Updates for iOS 7 and 8 when the App is Killed/Terminated/Suspended. I have had a busy development schedule in the last few months until the New Year Holiday break. Finally, I have time to write the articles and post the solution on Github.

Please read this article for more details: Getting Location Updates for iOS 7 and 8 when the App is Suspended.