How to add Microsoft's Azure Services to your Swift apps

Let’s see how to integrate an Azure service into your Swift application in Xcode. What I’m about to show you will work with any of Azure’s iOS libraries since they are all written in Objective-C. 

Just head over to Microsoft’s GitHub repo’s and download the service library you need.

In this tutorial, we’ll install Azure Storage Client Library for blob storage. 

Now, there are a couple of ways to install these libraries. You can use CocoaPods, which if you’re using the same point release of Xcode that the library was created with you should be alright, otherwise, you’re sure to be in for an untold quantity of build errors before you’re up and running. Alternatively, you could install the service as a framework provided it was compiled correctly for your current Xcode version. Or, you can do it the fool-proof way, and just include the Objective-C files into your application and add a bridging header. 

(Dear Apple, please see Nuget Package Manager…)

This is my preferred approach because it's timeless. Doesn’t matter which version of Swift you are using or what version of Xcode you’re using. It just works.

So, assuming you’ve got an existing Xcode project and the Azure service you wish to install downloaded to your computer. We can get started.

In the downloaded folder, look for the Objective-C source code. In the case of Azure Storage Client Library, its a folder named after the service. So, find something like this:

1folder.png

Next, create a new Group in your Xcode project and name it whatever you like. I just named mine “Azure Storage”. Once you have the folder created, go ahead and drag all of the Objective-C files from the folder you downloaded to your new Xcode project folder. Select copy if needed and then “Finish”.

Xcode will then ask you if you want to create a bridging header for these Objective-C files, select “Create Bridging Header”, we’ll need this bridging header to expose Azure to our Swift code.

2bridgingheader.png

By default, Xcode will place that bridging header in with off of Azure’s Objective-C files, I personally move this file into my own project hierarchy since I might reuse this file to incorporate other Objective-C libraries.

If we choose to move it, we’ll need to inform Xcode where we moved it to. We can update our bridging header path by editing the location stored under Objective-C Bridging Header in our Build Settings

Since I moved my bridging header into the main project hierarchy, I had to update my path to “AzureStorageExample/AzureStorageExample-Bridging-Header.h”

3buildsettings.png

Once we have that updated, Xcode will, once again, be able to expose Azure’s Objective C code to our Swift code. Of course, this wouldn’t be a day in the life of an Xcode user if there wasn’t a follow-up error.

4filenotfound.png

Looks like Azure has a dependency on `libxml/xmlwriter.h`, which is pretty simple to resolve. We’ll just have to tell Xcode where the file is. 

We’ll go back into our build settings and select “All” and then “Levels” from our build settings and then search for “Search Paths”. Under header search paths, we’ll add a search path of “${SDKROOT}/usr/include/libxml2”.

If we rebuild we’ll get a gang of errors. We’ve got one last step here.

Go to build phases > link library with binaries and add libxml2.tbd to your project.

6libxml2.png

Rebuilding now should result in a successful deployment.

7proof.png

If you run into any issues you can download the example project from GitHub here. You can also feel free to comment below and I'll do my best to help.

 

How to create a Line Chart using ios-charts

This tutorial is part of a series on iso-charts, if you haven't looked over the introduction I'd advise doing so before continuing. In this tutorial we'll be making a single line Line Chart using iOS-charts.

We’ll begin by creating a new single view application, we’ll name it and click create.

Go to the main.storyboard and search for “View” in the Object Library and you’ll see it near the bottom of the list. Drag the view out onto your view controller, position it however you like and add some basic constraints.

In the identity inspector, set your class to “LineChartView”, if you aren’t seeing an option for such a class please make sure you’ve followed the installation steps listed here.

If everything has gone well your main.storyboard should look like this:

20151018043029addLineChartView.png

Setting up our LineChartView object

Click on your Assistant Editor to reveal your ViewController.swift code. We’ll need to add an import statement and adopt a protocol before we can begin wiring up our Line Chart. Modify your class signature to look like this:

    
import Charts
class ViewController: UIViewController, ChartViewDelegate { //...
    

Now we can control drag from our View to our ViewController class and create an outlet named lineChartView with a type of LineChartView.

20151018043325Screenshot 2015-10-17 22.34.21.png
    
@IBOutlet weak var lineChartView: LineChartView!

We can now start setting the properties of our lineChartView object. in your viewDidLoad add the following lines of code:

    
override func viewDidLoad() {
    super.viewDidLoad()    
    // 1
    self.lineChartView.delegate = self
    // 2
    self.lineChartView.descriptionText = "Tap node for details"
    // 3
    self.lineChartView.descriptionTextColor = UIColor.whiteColor()
    self.lineChartView.gridBackgroundColor = UIColor.darkGrayColor()
    // 4
    self.lineChartView.noDataText = "No data provided"
    // 5
    setChartData(months)
        
}

func setChartData() {

}

  1. We set the ChartViewDelegate to our ViewController.
  2. We change the `descriptionText` that will appear at the bottom of our chart.
  3. Here, we set our description text color to white and our grid background color to dark grey.
  4. We make sure our user get feedback if there is not data provided.
  5. Finally, we call / create a custom function that will add data to our chart.

Setting Data

Of course, a very common thing to chart is money over time, and that what we’ll do in this example. So we’ll modify the signature of our setChartData method call to take an array of strings for our months.

    
setChartData(months) // in viewDidLoad
func setChartData(months : [String]) { }
	

And we’ll have to create an array of months as a class level object. While we’re at it, lets go ahead and add three variables that hold our month-to-month dollar amount.

    
let months = ["Jan" , "Feb", "Mar", "Apr", "May", "June", "July", "August", "Sept", "Oct", "Nov", "Dec"]
    
let dollars1 = [1453.0,2352,5431,1442,5451,6486,1173,5678,9234,1345,9411,2212]

For this part of the tutorial, we'll set our chart up with just one set of data, which will create a single red line across our graph. First the code, then the explanation.

    
func setChartData(months : [String]) {
    // 1 - creating an array of data entries
    var yVals1 : [ChartDataEntry] = [ChartDataEntry]()
    for var i = 0; i < months.count; i++ {
        yVals1.append(ChartDataEntry(value: dollars1[i], xIndex: i))
    }
        
    // 2 - create a data set with our array
    let set1: LineChartDataSet = LineChartDataSet(yVals: yVals1, label: "First Set")
    set1.axisDependency = .Left // Line will correlate with left axis values
    set1.setColor(UIColor.redColor().colorWithAlphaComponent(0.5)) // our line's opacity is 50%
    set1.setCircleColor(UIColor.redColor()) // our circle will be dark red
    set1.lineWidth = 2.0 
    set1.circleRadius = 6.0 // the radius of the node circle
    set1.fillAlpha = 65 / 255.0
    set1.fillColor = UIColor.redColor()
    set1.highlightColor = UIColor.whiteColor()
    set1.drawCircleHoleEnabled = true
        
    //3 - create an array to store our LineChartDataSets
    var dataSets : [LineChartDataSet] = [LineChartDataSet]()
    dataSets.append(set1)
        
    //4 - pass our months in for our x-axis label value along with our dataSets
    let data: LineChartData = LineChartData(xVals: months, dataSets: dataSets)
    data.setValueTextColor(UIColor.whiteColor())
        
    //5 - finally set our data
    self.lineChartView.data = data            
}
  1. We start by creating an array of ChartDataEntry items, to which we'll create and append one item for every value stored in our dollars array.
  2. We create a LineChartDataSet that take our array as its first parameter and a label for its second, this dataset represents the line we'll be creating. We continue by setting the attributes that belong to this class object.
  3. Since we're ultimately on a path to create a multi-lined array, we'll create a data set array that will just hold our single set.
  4. Create a data object that takes our months and our single data set.
  5. Set it as our lineCharView objects data 

Build and run

Build and run and you should see your first chart, congratulations, it gets better from here so move on to part II, where we augment this chart with multiple lines.

20151018050325Screen Shot 2015-10-18 at 12.02.56 AM.png

Passing data with the protocol delegate pattern

Delegates are the standard way we pass data between two view controllers. I recently wrote a tutorial on how to pass data by overriding prepareForSegue. In this tutorial I’ll show you how to pass messages back and forth using the “Standard” protocol pattern and without using any segues.

There won’t be an in-depth discussion about protocols or delegates here, for that I defer to Apples Swift Programming Language Guide or one of the many excellent books or online resources that have already covered this topic ad nauseam. 

What I will do, is create a succinct-minimal-working delegate pattern example, using naming conventions that will make it clear how the delegate pattern works. 

Setting Up

We’ll start by creating a single view application.

We’ll add a second View Controller to our storyboard which we’ll need to create a new CocoaTouch file for.  We’ll do that by clicking add new > cocoa touch class >  find UITableViewController… name it PresentedTableViewController and create. 

This controller class will belong to our “presented” view controller, so make sure you add it in your storyboard. Your final storyboard should look like this:

In the first View Controller, lets add a button and a label. We don’t need anything fancy for this exercise, just slap em out there. With split view open, control drag an outlet from your label and name it labelOutlet, and control drag an action from your button and name it doPresent. You should now have something like this:

    
class ViewController: UIViewController {
    
    @IBOutlet weak var textOutlet: UILabel!
    @IBAction func doPresent(sender: AnyObject) {

    }
    
    override func viewDidLoad() {
        super.viewDidLoad()   
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

With an interface that looks like this.

Now, select the other View Controller, the PresentedViewController and add a Text Field and a Button to the View. Just as before, control drag from your Text Field and create an outlet named “textFieldOutlet” and repeat that for your button, this time making an action named “doDismiss”. Your code should look like this:

    
class PresentedViewController: UIViewController {
   
    @IBOutlet weak var textFieldOutlet: UITextField!
    @IBAction func doDismiss(sender: AnyObject) {

    }
    
    override func viewDidLoad() {
        super.viewDidLoad()

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

And your interface should resemble mine:

Protocol

The Standard pattern is to add our protocol to top of our “presented” class, though I’ve seen people create separate files for these too. We’ll do it the standard way here.

At the top of your PresentedViewController class, just above your class declaration we’ll add the following code.

    
protocol PresentedViewControllerDelegate {
    func acceptData(data: AnyObject!)
}

The convention is to adopt the presented classes name with “Delegate” afterwords. Inside our protocol we’ve defined one function, acceptData that takes AnyObject. I should note that we can define any number of functions and properties inside of our protocol, but no logic. 

Think of a protocol as a binding contract between the protocol and any class that implements it. This contract forces said classes to abide by it's "protocol" and in doing so creates a level of "trust" from the compiler. This "trust" enables us to communicate between two separate bodies of code.

PresentedViewController

We’ll add the required code necessary to receive data from the view controller, but this wont be a one way dialogue. We’ll wire this up so it will send data back to the View Controller as well.

At the class level, add two properties. One being a variable called delegate with a type PresentedViewControllerDellegate. Which will look like this:

    
// create a variable that will recieve / send messages
// between the view controllers.
var delegate : PresentedViewControllerDelegate?
// another data outlet
var data : AnyObject?

We’ll add a print statement in our viewDidLoad that will receive our “data” object from the ViewController. 

    
 override func viewDidLoad() {
    super.viewDidLoad()
    print("\(data!)")

}

Now, we’ll handle our Text Field and Button by adding the following lines of code inside the doDismiss method:

    
@IBAction func doDismiss(sender: AnyObject) {
    if textFieldOutlet.text != "" {
        self.presentingViewController!.dismissViewControllerAnimated(true, completion: nil)
    }
}

You’ll notice that I’ve added a simple check to validate that the text field has content before we call presentingViewController!.disissViewControllerAnimated.

Finally, we’ll add viewWillDisappear which will  send our Text Field data to our delegates acceptData method. 

    
override func viewWillDisappear(animated: Bool) {
    super.viewWillDisappear(animated)
    if self.isBeingDismissed() {
        self.delegate?.acceptData(textFieldOutlet.text)
    }
}

Back in our ViewController, we’ll add PresentedViewControllerDelegate to our class signature like this:

    
class ViewController: UIViewController, PresentedViewControllerDelegate {//...

We’ll proceed with our protocol implementation by adding its acceptData(data:AnyObject!) method, which silences the compiler. Inside that method we’ll simply update our text label with the message we entered in PresentedViewController.

    
func acceptData(data: AnyObject!) {
    self.textOutlet.text = "\(data!)"
}

Finally, we’ll address the doPresent action we created earlier. Since in this exercise we aren’t passing values via Segue, we’ll need a method of traversing our data. In this case, it’s by presenting the view controller. We’ll create an instance of our PresentedViewController and with that instance, we can bind to it properties before presenting. That code looks like this:

    
@IBAction func doPresent(sender: AnyObject) {
    let pvc = storyboard?.instantiateViewControllerWithIdentifier("PresentedViewController") as! PresentedViewController
    pvc.data = "important data sent via delegate!"
    pvc.delegate = self
    self.presentViewController(pvc, animated: true, completion: nil)
}

Build And Run

When click the next button you should see the next view controller along with a print line in your console. If you enter some text in the text field and hit your go back button, you’ll see the text you entered assigned to you label.

If you have any troubles, feel free to download the Project Files and browse my code. You can also ask questions in the comments and we’ll get your code running.

Passing values using prepareForSegue

Set Up

The first thing we'll do is create a new single view application. Once the project is loaded, delete your ViewController.swift from your Project Manager as well as from your Storyboard.

Once you have this find a Navigation Controller in your object library and drag it out onto your storyboard, select your Navigation Controller in your StoryBoard and choose "Is Initial View Controller" in your Attributes Inspector. Now that you've got your initial view controller set up let's add a new Cocoa class to your project by right-clicking your main project folder in Project Manager and selecting "New File...". Select, iOS > Source > Cocoa Touch Class and then select next. Create a UITableViewController like I've done here.

We'll assign this new class as our table view in our storyboard by selecting our table view and adding our newly created class in our Identity Inspector it'll look like this.

Before we move on, click on your prototype cell in your storyboard and give it an Identifier of "Cell" and give it a Style of Basic for this example.

Now that we have our main controller lets add a View Controller that we'll send our values to. Drag a View Controller our onto your storyboard just as we did for our Navigation Controller. And just as we did with our FirstTableViewController, we'll add another Cocoa Touch Class, this time uses a UIViewController and we'll name it SecondViewController. Remember to add your new class to your View Controller in your storyboard as we did before for our FirstViewController.

Finally, we'll create a segue by control dragging from our FirstTableViewController to our SecondViewController like so.

Click on your new segue and in your Attributes Inspector add an Identifier, I chose "SendDataSegue" for this example.

We'll also want to add a label to our new View Controller, place it dead center and give it some simple constraints. Finally, create an outlet in your SecondViewController.swift by control dragging from your outlet to your class. 

Name your outlet viaSegueLabel, it should look like this:

@IBOutlet weak var viaSegueLabel: UILabel!

Code

Open your SecondViewController and at the class level, add a property called viaSegue like this:

var viaSegue = ""

Then inside your view controller we'll assign the value of viaSegue to our viaSegueLabel, add the following code to your viewDidLoad:

override func viewDidLoad() {
        super.viewDidLoad()

        viaSegueLabel.text = viaSegue
        // Do any additional setup after loading the view.
    }

We're finished with our viewController, lets move on to our tableViewController.

In our FirstTableViewController lets first quickly set our numberOfSectionsInTableView to 1 and numberOfRowsInSection to 10, I won't go into any detail here:

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        // #warning Incomplete implementation, return the number of sections
        return 1
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete implementation, return the number of rows
        return 10
    }

Now, let's add a method called prepareForSegue, which does exactly what it sounds like it does, it prepares for the upcoming segues.  To learn more about prepareForSegue see Apples Developer Guide. Here's the implementation:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "SendDataSegue" {
            if let destination = segue.destinationViewController as? SecondViewController {
                
                let path = tableView.indexPathForSelectedRow
                let cell = tableView.cellForRowAtIndexPath(path!)
                destination.viaSegue = (cell?.textLabel?.text!)! 
            }
        }
    }

In this method, we're determining which segue we're preparing for with segue.identifier, we're then using an if let to safely attempt to assign a segue with a destinationViewController with a type of ours. Getting the type lets us model the properties within, thus giving us access to our viaSegue in our SecondViewController, which we take advantage of here.

We haven't actually set up a segue yet, we'll do that now. Lets add a new tableView override function for didSelectRowAtIndexPath, this will allow us to trigger a segue from whichever row we select. The implementation is simple so I'll stop rambling.

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        _ = tableView.indexPathForSelectedRow!
        if let _ = tableView.cellForRowAtIndexPath(indexPath) {
            self.performSegueWithIdentifier("SendDataSegue", sender: self)
        }
        
    }

It's important to note that we are using our segue by it's identifier "SendDataSegue".

Last but not least, lets make sure our cells have some data to pass. Since we used the Basic setup for our prototype cell earlier, we've got access to a textLabel by default, so lets use it:

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)
        
        // Configure the cell...
        cell.textLabel?.text = "Hello from cell #\(indexPath.row))"
        
        return cell
    }

Build and Run

If everything as gone according to my master plan, you should've passed the value you selected. If you're having problems drop a line below or check out the project files.