Tool up!

Jakub Machowski – jamac17

Julia Ruchlicka – juruc17

Introduction

 

The name of our application “Tool up” is an English idiom for becoming equipped with some tools. We came up with idea that having simple measuring tools on an iPhone that we have most of the time around, would simplify people’s life when buying furniture or hanging a picture at home. The objective of the course was to design an iOS application using one of the embedded into Apple devices sensors. We developed through Xcode 9.1 platform using Swift 4.0 programming language (iOS 11). 

Requirements

To understand the subject we are writing about reader should be familiar with basics of iOS development described in e.g iOS Programming: The Big Nerd Ranch Guide 4th ed. and with additional external source concerning one of the used sensors, in this case gyroscope.

The Idea

Our application concept was to connect multiple measuring tools, mainly: spirit level, tape measure and a ruler. The main advantage of our idea was to add as well calculations where there would be possibility to calculate area or volume of rectangular prism, cylinder and pyramid. Moreover, we wanted to add a data storage where user could store measured data and also easily include them into particular calculation without being forced to write it down on a paper. We wanted to include settings to let user decide about used units, sound volume or whether to use vibration or not. After the presentation of portfolio exercise part 1, we also decided to use Jacobs feedback on our project and include voice commends that simplify measuring with the spirit level.

Methods and materials

Through brain storm we established the conceptual model for our application. We wanted to make it:

  • simple, intuitive and handy,
  • helpful on daily basis,
  • useful: simplified calculations with personalized data storage,
  • universal: multiple measurement methods.

As overall initial demand group we chose “everyone”, because its main application goal is to be helpful either for kids or adults. For our Idea we wanted to follow iHandy level app, Ruler and Tape measure PRO for iPhone that may be found on app store.

Simple prototyping

We decided to do the prototype phase with two different approaches. First one was with two paper sketches.

First design version

 

 

 

 

 

 

 

 

 

The alternative design.

 

 

 

 

 

 

Evaluation

Paper prototypes came in handy, when we were to choose between 2 different ideas concerning the app’s navigation. After discussion we decided to use and improve the system shown on the first picture. In our opinion navigation should be easy and intuitive and it is such when the app has the main menu. Another advantage are the big icons and buttons that are visible to everyone, young people and elders.

Building a first navigational digital prototype

As mentioned before, after we have finished our paper sketch, we focused on making a digital prototype. We decided to use Adobe XD environment. We created digital version of the paper sketch and introduced how we would like to our application to look. Thanks to Adobe XD we were able to record a video of app’s navigation system in simulator.

 

Graphics used as an icons and buttons in our application come from free images sources. The logo and graphics to bubble level, tape measure and ruler we designed ourselves.

Evaluation
after digital prototyping

The next step after creating digital prototype was to get the user feedback. This time we had more refined model of navigation in the app, so we have sent the created movie to our friends and got following responses:

„ After saving the result, it’s prefered to return to the particular tool that was used to measure rather than to the main-screen. Usually we need more than just one measurement and it makes the application less frustrating.”

„While using the Tape There should be just one start stop button. It’s easier”

„Applying hints for how to use a particular tool would be helpful”

Another feedback we received at the presentation of portfolio part 1, mainly that it would be interesting to put sound responds when using bubble level tool.

Implementation

During the development process we were able to optimize our project, as we probably were driven by design wave and decided to focus on main parts of our application – data storage, calculations and sensor using features – bubble level and on-screen ruler.

For example, we came to  a conclusion that in there is no need for implementing settings concerning sound volume and vibration, because it can be managed in main device settings. We also asked ourselves if there is a single pyramid object in our working environment at that time, whose area could be calculated. Unfortunately, we’ve found none, that is why we decided to change the calculation of pyramid figure to simple rectangle. Then some not very mathematically gifted user could count an area of floor or a wall.

Results

As we never worked with Xcode or even swift programming language, at first we were rusty, but with time we gained some humble experience, as we were implementing new parts of our app.

 

Gyroscope implementation
In order to use gyroscope for our bubble level we had to import CoreMotion. We want the app to start measuring the rotation rates only after selecting the correct button from the menu. This is why all the essential code is put in method viewDidAppear brackets – it starts working after the assigned view is loaded.
//
//  Bubble.swift
//  ToolUp!
//
//  Created by Julka on 20.11.2017.
//  Copyright © 2017 Julka. All rights reserved.
//

import UIKit
import CoreMotion

class Bubble: UIViewController {
    var motionManager = CMMotionManager()
    
    @IBOutlet var progressViewZ: UIProgressView!
    @IBOutlet var perfectLabel: UILabel!
    
    override func viewDidAppear(_ animated: Bool)
    {
        if motionManager.isGyroAvailable {
        motionManager.gyroUpdateInterval = 1.0/0.5
        
        motionManager.startGyroUpdates(to: OperationQueue.current!) { (data, error) in
            if let myData = data
            {   print (myData.rotationRate)
                self.progressViewZ.progress = Float(myData.rotationRate.z)
                if myData.rotationRate.z < 0.05, myData.rotationRate.z > -0.05
                {   print("Perfect!")
                    self.perfectLabel.text = "Perfect!"
                }
                else {
                    self.perfectLabel.text = ""
                }
            }
        }
        }
    }
}
The first thing to do is checking if the device is able to use gyroscope – isGyroAvailable. Then we set the gyroUpdateInterval – the ratio with which the app updates the rotation rates values (seconds/quantity per second). All the data we need concerns only the Z axis so far. After many try-outs we figured out the approximate min and max value within which lies the designed phone position. If we manage to place the device correctly, the „Perfect!” label is displayed on the screen.
In order to display the devices current position we used the UIProgressView.
Calculations
All the code parts concerning the area or the value calculations are similar, so below we present only one example of such – cuboid volume.
//
//  Volume.swift
//  ToolUp!
//
//  Created by Julka on 24.11.2017.
//  Copyright © 2017 Julka. All rights reserved.
//

import UIKit

class Volume: UIViewController {
    
    @IBOutlet var resultVolumeLabel: UILabel!
    @IBOutlet var textFieldL: UITextField!
    @IBOutlet var textFieldW: UITextField!
    @IBOutlet var textFieldH: UITextField!
    
    var lenghtValue: Double? {
        var lenght = Double(textFieldL.text!)
        return lenght
    }
    var widthValue: Double? {
        var width = Double(textFieldW.text!)
        return width
    }
    var heightValue: Double?{
        var height = Double(textFieldH.text!)
        return height
    }
    
    @IBAction func dismissKeyboard(_ sender: UITapGestureRecognizer) {
        textFieldL.resignFirstResponder()
        textFieldW.resignFirstResponder()
        textFieldH.resignFirstResponder()
    }
    
    
    var cuboidVolume: Double? {
        if let L = lenghtValue, let W = widthValue, let H = heightValue {
            var cuboidVolume1 = L*W*H
            return cuboidVolume1
        } else {
            return nil
            //let errorString = "Instrument reported lack of a value , please use all required values."
        }
    }
    
    func updateResultLabel () {
        if let cuboidVolume = cuboidVolume {
            resultVolumeLabel.text = "\(cuboidVolume)"
        } else {
            resultVolumeLabel.text = "???"
        }
    }
    @IBAction func computeTapped(_ button: UIButton) {
      updateResultLabel()
    }
}

We accuire the length, width and height values from assigned text fields: UITextField. Unfortunately, for further use their type has to be converted from String to Double. Afterwards we calculate the cuboidVolume using the simple math equation. For the calculations we used optionals to express the possibility that a variable may not store a value at all, as there is a possibility that user won’t apply all required data for calculating particular figures.  We decided to use a safer way to unwrap an optional by optional binding. If all the values were entered correctly – text fields aren’t empty and the input is a number, the resutVolumeLabel (UITextLabel) will display the result. The updateResultLabel method is called only after the „Compute” button is tapped.

In calculations section we also used the UITapGestureRecognizer. After any of text fields is tapped, the decimal keyboard will appear on the devices screen. To dismiss it, the user has to tap on screen, anywhere but on keyboard.
Saved data
So far the most complicated part is the one concernig the data storage. Unluckily it’s not working. The Tabel View Controller, which we decided to use for displaying the saved data cannot communicate with the main menu. We implemented the following code in AppDelegate.swift file:
//
//  AppDelegate.swift
//  ToolUp!
//
//  Created by Julka on 20.11.2017.
//  Copyright © 2017 Julka. All rights reserved.
//

import UIKit
import CoreData

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?


    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        
        //NOT WORKING PART

        // Create an objectsMemo
        let objectsMemo = ObjectsMemo()
        // Access the Dane (data ViewController) and set its objects memo
        
        let menuController = window!.rootViewController as! ViewController
        
        let navController = menuController.topViewController as! UINavigationController
        //The upper line concerns using the Navigation Controller between the menu ViewController and the TableViewController called Dane
        //PROBLEM: the code below doesn't work, because menuController, which is a ViewController doesn't have the 'topViewController' member
        //Question: How to connect those 2 without using "topViewController" command or what to replace it with?
        let daneController = menuController.topViewController as! Dane
        daneController.objectsMemo = objectsMemo

        return true
    }
The problematic one is the line 33 – ViewController doesn’t have the ‚topViewController’ member. It would have worked as the connection between the menu View Controller and saved data Table View Controller. Otherwise, this part works just fine – we tried it out after deleting the home screen of our app.
To store and save the data, we needed to create 4 swift files: one for managing the whole Table View Controller (it works like a bridge for the other files – allows them to exchange values and communicate), one for managing the objects themselves (add, move and delete actions implemented), one for creating the new object and one for entering the saved objects properties (length, width, height and date created). This part of the applicatiion we implemented following the iOS Programming: The Big Nerd Ranch Guide 4th ed..
We implemented the aboved described part in following way in Main.storyboard:

As required, we also created simple video of using the application.

You can find the code of our application here: https://bitbucket.org/iosprogrammingsdu/tool-up

Discussion

Our application is based mainly on following the chapters from iOS Programming: The Big Nerd Ranch Guide. If we were to release the application, we would still  have a lot of things to work on. During development process we’ve learned, that such a “simple” app, means actually a lot of complicated coding, that we were not prepared for (Xcode has not made our work easier with the crash we’ve experienced and lots of surprises following the software update). We resigned from creating the Tape measure as the implementation of accelerometer in this particular case turned out to be very difficult task, so we decided to stop working on that and focus on developing  bubble level. Due to lack of time we didn’t implement the ruler, because we experienced a lot of problems while trying to execute the code, mainly in this case with measuring distances in real time between two zips. We didn’t work further on the saving measured data due to the problems described in sections above. Our main problem with implementing all tools that we planned was result of struggle with finding corresponding descriptions of sensors that we wanted to use, either in books or in Internet tutorials. We read a lot of additional sources for finding information  [2] [3] [4], but the problem was that the books was working with old Xcode systems and with objective-c rather then with Swift 4.0 and so was most of internet tutorials. That is why for us as beginning Swift developers it was very hard to implement this knowledge into our project. Moreover, the iOS Programming: The Big Nerd Ranch Guide didn’t have enough information about sensors we wanted to use.

Future work

For our future work we want to fix bugs from Auto-layout that we use as well as we would like to implement Core Data, and focus on improving bubble level itself, with promised sound effects introduced below:

For the time being, we are convinced that we created a good base for future development of our application. If we manage to achieve satisfying results with three main objectives written above, we would like improve the things that we have already started e.g implementation of the ruler. As we don’t plane to release our application we don’t intend to work on non-started factors.

Sources:

  1. Christian Keur, Aaron Hillegass-iOS Programming The Big Nerd Ranch Guide-Big Nerd Ranch Guides (2016)
  2. Alasdair Allan-Basic Sensors in iOS Programming : the Accelerometer, Gyroscope, and More-O’Reilly Media.
  3. Matt Neuburg iOS 9 Programming Fundamentals with Swift Swift, Xcode, and Cocoa Basics.
  4. Rajiv Ramnath-Beginning iOS Programming For Dummies (2014)
  5.  iOS tutorial from https://www.raywenderlich.com.
  6. Youtube tutorials.

 

Written by Jakub Machowski and Julia Ruchlicka

 

Leave a Reply