Group member: Ruslan Jonusas (rujon14)
Git Repo: https://Ru_Ru@bitbucket.org/Ru_Ru/medvault_ios.git

Introduction

Mobile health is a field which has seen interests from many, and the development of mobile health applications is on the rise. They provide ways to get biodata from wearable, track the data, notify and monitor. Store health records and much more. As of this the field has a lot of space to grow as technology improves. One of the key issues however is that the EU market doesn’t have the foundation for the e-Health, and currently the this trend in mHealth is only seen in the US, with high success. All though the changes are happening in EU which in the next 10 years will have the foundation for the e-Health and m-Health.

With this in mind, I wanted to create an application which where a user would be able to brows the medications provided by through a web API and display to the user. The data presented would contain the information about the medication name, title and an image.

With this a user can also go into the details of the medication to find more concrete information about it.

The other part side of the application is to provide a user with an ability to check the assigned prescription to the user, and have personal details presented as well.
The trend to store health records in mobile device is not a new trend, but it gives a strong flexibility to the users to have their own prescriptions under easy access. The aim with this is that the user can verify which medications are assigned to which prescriptions, and see it’s start and end date of the prescriptions.

As of this the client applications services as a information and data center where the user uses it to gain information and inform them self’s about the medications and prescriptions that they should be taking. The logic of the applications happens on the cloud, where a java backend server handles the creation of medications, assignment of prescriptions and so forth.

Set up – Backend Architecture

For this iOS prototype application, a backend server was developed using Java with Spring Boot and Spring Data Rest.
These technologies provide an ability to rapidly create Spring MVC application for cloud and web. More information on the implementation can be seen here
git clone https://Ru_Ru@bitbucket.org/Ru_Ru/medvault_rest.git

What is important to understand is that the server has ends points which output the data when a type of a request is made to the server. These requests are know as:

  • GET
  • POST
  • PUT
  • UPDATE
  • DELETE

For instance if a GET request is issued to one of it’s end points, which are provided by this url, ‘https://mymedvault.herokuapp.com/medvault/api/medication/all’ 
the server will output a JSON object which will contain the information about the all medications currently present in the database.
This is what the result would looks like

Screen Shot 2015-12-03 at 02.24.52

{
medications: [
{
name: "Tylenol Cold Congestion",
symptoms: [
{
id: 1,
name: "Cold & Flu",
info: null
},
{
id: 2,
name: "Headache",
info: null
}
],
type: "Capsules",
img: "tylenol",
description: "Cold and Flu treatment",
new: false,
links: [ ]
},
{
name: "PhysiciansCare Cold and Cough Congestion Medication",
symptoms: [
{
id: 1,
name: "Cold & Flu",
info: null
},
{
id: 2,
name: "Headache",
info: null
}
],
type: "Syrup",
img: "congMed",
description: "Cold and Flu treatment",
new: false,
links: [ ]
},

To give a bit more understanding on the JSON is that it a very common way of serving data, it is not tied down to a specific class or a language. Before JSON became mainstream, developers used xml, which is still used but with the ease of JSON, it because a defector for serving data. Another important concept is that most mobile applications are data driven, and the data has to come form somewhere, most commercial and enterprise applications which with numerous amount of data with more than 15+ tables and classes. Of course the database for application is relative small, but it gives a representation of what a full fledged application could have. Nevertheless the iOS application is communicating with the backend and consumes JSON to create an object of it’s own which it will understand. More on this will come later.

This is a model of a database that is being used for the Spring Boot Application.

#####
medvault_erd

Set up – Frontend Design & Market Research

Now with a bit of understanding of the backend architecture we can move to the iOS application it self.
As mentioned previously a lot of apps at this moment provide similar idea of user tracking prescriptions and medication, through a mobile device.
Some of this applications are farm more superior then others and provide a high difference of products.

One of the clear examples of such application is by ‘medisafe’ (http://www.medisafe.com/)
The application is reach features and functionality. It provides connectivity with various gadgets for measuring the bio-data. Mostly importantly however, it allows a user to track a medication and have the phone remind you about it when it makes an alert. The user is given with a simple UI where one give time for the medication, as well as set a schedule for the medication. This is a nice feature which allows a user to be in control of their own health and medication tracking. It takes an issue of non-adherence very seriously and provides a clean and attractive to UI to working with the application.

medisafe

As we can from the image above, the app provides a nice visuals of when the medications are supposed to be taken after they are added. Besides this it also provides typical form and data tracking ui that is commonly seen in an everyday phone.

Overall the application provides the ease and the stability it will be good on IOS.

Other application which provides similar functionality but in slight different side. The Care Zone application is another mHealth application which utilities different aspects of mHealth. It aims at tracking prescriptions and more on a professional side of the application. It allows a user to scan medications and give a more sophisticated tracking experience. Also provides ability to store records and track data. A strange approach to an application though is the option to write a journal. To some this may however be a fantastic feature for keeping notes and tracking some information which is personal to the user.
As of the usability of the application, it is fairly simple and intuitive, the only downside is that the application is relatively harder to use due to the large amount of features. This increases the complexity of the application.

####

Wireframes

With given examples of the currently used application a mock up was UI was designed using ‘Balsamiq’ which is a design tool that provides a user to create any kind of UI as well as mock navigation features.

Bellow are the mock prototypes of the UI that should give a rough idea of how the application came to be. Based on the most applications standart functionality, this application is no different. It contains a list of items such as medications. An ability to display details and track medications.

 

 

 

mainDesign 2  SubDesign

 

The application aim with this layout is to provide information in a nice and simple way. The key to good UI is to optimise the amount of clicks is required to do basic jobs with the application. Of course there are multipule approaches on how could this bee done, but with the investigation on the UI and applications ability clear choice was to implement following the 1st picture. The interviews show that images are favoured by the users, and many say that it provides visual identification of the medication.
The only concern this raised is how it would work on a actually device, considering the spacing and the layouting of the application. Overall the design satisfied the needs of the application that is aimed to provide simple and easy to use interface that displays the data in the right fashion,

Implementation

To implement and develop this application a set of rules as to be set and understood. Firstly, the data is core part of this application and requires a high attention.
Secondly, setting up the views and the providing the visual representation of the flow of the application. Lastly, is understanding linking the views and the data with the controllers.

There are three parts to the application, ‘Model, View, Controller’ which is known as a MVC pattern. It is first originated from the Desktop development, and recently has been adopted in the Web as the defector framework and architecture of course majority of the current problems. iOS adopts this concept for creating feature reach applications by providing the abstraction between the 3 entities.

Model

Model or otherwise known as data is the core part of most applications.This application consists of 4 objects or otherwise known as classes. There are a two types of classes that are used in this application. One of the classes is the basic Swift class that is easy to get going with. The interesting part happened, is when the Core Data is used to manage the persistence of the application.

Core data is one of the frameworks natively provided for managing persistence, and crud operations such as fetching the records after they have been persisted.
To define a core data a extra module is added to the application known as AppDelegate. It provides a code which is generated by the application, and is responsible for managing operations such as fetching, saving and much more.

This is the class diagram of the Core Data

Screen Shot 2015-12-03 at 05.20.51

The class diagram above shows the relationships and the structure of the data of the application.
Before diving more, it is also important to address other feature that are close to core data and assist with data mangment. Core Data is an API which abstracts the SqLite from the clear use, but it is used behind the scene without the human interaction.. Beside SqlLite, a NSUserDefault is another good option to control the flow of the application. NSUserDafault isn’t saved directly to the database, it is used to set variables values which are long lasting, they help to execute when it is needed. For instance:

   if let Runned = NSUserDefaults.standardUserDefaults().valueForKey("Run") as? Bool {
 if Runned == true {
   print("Runned");
  
 } else {
    loadMedicationsData();
    loadUserData();
 }

What this code is runs only at the start to initialize the data for the application. Once it is initialized the variable for ‘Runned’ will be true and it will no longer be executed unless the application is reinstalled. So this data will be stored on the disk, but it is not the most suitable way of managing data.

With Core Data on other hand we are managing complex object with attached relationships. An example of this is bellow

func fetchAndSetResults() {
        let app = UIApplication.sharedApplication().delegate as! AppDelegate
        let context = app.managedObjectContext
        let fetchRequest = NSFetchRequest(entityName: "PrescriptionEntity")

        do {
            let results = try context.executeFetchRequest(fetchRequest)
            if let entities = results as? [PrescriptionEntity] {
                for presc in entities {
                    let thisPresc = Prescription()
                    thisPresc.AutoMapper(presc)
                    for med in presc.medications {
                        let medicine = Medication(id: med.id as! Int)
                        medicine.AutoMapper(med)
                        thisPresc.medications.append(medicine)
                    }
                    prescriptions.append(thisPresc)
                }
            }
        } catch let err as NSError {
            print(err.debugDescription)
        }
    }

The way Core Data works is by initializing this three objects, a AppDelegate, context and a fetch request which is used to fetch the desired object, in this case it’s ‘PrescriptionEntity’.
Next, we make sure that the results form the fetch request has an object, and the relationship is attached to it. Since the relationship is one to many, we know that it will have a NSSet and we can loop through it to get the medications of this particular prescription.

Another point to notice is that the Core Data entity is not used directly in the view, instead a separate class is used which is mapped from the Core Data entity into the swift class. The aim is to provide an abstraction, and not pollute the code with having having calls to the Core Data opperations made all the time.

But before the data can be used, it has to come form somewhere, and in this case it is coming form the previously shown uri, and the Web Api.
To perform a request from Web Api, we can use NSUrl and make a native call. But for this application Alamofire is used as it provides a clear and easier way to work with web calls from the iOS.

The process to make this calls happens during the execution of the first load of the first controller. The data is automatically loaded to have it available by performing the fetch requests.

The data as we are aware of now is in JSON format, and it not a native format, and because of that it requires parsing and assignment to the right entity, before it can be used in the application.

This is how the process goes:

static func downloadAllMedications(completed: DownloadComplete) {
        let app = UIApplication.sharedApplication().delegate as! AppDelegate
        let context = app.managedObjectContext
        let medEntity = NSEntityDescription.entityForName("MedicationEntity", inManagedObjectContext: context)!
        //let sympEntity = NSEntityDescription.entityForName("SymptomEntity", inManagedObjectContext: context)!
        let fetchRequest = NSFetchRequest(entityName: "SymptomEntity")

        let url = NSURL(string: "\(URL_BASE)\(URL_MEDICATIONS)")!

        Alamofire.request(.GET, url).responseJSON {
            response in

            let result = response.result
            print(result.value)

            if let dict = result.value as? Dictionary<String, AnyObject> {
                if let medicationsJSON = dict["medications"] as? [Dictionary<String, AnyObject>] where medicationsJSON.count > 0 {
                    for var x = 0; x < medicationsJSON.count; x++ {
                        //
                        let medication = MedicationEntity(entity: medEntity, insertIntoManagedObjectContext: context)
                        let medId = x + 1
                        medication.id = medId;
                        if let medName = medicationsJSON[x]["name"] as? String {
                            medication.name = medName
                        }
                        if let medType = medicationsJSON[x]["type"] as? String {
                            medication.type = medType;
                        }
                        if let medImg = medicationsJSON[x]["img"] as? String {
                            medication.pic = medImg;
                        }
                        if let medDesc = medicationsJSON[x]["description"] as? String {
                            medication.info = medDesc;
                        }

                        if let symptoms = medicationsJSON[x]["symptoms"] as? [Dictionary<String, AnyObject>] {
                            // Go through each symptom under medication
                            for var y = 0; y < symptoms.count; y++ {
                                let symp = symptoms[y]["name"] as? String // get a name of the symptom
                                do {
                                    // Fetch all symptoms
                                    if let results = try context.executeFetchRequest(fetchRequest) as? [SymptomEntity] {
                                        //fetchRequest.predicate = NSPredicate(format: "name == %@", symp!)
                                        // Loop through fetched symptoms and find a match
                                        for symptom in results {
                                            if symptom.name == symp {
                                                medication.symptoms.append(symptom)
                                            }
                                        }
                                    }
                                } catch let error as NSError {
                                    print(error.debugDescription)
                                }
                            }
                        }

                        context.insertObject(medication)
                        do {
                            try context.save()
                        } catch {
                            print("Could not download medications")
                        }
                    }
                }
            }
        }
    }

This process is not the most elegant and an easy way to go about, especially the more complex the object is the more work it will require.
When working with parsing it demands checking and printing the object to verify that the it has the data or not, and any mistake in the casting or spelling errors in the string keys will cause an error.
In here we can also see that a fetch request has been initialized and it used to map the medications to the right prescription based on the matching string names from the JSON. Based on that the right data can be inserted.

Also, notice that this method is a static method which will allow us to run it without initialization, and it also requires to pass a custom delegate. A delegate is a code which returns a data or a result only once it has fetched or has the right data. It is a powerful concept and is used a lot in iOS.

The delegate is provided in the utility class called Constants which stores all of the static data, such as urls for the Web API and some methods.

typealias DownloadComplete = () -> ()

This is how the delegate is provided and used by calling a closure.

Controllers

Controllers are much less of a complex topic. It role is to assign data, pass data to the view and provide a channel of communication from the view to data, and vise versa. This means that if the data changes, the view will show it, and if the view has changes and it needs to be persisted, the controller will take care of it.

It role is also heavily used for logic control, and event listeners, which is how the view communicates with the data. Gestures, button presses, it is all controllers by the controllers that are assigned to the views. There are many different kind of controllers that are there and server different purposes.
In this case, we have a view that takes a user command when button press is initialised on one of the elements in the table view.

This how it happens

 func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
       var med: Medication!

        if inSearchMode {
            med = filteredMedications[indexPath.row]
        } else {
            med = medications[indexPath.row]
        }

        print(med.name)
        print(med.description)
        performSegueWithIdentifier("MedicationDetailsVC", sender: med)
    }

  override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "MedicationDetailsVC" {
            if let detailsVC = segue.destinationViewController as? MedicationDetailsVC {
                if let med = sender as? Medication {
                    detailsVC.medication = med;
                }
            }
        }
    }

In here we can see that the data is taken from the array of medication based on the index row, and then passed to the next controller which has a medication declared as a variable. This one of the examples in this application on the data is passed around and controllers serve as a middleware in providing this service.

View

As clear as it sounds, views are what the user sees and interacts with. It also displays the data, and doesn’t necessary needs users input. It all goes down to what the application is trying to achieve.
The biggest challenge when working with views, is the managing the constraints, and working on delivering the content that is in the right place. iOS provides many different ways of managing constraints, as its screen size has started to change in the last few yeas, the development of good UI has gotten harder because of it. It is much harder to be able to target all of the screen sizes compared to one.
One of these challenges comes from creating custom UI components such as custom table cells. This adds the nuisance of linking and containing the custom elements and also providing the right data to the custom components. Some of the cases with some custom components, it can not be done through the UI building that the iOS provides, and has to be done manually through code.

Results

With the given time to implements the application, the application fits the idea of what has been portrayed in the wireframes that has been outlined. Some of the features has been stripped down, or not included, and would be addressed as a next to come features.

To give a feel for the app, the screen shots are shown bellow.

Simulator Screen Shot 01 Dec 2015 21.19.03 Simulator Screen Shot 01 Dec 2015 21.13.18 Simulator Screen Shot 03 Dec 2015 06.33.09 Simulator Screen Shot 02 Dec 2015 15.51.42

There are the achieved views of the applications. They may not strike as a graphically intensive application, but it’s core focus is not provided visual aesthetics, but more about the information and educational purpose for the user.

Discusion

The application has gotten to the point where it is showing some usability, but is still lacking major features. It is suitable as a prototype design for testing with users to get more information on what they would like to see, and in what direction the application can take place. If this was more sophisticated, big changes would not be possible, or would be critical when it comes to drastic changes.

However, this are the list of features that would have been nice to have and see:

  • Mail Medication
  • Alarm on individual medications
  • Creation of Prescription
  • Private Channel with Doctor/GP
  • Functional Search Bar

These are the features that would have improved the application, and gave a solid feel to it. However the concept has been delivered and gives the foundation for experimentation on more complex features.

With the results form the user review, a set of different suggestions came by as well. One of them suggested to have a poll or a discussion section where a user can see comments on the medication. It is a common experience for user to seek and evaluate the products that they are interested in. With providing an easy access to this information, and provide a discussion channel on the device would add a strong value to it.

Another comment was about having a map which would show the near by pharmacies to the logged in user, that sell a specific and selected medication.
These feature suggestion are interesting and something that not many applications in the mHealth category have addressed

Conclusion

As it stands the application have achieved the required basic functionality. It has demonstrated how the data driven application works combined with a web api that provides the data.

However the application does lack features that would make it stand out, the outlined features in the discussion would be something to work on in the future.

Leave a Reply