By Ahmad Rzgar Hamid (Ahham14)

The repository for GeoAlarm can be found at: https://bitbucket.org/iosprogrammingsdu/geoalarm/

1 Introduction

Throughout the autumn 2019 in the course iOS Programming, a project was presented with the objective to create an app that included usage of either an internal or external senor.

GeoAlarm is an alarm concept made with the intention of adding additional features to the native iOS Alarm app preinstalled on iOS devices. The concept is build around the idea of using of utilizing the GPS to receive a location, which will enable the option of making the alarms location based. This means that an alarm can be set to fire only when the device is in a given location. If the device is not in that said position, the alarm will not fire.

1.1 History

The concept has come a long way since the original pitch. The first version of the idea was called TickDown, an idea of an app that combine the power of timers, countdowns, task managers and other similar ideas. This with the intent of centralising what normally would be done in several app into one app.

Figure 1: First version of the low fidelity prototype. Built in Adobe XD.

As part of evolving the business idea and developing the app, it was clear that the scope for the original app was too much for this project, meaning that only a fraction of the idea could be implemented in the given timespan. Also, a complication hit the group, reducing the size from two group members to one.

In this reduction, the project was also reduced to a more tangible project, an alarm app incorporating location features into the way we uses alarms.

1.2 Similar solutions

Right now, there is a number of app that include somewhat comparable features. A number of the most popular and comparable ones has been listed here, to clarify similarities and which elements that differentiates the business ideas.

1.2.1 Naplarm, Alarm Me, OmniBuzz, SleepyMe, WakeMeHere and others

Naplarm and the other apps mentioned above is apps that shows an map and let you mark location on the map. As Naplarm keeps track of your location, it will remind you when you reach a marked location.
The core idea is to base the alarm on location instead of time. This is done, as they argument that factors as traffic, affect the duration of a journey, making it unreliable to rely on time. The app uses your real-time GPS location.

The app is not completely similar to this project, as it does not use time at all. Only location.
Furthermore, the concept is to bind the alert to a location, not to bind to “enablement” of the alert to a location.

1.2.2 IFTTT

IFTT is an app made to interconnect a large number of apps to interact and work with each other. It lets apps and devices talk to each other, making it possible to make “workflows” where different things can trigger other things. Technically IFTTT interacts with the API of a bunch of apps, making it a central hub for accessing these APIs and create events based on the users workflows.

An example of a workflow, which is presented on the IFTTT site is the workflow: “Turn on your porch light (Philips Hue) when the pizza’s (Dominos) on its way”.

Figure 3: IFTTT view of a specific workflow. Source: https://ifttt.com

A workflow combining location and alarm, could be made to mimic the idea of the project; “When you are in a given location, then enable the alarm”.

This will be a way to combine 3 apps, namely a maps app (like Google Maps), a alarm app and IFTTT to enabled the feature that this project are intended to do in a single app.

As of right now, an app has not been encountered that completely match the proposed business idea, even though a combination of apps will be able to mimic the functionality.

2 Methods and Materials

2.1 Materials

2.1.1 Prototype (Wireframe)

For creation of the low fidelity prototype, also called a wireframe, Adobes mock-up tool, XD was used. XD offers simple, visual drag and drop prototyping, while including the standard designs offered by Apple to develop for their devices. This is a easy way to sketch the business idea in a understandable way, that can be shown to potential users to test the app flow and understanding if the idea is feasible.

2.1.2 Development machine

An old Macbook Pro early 2013 was used to develop the app. As the machine houses an old i7-2620M processor, the iOS device simulator tool was nearly useless, making testing the app and the functionality difficult.

2.1.3 Development environment

For development, Swift 4 was chosen over Objective-C, as this is the new approach presented and favored by Apple.
Also the Apple developed IDE, Xcode, was used, as it is natively made to develop applications with the intention on running them on Apple products.

2.1.4 Version control

For version controlling the application, Git and GitHub was used. Git was chosen, as it is the most popular and well-known tool to implement version controlling right now.
Github was chosen, as it is the main tool used by the group in other projects, making setup easier.

2.2 Methods

2.2.1 Idea process

The initial idea was decided on early in the process, where a former group member have had some issues with keeping track of a number of things in a structured and convenient way. Therefore, an app-idea was already present even before the course started.

When the project has down-scaled and the scope was rethinked, the whole idea and its sub-issues was brainstormed to structure the different branches that the scope could follow. After examining the different branches that could be used as the new scope, a lot of ideas way filtered out, as different requirements was not meet. This made a number of ideas possible for the future work, where the one most interesting was chosen.

2.2.2 Low fidelity prototype

Using Adobe XD a low fidelity prototype was made, with the purpose of giving a representation of the business idea in a visual way. As this part of the project was done in a very early phase, the prototypes was made on the original business idea and not the idea that was used in the development.

2.2.3 High fidelity prototype

Using the interface builder in Xcode a interactive high fidelity prototype was made, with the purpose of showcasing the UI and appflow intended to use in the app. Though, as the development of the app moved on, a lot of the elements was changed, to follow the timeline and reality of how the project would be at end of the project.

2.2.4 Implementation

Implementation was initiated with a phase of research to understand the way that alarms is natively fired in iOS and to understand the limitations set by Apple.

2.2.4.1 Limitations

To make the alarm app work properly, it is essential that the app runs some business logic in the background and triggers some sort of functionality as soon as the time for the alarm has come.

As this is not a functionality that Apple supports, to make sure that don’t consume resources constantly, we are in need of a method, where the business logic, responsible for starting the alarm is triggered. I have chosen to solve this problem using Local Notifications, which is a way to inform users when some sort of new data has become available in the app, when the app is not running in the foreground. This means that i will combine the notification of the user with the triggering of the alarm it self.

This feature definitely help making the app a reality but also introduces a number of setbacks, compromising the idea of a fully functional alarm app.

  • The notification will be withheld if the phone is in silent or do-not-disturb mode, as these settings cannot be overwritten. This means that the logic may be triggered, but the user will not be notified.
    A user on reddit, chriswaco, says that this can be solved using MPMusicPlayerController application player instead of system player.
  • The alarm will only sound for 30 seconds, as this is limited by Apple.
  • There is no control over the volume of the alarm, making it up to the user to set the volume globally.
  • There is no guarantee for delivery of the notification. This means, even though chances are slim, that there is a risk of the notification (and therefore also the alarm itself) not triggering.

2.2.4.2 Libraries

A number of libraries has been used in the project in include the desired functionality in a meaningful and rightful way. The most important will be mentioned in this subsection.

UIKit
The UIKit library constructs and manages the iOS GUI by providing the infrastructure and functionality to display and interact with these elements.

CoreLocation
The CoreLocation library provides geographical location of the device in use. It gathers data using a number of components like GPS, Wi-Fi and cellular hardware.

MapKit
The MapKit library provides the graphical map interface and make embedment of these possible. Annotations can be used to pinpoint different locations.

UserNotifications
The UserNotifications library enables push notifications to be sent to the user either from a server er locally in the app.

3 Results

After actuating and implementing the above mentioned methods in the workflow a number of decision was taken. These decisions, their effects and results are presented here.

3.1 Idea process

As a result of the brainstorm, an idea was proposed of a alarm app, preferably a look-a-like to the native iOS alarm app, that included the feature of activating alarms only in a preselected location.

Figure 4: The native iOS alarm app. Source: https://www.idownloadblog.com/2019/04/06/sleeper

3.2 Low fidelity prototype

The first prototype was as mentioned a prototype of the original business idea. This means that the prototype itself does not have any relation to the actual business idea.
The prototype starts with the main screen being the currently running timers. The app features a tab bar, where different views can be reached.
The second view is the active timers view. This shows all enabled timers even if they are not running.
The third view is the categories view. Here it is possible to see all saved timers that are saved in an organised and structured fashion.
The last three views is the add-process, showing how to add a timer.

Figure 5: Final version of the low fidelity prototype. Built in Adobe XD.

3.3 High fidelity prototype

The second prototype was a prototype made in the Xcode interface builder. This prototype was in a interactive form, making the buttons and segues transfer the user to the following views, giving a realistic user experience. It is clear to see that the business idea and the scope had been changed majorly.
This prototype is based on the intention that this app should mimic the feature of location being implemented in the native iOS alarm app.

The first view shows the main screen. Here a table show the currently registered alarms.
The alarms can be activated by clicking on the switch. Clicking on the “Edit”-label, makes it possible to delete or edit a already registered alarm.

Clicking the “+” switches view to the view for creating alarms. Here it is possible to set the
time for the alarm to fire, which weekdays it should fire on, giving it a label and choosing if it should be possible to snooze the alarm.

By clicking the “Location”-cell, the map view will show up, letting you choose the location for the alarm to fire. By default the alarm will fire everywhere, but selecting a location restricts the alarm to only fire on that said location.

3.4 Implementation

As mentioned earlier, the repository containing the complete app can be found at: https://bitbucket.org/iosprogrammingsdu/geoalarm/

3.4.1 Storage

For storage a simple and easy implementation where chosen. Here the data was stored locally in a file. The FileManager-class was used to access the filesystem, creating the file and editing it. The data was stored in JSON-format, making it easy to substitute the local storage with a number of other solutions in the future. Comments has been added to make the code readable.

func saveAlarmToDisk(_ alarm: Alarm) {
    //Creates JSON encoder and makes a timestamp.
    let encoder = JSONEncoder()
    let timestamp = location.date.timeIntervalSince1970
    
    // Gets URL (path) to the file and makes filename from timestamp.
    let fileURL = documentsURL.appendingPathComponent("\(timestamp)")
    
    // Converts alarm with the encoder and writes to the file.
    let data = try! encoder.encode(alarm)
    try! data.write(to: fileURL)
    
    // Adds the alarm to the alarms-array
    alarms.append(alarm)
    
 }

3.4.2 Alarm

For the Alarms a struct was created, making it easy to duplicate and reuse. The struct does include more information than what are currently being used in the app. This is due to the parts not being implemented fully.

struct Alarm {
    var id = ""
    var date = Date()
    var isEnabled = true
    var location = Location()
    
    init() {
        
    }
    
    init(id: String, date: Date, isEnabled: true, location: Location) {
        self.id = id
        self.date = date
        self.isEnabled = isEnabled
        self.location = location
        
    }
}

3.4.3 Notifications

Then the time has come for the alarm to fire, the NotificationCenter is called and a push notification is made.

NotificationCenter.default.post(name: .newAlarmSaved, object: self, userInfo: ["alarm": alarm])

As default the notification would not fire then the app was in the foreground. This meant, that the alarm would not fire at that time. Normally this would be fixed by making a new class to act as the NotificationDelegate, but as the code for making it work was so small, it was extended to the already existing AppDelegate.

// Extension, making it work as Notification delegate.
extension AppDelegate: UNUserNotificationCenterDelegate {
  // Function, making the notifications show in foreground as well.
  func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
    completionHandler([.alert, .sound])
  }
}

4 Discussion

The app GeoAlarm has been made. It can fire alarms and send notifications to notify the user. Sound has not been implemented, so right now it is only the notification that is fired by itself.

Also the user’s location can be received and saved with the alarm. It is not possible to select a location on the map other than the current location of the device. This was a feature that would be nice to implement, but due to time limits it was excluded. Furthermore, the functionality of making the alarm fire only in the given location has not been implemented successfully, in a way that actually work. This would be investigated and hopefully implemented in the upcoming days.

Lastly, the storage-method should be substituted with a method that are more appropriate for storing data of this kind. That could be CoreData, a mySQL (or other SQL-servers) or firebase (or other noSQL-servers).

The above-mentioned are all things that should be added in the future, as it is core parts of the app.

5 Conslusion

The project has reach a acceptable state, although some key features are missing. The business idea is clearly represented in the app and
Even though a lot of the desired functionality has been excluded due to lack of skills and time limits, it is still in a state where the most important parts work in a somewhat acceptable way.

6 Evaluation

The project has been a very educational and with the lectures and videos as supporting material, it has been a good technical tour through Swift and iOS programming. The project is one that stem from a real-life problem, where it in reality do solve a problem. The group therefore has the intention to complete the project to be used by ourselves.

It is clear which functionalities need to be implemented as minimum, but when they are implemented, a future task could be to make it look and function “exactly” like the native iOS alarm app.

7 Demo video

As I do not own a iOS device myself, and my computer is to weak to run the iOS device simulator tool in a way where it is usable, a demo video is not provided. I’m in search of a device and as soon as i find one, a video will be made and included.

Leave a Reply