0

Using RestKit with Swift

What is RestKit?

RestKit is an Objective-C framework that simplifies interaction with RESTful web services. It combines a clean, simple HTTP request/response API with a powerful object mapping system that reduces the amount of code you need to write to ‘get stuff done’. RestKit does a lot of the heavy-lifting (integrated network operations, JSON/XML parsing, object-mapping, etc.) for you while allowing you to think more in terms of your application’s data model and worry less about the details of sending requests, parsing responses, and building representations of remote resources. Additionally, it has a powerful wrapper for Core Data.

At the time of this article, it is still an Objective-C framework that requires additional configuration to be used in a Swift project.

This article explains with an example, how RestKit could be used in a Swift project to make a REST call and map the response to a desired model type. To accomplish this, we will be using an Objective-C bridging header file that exposes the required headers to Swift.

This example uses Xcode 7.3.1 and Swift 2.2.

Set up a Swift project via Xcode

Step 1: Create a Single View Application project in Xcode.

restkit-create-project

Step 2: Remember to choose Swift for your Language preferences.

restkit-project-options

Install RestKit

The recommended way to install RestKit is via the CocoaPods package manager as it provides flexible dependency management.

Step 1: Install CocoaPods (if not already available).

NOTE: CocoaPods is built with Ruby and it will be installable with the default Ruby available on macOS. If you encounter problems during installation, please visit this guide: https://guides.cocoapods.org/using/troubleshooting#installing-cocoapods

$ [sudo] gem install cocoapods
$ pod setup

This example uses cocoapods 1.0.1 and ruby 2.3.1.

Step 2: Go to the directory of your Xcode project and create a Podfile.

$ cd /path/to/my/Project
$ pod init

Step 3: Edit your Podfile to include RestKit.

$ open Podfile -a Xcode
platform :ios,'9.0'
use_frameworks!
target'RestKitExample'do
 pod'RestKit','~>0.27.0'
end

Step 4: Install RestKit into your project.

$ pod install

Step 5: Open your project in Xcode using the .xcworkspace file.

Create an Objective-C bridging header

Xcode will automatically configure an Objective-C bridging header, if you create an Objective-C file in a Swift project.

Step 1: Create an Objective-C file inside your project folder by right-clicking on the folder and selecting “New File…”.

restkit-right-click-new-file

Step 2: In the dialog that shows up, select Objective-C file under iOS -> Source category. Click Next, provide a name for the file and complete the file creation process.

restkit-add-new-file

Step 3: Xcode will automatically offer to create a bridging header file. If you accept, Xcode creates the file and names it as “<Project-module>-Bridging-Header.h”.

restkit-bridging-header

Step 4: (Optional) You may now delete the dummy Objective-C file created in Step 1 of this section.

Import RestKit

Step 1: Open the bridging header file and import RestKit.

@import RestKit;

Step 2: Build your project and make sure there are no errors.

Congratulations! You have now integrated RestKit in your Swift project.

Fetch a REST Resource

We are now going to make a simple GET request to JSONPlaceholder (https://jsonplaceholder.typicode.com) using RestKit. JSONPlaceholder has a “posts” API that returns a collection of posts. The structure of the “post” JSON returned is shown below:

{
  "userId": 1,
  "id": 1,
  "title":"sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
  "body":"quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
}

Create a model class

Create a Swift file and name it Post.swift. This file contains the model class which holds the data from the REST API. We would use RestKit’s object mapping capabilities to transform the above JSON into a Post instance.

class Post: NSObject {
    var userId = 0
    var id = 0
    var title = ""
    var body = ""

    override init() {
        super.init()
    }

    init(userId: Int, id: Int, title: String, body: String) {
        self.userId = userId
        self.id = id
        self.title = title
        self.body = body
    }
}

Define Object Mappings

NOTE: The purpose of this article is to demonstrate the use of RestKit in a Swift project. To keep things simple, the networking code has been placed inside the ViewController. Ideally, we would have a thin controller and create a separate networking layer that handles REST requests.

Henceforth, we will be placing all of the code below in the viewDidLoad() method inside ViewController.swift.

Let’s define our object mappings first:

let postMapping: RKObjectMapping = RKObjectMapping(forClass: Post.self)
postMapping.addAttributeMappingsFromArray(["userId", "id", "title", "body"])

RKObjectMapping is used to define the rules for transforming data within the parsed payload to attributes on an instance of Post. If the attributes do not precisely match the field names in the payload, addAttributeMappingsFromDictionary() may be used to define the appropriate mappings.

Create a Response Descriptor

The response descriptor verifies that an HTTP response (encountered in the HTTP success code range) matches the object mapping defined above. It also establishes the path pattern.

let statusCodes = RKStatusCodeIndexSetForClass(RKStatusCodeClass.Successful)
let resDescriptor = RKResponseDescriptor(mapping: postMapping, method: RKRequestMethod.GET, pathPattern:"/posts/:id", keyPath: nil, statusCodes: statusCodes)

Initialize an Object Manager

The object manager gets initialized with a new AFHTTPClient which in turn is initialized with the given base URL.

let url = NSURL(string: "https://jsonplaceholder.typicode.com")
let jsonPlaceholderManager = RKObjectManager(baseURL: url)
jsonPlaceholderManager.addResponseDescriptor(resDescriptor)

GET Objects at Path

The object manager is used to perform a GET request with a URL for the given path. This creates an RKObjectRequestOperation object that manages the transmission of the HTTP request, deserialization of the response and parsing of the response through the object mapping engine.

jsonPlaceholderManager.getObjectsAtPath("/posts/1", parameters: nil, success: { (operation, mappingResult) -> Void in

     let post: Post = mappingResult.firstObject as! Post

     print("ID: \(post.id)")
     print("UserId: \(post.userId)")
     print("Title: \(post.title)")
     print("Body: \(post.body)")

}) { (operation, error) -> Void in
     print(error.localizedDescription)
}

Note that the mappingResult needs to be type casted to our model type.

Conclusion

In this article, we learned how to configure a Swift project to use RestKit. We also used RestKit to fetch data from remote APIs and map the parsed payload to a model using object mappings.

Here is the example project with all of the code explained above.

0

Disaster Recovery Using Hybrid Cloud

Overview

Financial Engines recently celebrated the 20th anniversary since the company was founded.  Those two decades reflect our growth en route to becoming the largest registered investment advisor in the US.
During those same two decades the technology industry has changed profoundly and we have adjusted along the way.  One change we completed earlier in 2016 was moving our disaster recovery footprint to a hybrid cloud solution using AWS. This document describes that effort in more detail and the results we achieved.

Moving to IaaS

Our offerings have been web-based since inception. For hosting these web experiences we utilized top tier colocation providers. That relieved us from building and operating physical datacenters.
Today enterprise capable IaaS is avaiable from providers such as AWS.  We are now on a journey to move “up the stack” and adopt IaaS and reduce the burden we bear for things like:

  • hardware (servers, network gear, storage) procurement
  • physical site design and engineering (space, power, cooling, rack design, cable management, etc)
  • hardware maintenance: replacing failed drives, DIMMs, CPUs, NICs, motherboards, switch blades
  • firmware maintenance: qualifying and applying updates/patches across all hardware devices
  • hypervisor work: licensing, installation, tuning, maintenance, patching, upgrades
  • physical storage: design, engineering, and maintenance for iSCSI boot and data disks and NFS/CIFS network attached storage

Moreover, when we are ready to decomission infrastructure we just call an API to terminate/free those resources. This eliminates physical maintenance at the end of hardware lifecycles.

Peak Colo

Our transition to IaaS marks early 2016 as the point of “Peak Colo” for Financial Engines.

Over the coming quarters we expect to:

  • require fewer racks in colocation facilities
  • buy fewer servers from Cisco, Dell, or IBM
  • consume fewer VMware licenses
  • spend more on AWS for IaaS resources
  • achieve a net savings in our infrastructure total cost of ownership (see chart below for details)

Lift and shift for DR

Our rebuild of the DR environment had a fixed timeline due to a colocation contract ending. We therefore focused our effort on a lift-and-shift approach and moved the Linux compute portion of our stack into a VPC. We connected that VPC using Direct Connect to a reduced colo footprint resulting in a seamless LAN spanning our colo space and AWS:

HybridDiagram.png

This hybrid posture converts roughly 80% of our servers from on-prem hosted to cloud-hosted.  In doing so we trade capital for expense and ownership for rental.

For disaster recovery this trade is attractive since these resources are rarely needed (our DR utilization is < 10% for testing, drills, etc).

This lift-and-shift hybrid project has a residual footprint in our colo consisting of:

  • backend NetApp storage
  • large database hosts which are more diffcult to run on EC2 (due to size, iops, and cpu requirements)
  • batch machines which currently run on Windows Server

Future revisions of our hybrid posture should enable more of this infrastructure to run on AWS.

Our previous generation disaster recovery consisted of a colocation-hosted footprint containing:

  • 6 racks
  • vmware compute on IBM blades
  • NetApp storage
  • RHEL subscription fees
  • Load balancers as hardware appliances

The new disaster recovery footprint built on a hybrid cloud consists of:

  • 1 rack of UCS and NetApp (tech refreshed to yield better density and performance)
  • EC2 compute (our upgrade to the latest Xeon E5 v3 hardware was just selecting from the M4/C4 instance families)
  • Ubuntu 14.04 LTS
  • Load balancing on ELBs

In terms of costs here is what the transformation looks like:

hybrid-waterfall.jpg

Our DR site on AWS uses the pilot light model which incurs a modest monthly expense.

In exchange for that pilot light expense we achieved large reductions in depreciation, engineering time, and colo expense.

Looking Ahead

Following this disaster recovery rebuild we are moving to other re-hosting projects such as:

  • dev and test environments
  • production, starting with cpu-intensive tiers of our footprint

We expect these new environments to utilize the same hybrid cloud architecture with similar results.

Related Work

In addition to our lift-and-shift projects we are also moving to cloud native substrates for net new functionality.

These projects are using high-level primitives in AWS such as:

  • Lambda
  • API Gateway
  • DynamoDB
  • S3
  • Kinesis

Look for future blog posts covering that work.