Arduino Tutorial: Networked Temperature Sensor with Swift

In this Arduino Tutorial, you’ll work with a temperature sensor and the companion iPhone app in Swift to connect with it! By Tony Dahbura.

Leave a rating/review
Save for later
Share
You are currently viewing page 4 of 4 of this article. Click here to view the first page.

iOS and Swift Integration

Now comes the iOS! You will build an iPhone app to get your temperatures. To start things off, open the included Xcode project from the tutorial download. You can find it in the folder ArduinoTemperatureSwift Starter. The starter project has the following functionality:

  • It provides a simple user interface for the application.
  • The supported interface orientation is set to portrait.
  • It includes a custom open-source digital-looking font to show temperatures.
  • It contains a configuration/settings screen.
  • It provides methods to save and load your settings, including the URL and the temperature display format.

Open the project in Xcode and build and run. You should see the following:

initial_run_nosettings

This project uses a basic Application model including a flip view for settings. You will handle the communications and parse the results.

Tap the info button at the bottom of the screen and input the URL for your Arduino server:

configscreenios

Click the Done button and on the main screen, tap Update. You should see a message to the debug window telling you that your settings have been saved, but wait… there are no temperatures from your new circuit!

This is where you come in. Open ViewController.swift and locate performRestCall(). Inside this method, place the code needed to communicate over the network with the Arduino:

var url = NSURL(string: theURL)

if (url == nil || theURL == "") {
  showAlert("Invalid or no URL entered!")
  return
}

updateButton.enabled = false

var request = NSMutableURLRequest(URL: NSURL(string: theURL)!)
request.HTTPMethod = "GET"
request.setValue("application/json; charset=utf=8", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalAndRemoteCacheData

NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue(),
  completionHandler:{ (response:NSURLResponse!, data: NSData!, error: NSError!) -> Void in
      
  dispatch_async(dispatch_get_main_queue(), {
    if let anError = error {
      //error getting data
      self.showAlert(error!.localizedDescription)
    } else {
      //process JSON
      self.handleResultsOfWebCall(data)
    }
    self.updateButton.enabled = true
  })
  return
})

This code simply takes the URL you provided to talk to the Arduino and sets up a background HTTP request using an Operation Queue. We utilize Swift closures to handle the results of the background web request.

The code receives the results and calls handleResultsOfWebCall(_:) on the main thread. This method parses and displays the results.

Let’s get to that now!

Find handleResultsOfWebCall(_:) and add the following implementation inside the method:

var error : NSError?

var jsonResults = NSJSONSerialization.JSONObjectWithData(theData, options: nil, error: &error) as! NSDictionary
if let jsonError = error  {
  println("JSON Error \(error!.localizedDescription)")
  showAlert("Error retrieving results-check the URL or Server!")
} else {
  let theSensors = jsonResults["arduino"] as! NSArray
  for i in 0..<theSensors.count {
    let sensor = theSensors[i] as! NSDictionary
    let location = sensor["location"] as! String
    let temperature = sensor["celsius"] as! NSString
    
    if (location == "indoor") {
      indoorTemperatureCelsius = temperature.floatValue
    } else {
      outdoorTemperatureCelsius = temperature.floatValue
    }
  }
  lastUpdate = NSDate() 
  saveSettings()  
  updateDisplayWithCurrentReadings()
}

This method to see if any data was returned, you use the built-in NSJSONSerialization handler to get the results into a NSDictionary object. From there, you read the values returned from the sensors and save them as Celsius values.

Next the settings are saved for display later when the application starts up again. Finally, you call updateDisplayWithCurrentReadings() to show the temperature values.

Build and run the application, and enjoy!

samplescreenshotwithtemps

Congratulations! You have a mobile application and temperature server that lets you read temperatures from sensors you can place anywhere. My setup has one sensor outside of a window and one inside. It’s really nice to be able to check the temperature quickly in the morning before heading out the door.

Where to Go from Here?

Here's the download for the completed Xcode project from this tutorial.

You will notice the display shows the temperatures in different colors, based on the range of the value. This color handling is in the setFieldColor method. Feel free to change them for your climate.

You also may not like the sensor changing the IP address if it reboots, based on your DHCP settings. If that's the case, modify the Arduino code to include a predefined IP address. This was described earlier in the tutorial, but for reference, you need to add a line near the top of the LEDBlinkAndEthernetTemperatureJSON file, like this:

byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0x7D, 0x54 };  
IPAddress ip(192,168,1, 121);  //or some value you want

Then replace the if (Ethernet.begin(mac) == 0) line with:

Ethernet.begin(mac, ip);  //in place of Ethernet.begin(mac).

What you've done in this tutorial is easily adapted to many other sensors!

I hope you enjoyed this tutorial and that it has inspired you to continue with your Arduino investigations. In the meantime, if you have any questions or comments, please join the forum discussion below!

Tony Dahbura

Contributors

Tony Dahbura

Author

Over 300 content creators. Join our team.