Build an iOS App in Swift that uses a REST API and Stormpath

Overview

In this tutorial, we'll walk through how to build a simple note-taking application that allows a person to log in, edit, and save their personal notes on a server. This tutorial is for an iOS app in Swift, but you can also try out our Android tutorial here.

Here’s a demo of the app in action:

The backend for this application has already been built and is hosted at https://stormpathnotes.herokuapp.com, so we will take the perspective of an iOS developer using the Stormpath SDK to build against this existing backend. If you want to learn how to build this backend, check out the tutorial on building the Stormpath Notes Backend with Node.js.

Stormpath’s backend integrations expose a common API for mobile clients to connect to, which we’ll use the iOS SDK for. This allows your backend developers to protect additional endpoints with Stormpath authentication.

For Stormpath Notes’ backend, these are the exposed and protected endpoints:

GET /notes – returns the notes for the authenticated user in the form of a JSON object.

POST /notes – takes a JSON object with the notes and saves it for the authenticated user.

The JSON object takes the form of:

{"notes": "The notes the user saved"}

In case you’re curious, we used the following tools to build the backend for Stormpath Notes:

  • Express – A Node.js framework that allows us to write the /notes endpoints.
  • Express-Stormpath – Exposes a configurable REST API for our mobile clients within Express.
  • Stormpath – Allows us to store and authenticate users without having to create our own backend for it.
  • Heroku – Hosts the code for Stormpath Notes online.

Step 1. Setting up Our iOS Project

First, download or clone barebones project from Github.

git clone https://github.com/stormpath/stormpath-ios-notes-example.git

We have already built a barebones project with views already created, so we can get to the fun stuff quickly. 

Try running the application and clicking around. You will see we already have login, registration, and notes screens, with the basic ability to navigate between them. If you’d like to, you can also try browsing through the finished version of the example.

Step 2. Install Stormpath

Now that you have cloned the app and have it running, add the Stormpath iOS SDK to our iPhone app! We’ll use Cocoapods, a popular dependency manager for iOS projects, to install Stormpath.

To get started with Cocoapods, open up the Terminal and install it:

$ sudo gem install cocoapods

Then, navigate in the command line to the iOS project. We’re going to initialize this project in Cocoapods:

$ pod init

This creates a Podfile in your current directory, which stores information about libraries that your project depends on. Open the Podfile in your iOS project’s directory, and replace it with the following:

  # Uncomment this line to define a global platform for your project
# platform :ios, '8.0'
# Uncomment this line if you're using Swift
use_frameworks!

target 'Stormpath Notes' do
    pod 'Stormpath', '~> 1.2'
end

From the Podfile Cocoapods created, we added two lines:

use_frameworks! – installs the pods as a dynamic framework instead of a static library. It’s required for Stormpath. (More Info)

pod 'Stormpath', '~> 1.2' – installs Stormpath 1.2.x. We don’t need to specify the version, but we’re doing this so that any future updates we make are intentional.

After saving the Podfile, go back to the terminal and run pod install. This will now grab Stormpath from GitHub, and install it into your project. Quit out of your Xcode project, and you’ll see that Cocoapods generated a new file, Stormpath Notes.xcworkspace. You’ll open this up instead of Stormpath Notes.xcodeproj, as the workspace contains all of your dependencies in addition to your code.

Now that we have Stormpath installed, open AppDelegate.swift and add the following lines to the file:

Under the import UIKit statement:

import Stormpath

In application:didFinishLaunchingWithOptions:

  let APIURL = "https://stormpathnotes.herokuapp.com"
Stormpath.sharedSession.configuration.APIURL = NSURL(string: APIURL)!

This will configure your application to use our API server for Stormpath.

Note: Xcode may not recognize the import Stormpath command after installing it via Cocoapods. You can get rid of the error by pressing ⌘-B to rebuild your project.

Step 3. Add User Registration

Now that we have the Stormpath SDK embedded in your Xcode project, let’s add it to your RegisterViewController so that users can sign up for an account!

As earlier, we need to add import Stormpath to the top of the file so you can use the Stormpath SDK.

Looking through the file, you’ll notice a function called register:, which will be run whenever someone presses the register button in the app. Let’s start writing some code so that we can register a user.

In register:account:, we need to create a RegistrationModel, which represents the registration form for the user. Depending on the configuration in your backend, you may require different fields for registration. In this case, we are using the default of email, password, givenName, and surname:

  let newUser = RegistrationModel(email: emailTextField.text!, password: passwordTextField.text!)
newUser.givenName = firstNameTextField.text!
newUser.surname = lastNameTextField.text!

After we create the RegistrationModel, we can send it to the API server by calling Stormpath’s register method. Stormpath exposes itself as a singleton named sharedSession, so you can easily access it in any view controller without problems. When the registration completes, it calls back on the main thread (so you can do UI work) and sends an account and error parameter, both which are optionals.

In this case, we want to show an error alert if there’s an error, otherwise close the registration screen. Add below your previous code:

  // Register the new user
Stormpath.sharedSession.register(newUser) { (account, error) -> Void in
    if let error = error {
        self.showAlert(withTitle: "Error", message: error.localizedDescription)
    } else {
        self.exit()
    }
}

Note: showAlert:title:message: is a helper extension to UIViewController I’ve added to make displaying an UIAlert easier

Try running your app and testing the registration page. You should be able to register a new user!

Step 4. Add Login Functionality

Now that people can register for your app easily, let’s configure your login screen in LoginViewController!

As always, don’t forget to import Stormpath at the top of the file.

In this file, we have four stubs: login:, loginWithFacebook:, loginWithGoogle:, and resetPassword:. We’re going to add login and reset password functionality for now, and implement Login with Facebook/Google at the end of the tutorial.

To add login functionality, in login:, replace the existing view code with:

  Stormpath.sharedSession.login(emailTextField.text!, password: passwordTextField.text!, completionHandler: openNotes)

This will call Stormpath with the email and password provided, and attempt to log the user in. When done, Stormpath calls openNotes:success:error:.

Speaking of which, in this case the callback is a StormpathSuccessCallback, which means it’s looking for a method of type (Bool, NSError?) -> Void. The Bool represents if the login was successful, while NSError? will be set if there’s an error.

Let’s modify openNotes so it alerts the user on an error, and otherwise opens the login page:

  func openNotes(success: Bool, error: NSError?) {
    if let error = error {
        showAlert(withTitle: "Error", message: error.localizedDescription)
    }
    else {
        performSegueWithIdentifier("login", sender: self)
    }
}

Try this out; you can now log in with the account you just registered!

In addition, we need to add functionality to resetPassword: to send you a password reset email. Stormpath’s reset password method calls back with a StormpathSuccessCallback just like earlier, so we’ll have it alert the user with the result:

  Stormpath.sharedSession.resetPassword(emailTextField.text!) { (success, error) -> Void in
    if let error = error {
        self.showAlert(withTitle: "Error", message: error.localizedDescription)
    } else {
        self.showAlert(withTitle: "Success", message: "Password reset email sent!")
    }
}

Step 5. Retrieve Your Notes from the API

Now that we can register and login to Stormpath Notes, let’s build the core of the app: the note taking view!

When we first open the notes view, we see two things: your notes, and a “Hello [Name]!” message. Since we register our users with a name property, Stormpath exposes a /me endpoint in the backend which allows you to access a user’s profile data. Let’s put code to retrieve the user’s account, and add the user’s name to the helloLabel!

In viewWillAppear:

  Stormpath.sharedSession.me { (account, error) -> Void in
    if let account = account {
        self.helloLabel.text = "Hello \(account.fullName)!"
    }
}

Right below this segment of code, we’ll retrieve our notes by sending an authenticated GET request to /notes.

Stormpath uses token based authentication, which means that after authenticating, your application receives an access token and refresh token. When making an API request, you send the access token along with the request in the form of an Authorization: Bearer [AccessToken] header. The access token expires after some time, and when it expires, you can request a new one with the refresh token.

While this sounds complex, this ultimately makes your backend more secure and scalable.

To retrieve our notes, add this code in viewWillAppear::

  let notesEndpoint = NSURL(string: "https://stormpathnotes.herokuapp.com/notes")!
let request = NSMutableURLRequest(URL: notesEndpoint)
request.setValue("Bearer \(Stormpath.sharedSession.accessToken!)", forHTTPHeaderField: "Authorization")
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { (data, response, error) -> Void in
    guard let data = data, json = try? NSJSONSerialization.JSONObjectWithData(data, options: []), notes = json["notes"] as? String else {
        return
    }
    dispatch_async(dispatch_get_main_queue(), {
        self.notesTextView.text = notes
    })
}
task.resume()

In addition to constructing the HTTP request with the Authorization header, we convert the JSON returned by the server into text, and put it in the notes view.

Note: we wrapped our view code in dyspatchasync, as we can only manipulate UIKit views on the main thread, and NSURLSession calls back on a secondary thread.

Step 6. Save Your Notes to the API

Let’s also make our app save when we stop editing the text field. This API endpoint requires that we send a POST request to /notes, with JSON of the notes. Since we’re sending JSON to the server, we also need to additionally specify that we’re sending Content-Type: application/json.

In textViewDidEndEditing:, add:

  let postBody = ["notes": notesTextView.text]

let notesEndpoint = NSURL(string: "https://stormpathnotes.herokuapp.com/notes")!
let request = NSMutableURLRequest(URL: notesEndpoint)
request.HTTPMethod = "POST"
request.HTTPBody = try? NSJSONSerialization.dataWithJSONObject(postBody, options: [])
request.setValue("application/json" ?? "", forHTTPHeaderField: "Content-Type")
request.setValue("Bearer \(Stormpath.sharedSession.accessToken ?? "")", forHTTPHeaderField: "Authorization")

let task = NSURLSession.sharedSession().dataTaskWithRequest(request)
task.resume()

Finally, we’ll make sure to have Stormpath log us out when we click the logout button.

In logout:, add:

   class="Stormpath.sharedSession.logout()```">

There we go! If you now run and try out your app again, you’ll find that you can now register users, log in, and save your notes!

Step 7. Add Facebook and Google Login

With Stormpath, we’ve made it really easy to add social login with Facebook and Google. The Facebook and Google SDKs are very feature-rich, but overkill when you just want to log in. In our iOS SDK, we’ve simplified Facebook and Google Login so integration is just one line of code!

When integrating social login for your own app, you’ll have to register an app on Facebook or Google’s developer website, and set that up. However, since this is for our test app, we already have App IDs you can utilize for sign in.

To integrate social login, Facebook and Google assign us custom URL schemes, so their login page can redirect back to our app. Just like how links with ```http://``` get opened with Safari, we can register a custom URL scheme to do so for Stormpath Notes.

To do so, open the Stormpath Notes project file, click on the Info tab, and scroll down. Under URL Types, click the + button to add a new URL Type.

In the URL Schemes box, add: fb1697895913782798 and com.googleusercontent.apps.120814890096-1dt9ac0f83eng66troavm0a6dt9dgsp4.

Now, in the AppDelegate, add the following method:

func application(app: UIApplication, openURL url: NSURL, options: [String : AnyObject]) -> Bool { return Stormpath.sharedSession.application(app, openURL: url, options: options) }

This function will notify Stormpath when Facebook or Google redirects back into Stormpath Notes, so that Stormpath can complete the social login process. Finally, in the LoginViewController, insert into loginWithFacebook::

Stormpath.sharedSession.login(socialProvider: .Facebook, completionHandler: openNotes)

And loginWithGoogle::

Stormpath.sharedSession.login(socialProvider: .Google, completionHandler: openNotes)

Note: Stormpath considers email/password, Facebook, and Google accounts to be completely separate, so notes saved under one account will remain solely in that account.

Try running the app, and you’ll find that you’re now able to login with Facebook and Google!

Congrats! You’re amazing — you finished building your note-taking app! In the process of building it, you’ve learned how to implement registration and login via Stormpath, and use Stormpath’s access token to access a protected API endpoint!

What’s next?

Try the Android SDK – If you (or a friend) is into Android development, try following through the Android tutorial for Stormpath Notes. Since the app would make requests against the same API, you’ll notice that you can save your notes on one device, and open them up on the other!

Build a Backend with Stormpath – Try building this API from scratch! Stormpath Notes’ example backend is just 45 lines of code! Learn how to do it in our Stormpath Notes REST API tutorial, or view code on GitHub. Alternatively, try getting started with express-stormpath or check out our comprehensive documentation!

Stormpath is free to use, and can help your team write a secure, scalable application without worrying about the nitty gritty details of authentication, authorization, and user security. Sign up for an account today!

Talk with Us – We’re proud of the exceptional level of support we provide our community, and would love to hear from you about your project! Please don’t hesitate to contact us at support@stormpath.com, file an issue against one of our GitHub projects, or leave a comment below!

iOS is a trademark of Apple Inc.


Have more questions? Submit a request

Comments

0 comments

Article is closed for comments.