Working with NEHotspotHelper

I had to evaluate NEHotspotHelper for a project I am working on. The documentation from Apple is sordid to say the least. Here are a few bits and pieces of information that will help you understand the API better.

Apply for the Network Extension Entitlement

You may already know this but to use the NEHotspotHelper API you will need to apply for the Network Extension Entitlement from Apple. It may take several days for Apple to approve or reject your application.

Modify your Provisioning Profiles

Once you are granted the entitlement, go to iOS developer console and add the entitlement to your developer and deployment provisioning profiles. Many on the Internet will tell you to create a new set of provisioning profiles. That is not necessary. You can add entitlements to existing profiles. Download these modified profiles and re-install them on your development machine.

Add Background Mode

In our case we wanted to use the Wi-Fi Hotspot Authentication API of NEHotspotHelper. This requires the app to run in the background mode. Edit your Info.plist file and add the network-authentication background mode.

Use the Wi-Fi Hotspot Authentication API

The purpose of the authentication API is to implement custom application level logic to authenticate the connection to a WIFI hotspot. This authentication is a two step process:

  1. First connect to the hotspot providing the hotspot’s password.
  2. Then perform custom authentication. For example, this can involve communicating with a server and passing additional credentials.

This process uses a callback based approach. The first thing you do is register a closure or lambda that is invoked at various times with a command object.

let options: [String: NSObject] = [kNEHotspotHelperOptionDisplayName : "Join this WIFI" as NSObject]
let queue: DispatchQueue = DispatchQueue(label: "com.mobiarch", attributes: DispatchQueue.Attributes.concurrent)

NSLog("Started wifi scanning.")

NEHotspotHelper.register(options: options, queue: queue) { (cmd: NEHotspotHelperCommand) in
  NSLog("Received command: \(cmd.commandType.rawValue)")
}

There are three command types that you need to be aware of to perform custom authentication.

  • NEHotspotHelperCommandType.filterScanList – iOS will call your closure with this command type when the user opens the WIFI Settings page. You can obtain a list of all available hotspots from the command. Your code needs to create a filtered list of hotspots that you will like to authenticate with. You also need to set the WIFI password for these hotspots at this point. Once the closure returns, iOS will show the display name below the filtered hotspots. The display name is set using the kNEHotspotHelperOptionDisplayName option as shown in the code above. Note: Filtering does not really remove other hotspots from the list in the WIFI settings page. It is simply meant to identify the networks that your app deems appropriate for authentication.
  • NEHotspotHelperCommandType.evaluate – If the user taps on one of your filtered hotspots and makes a connection the closure is called again with an evaluate command. You can perform custom business logic to evaluate the connected hotspot. If it is appropriate, your code should set a high confidence level for the network.
  • NEHotspotHelperCommandType.authenticate – After the evaluation phase the closure is called again with an authenticate command. Your code can now perform custom authentication logic and respond with a success or failure status. If successful the connection is finally established.

Remember, your callback closure will only be called if the user opens the WIFI Settings page. Also, the user must manually initiate a connection to a hotspot. Your code can not automatically connect.

A sample code for the lambda can look like this.

{ (cmd: NEHotspotHelperCommand) in
    NSLog("Received command: \(cmd.commandType.rawValue)")
    
    if cmd.commandType == NEHotspotHelperCommandType.filterScanList {
        //Get all available hotspots
        var list: [NEHotspotNetwork] = cmd.networkList! 
        //Figure out the hotspot you wish to connect to
        let desiredNetwork : NEHotspotNetwork? = getBestScanResult(list) 

        if let network = desiredNetwork {
            network.setPassword("password") //Set the WIFI password

            let response = cmd.createResponse(NEHotspotHelperResult.success)

            response.setNetworkList([network])
            response.deliver() //Respond back with the filtered list
        }
    } else if cmd.commandType == NEHotspotHelperCommandType.evaluate {
        if let network = cmd.network {
            //Set high confidence for the network
            network.setConfidence(NEHotspotHelperConfidence.high) 

            let response = cmd.createResponse(NEHotspotHelperResult.success)
            response.setNetwork(network)
            response.deliver() //Respond back
        }
    } else if cmd.commandType == NEHotspotHelperCommandType.authenticate {
        //Perform custom authentication and respond back with success
        // if all is OK
        let response = cmd.createResponse(NEHotspotHelperResult.success)
        response.deliver() //Respond back
    }
}

For additional details about the different command types, see the official document.

Running Instrumented Test in Android

An instrumented test is a fancy name for a test that runs within the Android device in the same process space as your app. This lets you test code that relies on Android SDK calls. The official guide is horridly incomplete. Here are a few quick notes.

Package Conflict

Android Studio builds a separate APK just for instrumented test. This runs in the same process space as the APK for the main app. Unfortunately this means both APKs must have no conflicting package dependencies. But the Internet is full of example of conflict with the com.android.support:support-annotations package. You will need to force both APK to use a higher version.

androidTestCompile 'com.android.support.test:runner:0.5'
androidTestCompile 'com.android.support.test:rules:0.5'

//Force same version
androidTestCompile 'com.android.support:support-annotations:23.2.0'
compile 'com.android.support:support-annotations:23.2.0'

This is just an example only. By the time you read this newer versions may be available.

Location of the Test Java File

You have to create the test Java file in the androidTest folder. This way it will get packaged with the test APK.

Annotation

An instrumented test class needs to have @RunWith and @SmallTest annotation.

A sample template class:

import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.SmallTest;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

@RunWith(AndroidJUnit4.class)
@SmallTest
public class InstrumentedTests {
 @Test
 public void testCaching() {
   assertNotNull("Hello");
   assertTrue(true);
   assertEquals("One", "One");
 }
}

Simplify Sqlite Access from Swift

Using the SQLite C API has always been a pain. Now with Swift it’s practically unworkable. I think most people are using some kind of a wrapper library like FMDB. I took a few hours to evaluate various libraries available:

Out of these I liked GRDB the most. Here’s a quick tutorial on how to do the most common tasks in GRDB. We will assume a schema like this.

create table if not exists Employee (
    id INTEGER NOT NULL PRIMARY KEY,
    name TEXT NOT NULL,
    salary real not null,
    last_update datetime NOT NULL
);

Using GRDB

I use Cocoapod to add GRDB to my project. And then from any Swift file where you need to use GRDB add:

import GRDB

Opening a Connection

A connection is represented by a DatabasePool object. Here we connect to a file database.dat within the app’s Documents directory.

let paths = NSSearchPathForDirectoriesInDomains(
    .DocumentDirectory, .UserDomainMask, true);
let docsDir = paths[0];
let dbFile = docsDir + "/database.dat";

let db = try! DatabasePool(path: dbFile)

A connection is closed when the DatabasePool object gets destroyed.

Inserting a Row

This will add a new row to the Employee table.

try! db.execute(
  "INSERT INTO Employee (name, salary, last_update) VALUES (?, ?, ?)", 
  arguments: ["Daffy Duck", 24000.00, NSDate()])

Note how the Swift data types in arguments: match the SQLite data types.

Query

To query by primary key or any other clause that is expected to return a single row do this.

if let row = Row.fetchOne(db, 
  "select * from Employee where id=?", 
  arguments: [1]) {
    let name : String = row.value(named: "name")
    let lastUpdate : NSDate = row.value(named: "last_update")
    let salary : Double = row.value(named: "salary")

    print("Found employee: \(name) \(lastUpdate) \(salary)")
} else {
    print("Could not find employee with that ID.")
}

The Row.fetchOne() method returns an optional Row object. Using the options makes it super easy to tell if the query returned anything or not.

The Row class has different value(named:) methods that return different data types. Here the compiler has automatically picked the correct value(named:) based on the data type of the variable on the left hand side. Type inference has made things safer and easier.

When a query returns multiple rows, do this:

let rows = Row.fetchAll(db,
    "select * from Employee where salary > ?",
    arguments: [25000.00])

for row in rows {
    let name : String = row.value(named: "name")
    let lastUpdate : NSDate = row.value(named: "last_update")
    let salary : Double = row.value(named: "salary")

    print("Found employee: \(name) \(lastUpdate) \(salary)")
}

Updating a Row

Updates are done using the same db.execute() method that we have used to insert rows.

try! db.execute("update Employee set salary=? where id=?", 
  arguments: [40000.00, 4])

Deleting Rows

Deleting a single row using primary key:

try! db.execute(
  "delete from Employee where id = ?", arguments: [1])

Bulk delete is done the same way:

try! db.execute(
  "delete from Employee where salary > ?", 
  arguments: [25000.00])

Dependency Management Using Cocoapods

Cocoapods is a Swift and Objective-C dependency management tool like NPM is for Node and Gem is for Ruby. Swift now has its own official package manager. But it’s still very new. Until it matures fully you can keep using Cocoapods.

Installing Cocoapods

Use Gem to install Cocoapods

sudo gem install cocoapods

A few things may go wrong.

You may see this error:

ERROR:  While executing gem ... (Errno::EPERM) Operation not permitted

If you see that try installing Cocoapod like this:

sudo gem install -n /usr/local/bin cocoapods

You might see a Insecure world writable dir warning. This can be safely ignored.

enter image description here

Declaring Dependencies

Create an Xcode project if you don’t already have one. Here, we will assume that the name of your project is MyApp. In the root folder of the project create a file called Podfile.

platform :ios, '9.0'
use_frameworks!

target 'MyApp' do
    pod 'AFNetworking', '~> 2.0'
    pod 'FLKAutoLayout'
end

This states that our project requires AFNetworking version 2.0 or higher. It also depends on the latest version of FLKAutoLayout.

Installing Packages

When you install a package Cocoapod downloads the source files of the package and any other packages that it depends on. Cocoapod creates a new project called Pods and adds these source files there. It then creates a new workspace and adds your project and the Pods project to the workspace.

Since Cocoapod modifies your Xcode workspace, it is better that you shutdown Xcode while you are installing a package.

Make sure that your Podfile is properly defined. From the root folder of your project run:

pod install

enter image description here

There are a few things you have to do for your project to compile correctly:

  1. Shutdown Xcode if it is running.
  2. Double click the workspace file to open it and not the project file. In our case that will be the MyApp.xcworkspace file.

enter image description here

Now you will see the Pods project added to the workspace. Source code for the downloaded packages will be there.

enter image description here

Cocoapod will also modify your project to link in the code from all packages in the Pods project.

You are now ready to use classes from these packages.

Removing Packages

To remove a package simply delete it from Podfile. Then from the root of the project run:

pod update

Using Pod Packages in Unit Tests

So far in this article we have added packages only to the application’s main target. If you try to use these packages from unit tests you will get a compilation error. The solution is to also add the packages to the unit test targets. Find out the name of the unit test target and specify the packages used from there.

platform :ios, '9.0'
use_frameworks!

target 'MyApp' do
    pod 'AFNetworking', '~> 2.0'
    pod 'FLKAutoLayout'
end

#Add any package you need to the unit test target
target 'MyAppTests' do
    pod 'AFNetworking', '~> 2.0'
    pod 'FLKAutoLayout'
end

Run pod update to set things up.

Reactive TCP Client Using Akka Framework

Reactive or asynchronous networking code produces maximum throughput using the least amount of resources. If you need to communicate with a web server the play.api.libs.ws.WS class will let you write a reactive client. This class wraps over the AsyncHttpClient Java library which uses Java NIO under the covers. But if you need to write a custom TCP client that communicates with a server using a proprietary protocol then you are on your own. Fortunately the Akka actor framework can significantly simplify this process. In this article we will develop a simple reactive TCP client using Akka.

If you have a Play project then Akka is already there as a dependency. You don’t have to manually add Akka as a dependency.

The Business Requirements

We will write a client that will connect to a server and send a short request message. It will then receive a short response. The messages are so short that we can expect to read or write them in a single read or write call without overflowing the networking buffer of the OS. We make this assumption to keep our client code as simple as possible. In real life partial reads and writes are definite possibilities. We are not going to address that here.

In this article our client will send a HTTP request to http://www.example.com. We use HTTP so that you can try the code out without having to write your own server. The basic principles will be same even for a proprietary server.

The API will be very similar to the WS class mentioned above. The client should return a Future. This is necessary because Play requires an asynchronous controller to return a Future[Result].

Getting to Know Akka Actors

We will develop the TCP client code in an actor class. Let’s take a look at some of the unique aspects of an actor.

Actors Do Things

An actor encapsulates actions. It extends the akka.actor.Actor trait. All the action logic goes inside the receive method. A basic skeleton actor will be like this:

import akka.actor.Actor

class MyActor(someState: String) extends Actor {

  def receive = {
    //Action logic here

  }

} 

Actors are Discovered and Not Instantiated

You never instantiate an actor class using new. You discover an actor instance either in the local process or in another machine in the network. There are several ways to discover an actor using akka.actor.ActorSystem. Here we will only discuss how to discover an actor in the local process. First we obtain a reference to an ActorSystem. You can use any name for your system.

val sys = ActorSystem.create("MyActorSystem")

Then you use akka.actor.Props to define how to locate the actor. We will supply the class name of the actor and any constructor argument.

val p = Props(classOf[MyActor], "Some data")

Finally, we discover the actor like this:

val actor = sys.actorOf(p) //Find the actor

You Interact with an Actor Using Messages

You never ever directly call a method of an actor. You ask an actor to do something by sending it a message. You send a message using the ! operator. Almost any type of object can be sent as a message.

actor ! "Some message" //String message
actor ! 20 //Int message

The actor receives these messages from its receive method.

class MyActor(someState: String) extends Actor {
  def receive = {
    case str: String => println(s"String message: $str")
    case i: Int => println(s"Int message: $i")
    case _ => println("Bizarre message from outer space.")
  }
} 

OK, that is all you need to know to get started developing a TCP client actor.

Write the TCP Client

Create a class called TcpClient. Add these import statements.

import java.net.InetSocketAddress
import akka.actor.Actor
import akka.io.{IO, Tcp}
import akka.util.ByteString
import scala.concurrent.Promise
import Tcp._

The client will need these state variables:

  1. The address of the server to connect to.
  2. The request message data.
  3. The scala.concurrent.Promise to complete when response comes back. We can obtain a Future from the promise as we will see later.

So, the class definition will have these three state variables:

class TcpClient(remote: InetSocketAddress, 
  requestData: String, 
  thePromise: Promise[String]) extends Actor {

}

As soon as the actor is created we will like to establish connection with the server. This is done like this.

class TcpClient(remote: InetSocketAddress, 
  requestData: String, 
  thePromise: Promise[String]) extends Actor {

    import context.system

    println("Connecting.")
    IO(Tcp) ! Connect(remote)
}

Basically IO(Tcp) returns reference to an actor. We send it a Connect message to ask it to setup a connection. A reference to our own actor (TcpClient) is sent along with the Connect message as an implicit argument.

After the connection is established or an error occurs the TCP actor will send us a message back. All we have to do is intercept these messages from our receive method.

class TcpClient(remote: InetSocketAddress, requestData: String, thePromise: Promise[String]) extends Actor {
    import context.system

    println("Connecting.")
    IO(Tcp) ! Connect(remote)

    def receive = {
        case CommandFailed(_: Connect) =>
            println ("Connection failed.")
            context stop self

        case c @ Connected(remote, local) =>
            println ("Connect succeeded.")
            val connection = sender()
            connection ! Register(self)

            println("Sending request message.")
            connection ! Write(ByteString(requestData))
        case _ => println("Something else is up.")
    }
}

A Connected message signifies a successful connection. In that case we send the connection actor a Register message to set our TcpClient actor as receiver of various IO events (like socket is readable or writable). Next, we write the request message. This is done by sending a Write message to the connection. Data is always represented using akka.util.ByteString.

After this our actor will receive messages every time something interesting happens to the connection. We are specifically interested in these events:

  • The attempt to write the request data has failed.
  • The socket is readable indicating the server has written some response data.
  • The server has closed the connection.

There are many other possible events that can happen. But we will ignore them for now.

To process these messages we use a separate receive method. This is defined using context become. The full code for the actor will now look like this.

class TcpClient(remote: InetSocketAddress, 
  requestData: String, 
  thePromise: Promise[String]) extends Actor {
    import context.system

    println("Connecting")
    IO(Tcp) ! Connect(remote)

    def receive = {
        case CommandFailed(_: Connect) =>
            println ("Connect failed")
            context stop self

        case c @ Connected(remote, local) =>
            println ("Connect succeeded")
            val connection = sender()
            connection ! Register(self)
            println("Sending request early")
            connection ! Write(ByteString(requestData))

            context become {
                case CommandFailed(w: Write) =>
                    println("Failed to write request.")
                case Received(data) =>
                    println("Received response.")
                    //Fulfill the promise
                    thePromise.success(
                        data.decodeString("UTF-8"))
                case "close" =>
                    println("Closing connection")
                    connection ! Close
                case _: ConnectionClosed =>
                    println("Connection closed by server.")
                    context stop self
            }
        case _ => println("Something else is up.")
    }
}

Note how we are fulfilling the promise once we receive a response message.

Normally a server closes connection. Here we allow someone to send a “close” String message to our actor to close the connection from the client side.

Use the Actor from a Play Action

I will assume that you know the basics of asynchronous controller development. If not read this official guide on the subject. Basically, the controller method needs to return a Future[play.api.mvc.Result].

Add these import statements to your controller.

import java.net.InetSocketAddress
import akka.actor.{Props, ActorSystem}
import play.api.libs.concurrent.Execution.Implicits._
import play.api.mvc._
import scala.concurrent.Promise

Importing play.api.libs.concurrent.Execution.Implicits is necessary to add an implicit execution environment for the Akka framework.

The skeleton of our controller code will look like this.

class Application extends Controller {

  def index = Action.async {

  }

}

In our index method, add these lines to discover the TcpClient actor.

    val host = "example.com"
    val promise = Promise[String]()
    val props = Props(classOf[TcpClient],
      new InetSocketAddress(host, 80),
      s"GET / HTTP/1.1\r\nHost: ${host}\r\nAccept: */*\r\n\r\n",
      promise)

    //Discover the actor
    val sys = ActorSystem.create("MyActorSystem")
    val tcpActor = sys.actorOf(props)

Next, we obtain the Future associated with the Promise by calling promise.future. Then we convert the Future[String] into Future[Result] and return it.

    //Convert the promise to Future[Result]
    promise.future map { data =>
        tcpActor ! "close"
        Ok(data)
    }

The full code of the index method will now look like this.

  def index = Action.async {
    val host = "example.com"
    val promise = Promise[String]()
    val props = Props(classOf[TcpClient],
      new InetSocketAddress(host, 80),
      s"GET / HTTP/1.1\r\nHost: ${host}\r\nAccept: */*\r\n\r\n", promise)

    //Discover the actor
    val sys = ActorSystem.create("MyActorSystem")
    val tcpActor = sys.actorOf(props)

    //Convert the promise to Future[Result]
    promise.future map { data =>
        tcpActor ! "close"
        Ok(data)
    }
  }

Fully Working Code

Get the complete sbt project from GitHub.

About Partial Writes

When you write to a socket your OS will store the data in a buffer and then send data from this buffer over the network interface hardware. The OS has a limited amount of space to store this data. If the written data is large or when there are many writes going on at the same time the OS can easily run out of buffer space. If that happens the OS won’t be able to fully store the written data in the available buffer space. The write call will do a partial write and will let you know how much data was written. The socket becomes unwritable while there is no more buffer space available. It is the responsibility of the program to retry writing the remaining data when the socket becomes writable again.

Akka helps you take care of this problem. When you write a chunk of data to a connection Akka will keep retrying until the entire chunk is fully written. Depending on how much data you tried to write and how busy the machine is it my take Akka several attempts and some time for it to fully write the data. At least from the application’s point of view you don’t have to worry about this. You do a single write call and Akka takes care of sending the data, in multiple attempts if needed. However there is a catch. Akka can only retry writing a single chunk of data. Any attempt to write another chunk of data while a previous chunk is still in the middle of getting fully written will fail. Basically the application code will need to wait for the previously written data to be fully written by Akka before it can write again. To deal with this restriction Akka can let your application know when a previous write has fully completed. This is done using an acknowledgment mechanism. Let’s see this in the event handling code of an actor. In the example below we write the HTTP request header and body in two separate write calls.

class TcpClient(remote: InetSocketAddress, 
  requestHeader: String, 
  requestBody: String,
  thePromise: Promise[String]) extends Actor {
    import context.system

    println("Connecting")
    IO(Tcp) ! Connect(remote)

    //Our acknowledgement data type
    case object MyAck extends Event

    def receive = {
        case CommandFailed(_: Connect) =>
            println ("Connect failed")
            context stop self

        case c @ Connected(remote, local) =>
            println ("Connect succeeded")
            val connection = sender()
            connection ! Register(self)
            println("Sending request header.")
            //Write the request header first
            //Supply the ack type with a write
            connection ! Write(ByteString(requestHeader), MyAck)

            context become {
                case CommandFailed(w: Write) =>
                    println("Failed to write request.")
                case MyAck => 
                    //Our last write has completed
                    println("Writing request body.")
                    //Safe to write the request body now.
                    connection ! Write(ByteString(requestBody))
                case Received(data) =>
                    println("Received response.")
                    //Fulfill the promise
                    thePromise.success(
                        data.decodeString("UTF-8"))
                case "close" =>
                    println("Closing connection")
                    connection ! Close
                case _: ConnectionClosed =>
                    println("Connection closed by server.")
                    context stop self
            }
        case _ => println("Something else is up.")
    }
}

Here, after we write the request header we have to wait for it to be fully written before we can write the body.

Testing Scala and Play with Scala Test + Play

There are many ways to unit test your Scala and Play code. At the time of this writing (Scala 2.11.6) I prefer using Scala Test + Play. It’s pretty easy to use and seems to let me do all I need.

Setup Dependency

Open build.sbt and add these dependencies.

libraryDependencies ++= Seq(
  jdbc,
  cache,
  ws,
  specs2 % Test,
  //Scala Test + Play
  "org.scalatest" %% "scalatest" % "2.2.1" % "test",
  "org.scalatestplus" %% "play" % "1.4.0-M3" % "test"
)

Write a Test Suite

Create a class that extends org.scalatestplus.play.PlaySpec.

import org.scalatestplus.play.PlaySpec

class MyTestSpec extends PlaySpec  {
  "Application" should {
    "Addition test" in {
      (2 + 2) mustBe 4
    }
    "Multiply test" in {
      (2 * 4) mustBe 8
    }
  }
}

Running a Test Suite

To run all tests using sbt run:

sbt test

In IntelliJ right click the test suite class – MyTestSpec – and select Run MyTestSpec.

Override Application Settings

If your Play application uses settings from application.conf then you probably wish to override some of the settings just during unit testing. This can be done fairly easily. Let’s say that our application.conf has this:

money-server-host="10.100.22.152"
money-server-port=3412

During unit testing we will like money-server-host to point to localhost. To do this we have to setup a play.api.test.FakeApplication.

import org.scalatestplus.play.{OneAppPerSuite, PlaySpec}
import play.api.Play._
import play.api.test.FakeApplication

class MyTestSpec extends PlaySpec with OneAppPerSuite {
  //Override test specific settings here.
  implicit override lazy val app: FakeApplication =
    FakeApplication(
      additionalConfiguration = Map(
        "money-server-host" -> "localhost"
      )
    )

  "Application" should {
    "Settings test" in {
      current.configuration.getString("money-server-host").get 
        mustBe "localhost"
    }
  }
}

Testing with a Device from Xcode 7.1

Starting with Xcode 7.1 a developer does not need to purchase a iOS Developer subscription to be able to test her apps using a device. All you need is an Apple ID. But, in reality, the process is not as straightforward. In this article I will show you how to test your app using a device from Xcode 7.1.

First of all create an Apple account (Apple ID) if you have not already done so. Next, add that account in Xcode from the preferences dialog (Xcode > Preferences menu).

enter image description here

Attach the iOS device to the laptop. Xcode will pick it up right away. You will be able to choose it from the list of targets as shown below.

enter image description here

Now, try to run the app from Xcode and you will get this message.

enter image description here

Back in the iOS device you will see a trust dialog.

enter image description here

Tap the Trust button.

Try running the app again. This time Xcode will show this message.

enter image description here

Ugh! Whatever. Wait for the symbols to be processed. Then run the app again from Xcode. This time:

enter image description here

Click Fix Issue button. Xcode will create the required certificates and provisioning profiles for you.

Run the app again from Xcode. This time:

enter image description here

Are you serious? What happens now? I can see that the app was installed properly on the device. When I tried to run the app from the device I got:

enter image description here

A bit of Googling followed. Basically, open your device’s Settings app. Then go to General > Device Management. Tap your Apple user ID.

enter image description here

Click the Trust YOUR_APPLE_ID button.

enter image description here

Tap Trust.

Run the app again from Xcode. This time Success!

Exception in Swift 2 for Java Developers

For Java developers Swift 2 has a familiar but strangely different exception handling system. An exception type must implement the ErrorType protocol. It’s an empty protocol so there is no method to implement.

class AppError : ErrorType {
    var message : String

    init(message: String) {
        self.message = message
    }
}

A function that needs to throw an exception must delcare the intention in its signature using the throws keyword. This is similar to Java except that no exception data type needs to be specified.

func evenSquared(val : Int) throws -> Int {
    if val % 2 == 0 {
        return val * val
    }

    throw AppError(message: "Not an even number")
}

If you call a function that throws exception you must either catch the exception or throw it again. This again is same as in Java. Catching exception is strangely different from Java. The code is wrapped in a do block. Each function that throws exception must be called using a try keyword.

func test() {
    do {
        let v = try evenSquared(3)
        print("return: \(v)")
    } catch let e as AppError {
        print("Application error: \(e.message)")
    } catch {
        print("Something else is wrong") //Catch all
    }
}

Note, as of Swift 2 you must have a catch all block. Otherwise you will get a compilation error – Errors thrown from here are not handled because the enclosing catch is not exhaustive. This is because we don’t specify the data type of the thrown exception in the function signature and the compiler has no way of knowing if you have handled all possible scenarios. This is pretty dumb IMHO.

In some cases an exception may be unrecoverable. Crashing the app will be the only option in that case. Coding for this situation is easy using try!.

func test() {
    let v = try! evenSquared(3)

    print("return: \(v)")
}

In this case the program will abort if evenSquared() throws an exception. Otherwise, the return value will be assigned to v.

You can also convert the value returned by a function that throws exception into an optional. This is done using try?.

func test() {
    let v = try? evenSquared(3)

    if let val = v {
        print("return: \(val)")
    } else {
        print("evenSquared failed.")
    }
}

I am not a huge fan of try? because it doesn’t reduce code size in any way and you lose the actual exception object that was thrown.

The functionality of Java’s finally block is achieved with the defer block in Swift. A defer block simply delays execution of the block until the enclosing block finishes.

func test() {
    defer {
        print("Defer block 1")
    }
    defer {
        print("Defer block 2")
    }
}

The defer blocks are executed in reverse order as they are encountered. So, the above will print:

Defer block 2
Defer block 1

A defer blocks executes at the end of the parent block.

func test() {
    if true {
        defer {
            print("Defer block 1")
        }
    }
    defer {
        print("Defer block 2")
    }
}

The above will print:

Defer block 1
Defer block 2

That is because the first defer block is within an if block that ends before the function block.

A defer block is not executed if it is not encountered during program execution.

func test(num : Int) {
    defer {
        print("Defer block 1")
    }
    if true {
        return
    }
    defer {
        print("Defer block 2")
    }
}

The above will print:

Defer block 1

The second defer block is never encountered and will not be executed.

In Swift you can clean up resources from the destructor (dinit block) of a class. This is not possible in Java. So you should not need to use defer blocks all that much. But they are useful for cleaning up resources that are not cleaned up by a destructor. For example, you can clean up temporary files created within a function.

func test() {
    var tmpFile = ... //Code to create a temp file
    defer {
        //Delete the temp file
    }
    //Do other things
}