Raspberry Pi Temperature Sensor Web Server - Part 4 (iOS Swift App)

So we have our Raspberry Pi web server which gives us a lovely set of json temperature data. What would be great though is an app that could display this data whenever we want. So lets do just that. Once again all of the source code can be found in my Github Repo.

Create a new single view project in Xcode, selecting Swift as the language. Open the storyboard and add some labels to the ViewController for the temperature output and date ( I used two for the date, one just as a title). Mine is below. I disabled size classes for this.

Using assistant editor, ctrl drag the temp and date labels into ViewController file to create IBOutlets for UIlabels. I called mine currentTempLabel and lastUpdateLabel.

Although we could put all the code we need for this project in the VIewController it would probably be better to abstract away all of the code we will use to get the json data from the Raspberry Pi. So make a new Swift file that subclasses NSObject calledTemperatureWebService. Copy the below code into that new file, remembering to swap the IP address for yours!

import Foundation
import UIKit
 
protocol TemperatureWebServiceDelegate
     
{
    func temperatureReceived(temperature: String, date: String)
}
 
class TemperatureWebService: NSObject, NSURLConnectionDelegate
{
     
    var delegate: TemperatureWebServiceDelegate?
     
    var data = NSMutableData()
    var jsonResult: NSArray = []
 
    func startConnection()
    {
        let urlPath: String = "http://192.168.0.11/temperaturejson.php"
        var url: NSURL = NSURL(string: urlPath)!
        var request: NSURLRequest = NSURLRequest(URL: url)
         
        var connection: NSURLConnection = NSURLConnection(request: request, delegate: self, startImmediately: true)!
    }
     
    func connection(connection: NSURLConnection!, didReceiveData data: NSData!)
    {
        self.data.appendData(data)
    }
     
    func connectionDidFinishLoading(connection: NSURLConnection!)
    {
        var err: NSError
        jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as! NSArray
         
        getLatestTempReading()
    }
     
    func getLatestTempReading()
    {
        var dictionary: NSDictionary = jsonResult.lastObject as! NSDictionary
        var tempValue = dictionary.objectForKey("Temp") as! String
        var dateValue = dictionary.objectForKey("Date") as! String
         
         
        if (delegate != nil)
        {
            delegate?.temperatureReceived(tempValue, date: dateValue)
        }
    }
}

This class is using NSURLConnection to get the data from our web service. We provide a function startConnection() that we can call from other classes that will do as it says. It will start the NSURLConnection for our IP address. We implement the NSURLConnectionDelegate and its delegate functions - using connection to append data to our NSMutableData object and connectionDidFinishLoading to know when we have all the data and to serialise our data into JSON.

When we have the data we call getLatestTempReading() to put the last temp reading from the JSON into a dictionary and call the corresponding objects for keys for temperature and date.

I have then opted to use a delegate method to give the data back to the object that owns the TemperatureWebService object as two String objects.

Now copy the below code into your ViewController class.

class ViewController: UIViewController, TemperatureWebServiceDelegate
{
    @IBOutlet weak var currentTempLabel: UILabel!
    @IBOutlet weak var lastUpdateLabel: UILabel!
     
    override func viewWillAppear(animated: Bool)
    {
        super.viewWillAppear(animated)
         
        var webService = TemperatureWebService()
        webService.delegate = self
        webService.startConnection()
}
     
    func temperatureReceived(temperature: String, date: String)
    {
        currentTempLabel.text = "\(temperature) °C"
        lastUpdateLabel.text = "\(date)"
    }
}

As all of the hard work is done in the web service class our ViewController is incredibly simple. We firstly have two IBOutlets for our labels and then we override viewWillAppear and create a TemperatureWebService object, which we call startConnection() on. Then we implement the TemperatureWebServiceDelegate and its associated method which will be called when the web service has received data, serialised it and found the last temperature reading. We then simply set our labels to show the two strings given to us by the web service.

NOTE: If you are using iOS9 changes in App Security stop you accessing http web addresses. To fix this do what is detailed here.

When working it should look like this.

Next time we will make a graph to show all of our data that has been collected.