Tag Archives: programmng

SFO API Swift Implementation

A pattern that we’ve started using at Sabre Labs in our iOS projects is that the view controllers are written in Objective-C and utility classes are written in Swift. We also try to keep as much of the heavy lifting out of the view controllers, so that the VC is responsible for just brokering the information to the view and handling all the necessary delegate methods therein. Anything that a utility class needs to bubble up is handled through a delegate method.

Here is a simple example that hits the SFO API.

First, the header file of the view controller. Note that this has been pulled out of a real project, so I present it here merely as example.

//
//  ViewController.h
//  YourProject
//
//  Created by Barrett Clark on 8/25/14.
//  Copyright (c) 2014 Barrett Clark. All rights reserved.
//

#import <UIKit/UIKit.h>
#import <YourProject-Swift.h>

@interface ViewController : UIViewController <SFOProtocol> {
  SFO *sfo;
}

@end

And now the implementation file:

//
//  ViewController.m
//  YourProject
//
//  Created by Barrett Clark on 8/25/14.
//  Copyright (c) 2014 Barrett Clark. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController
            
- (void)viewDidLoad {
  [super viewDidLoad];
  // Do any additional setup after loading the view, typically from a nib.
  sfo = [[SFO alloc] initWithApiKey:@"sekretkey"];
  sfo.delegate = self;
  [sfo getAirlinesWithOffset:0 limit:5];
  [sfo getDiningWithOffset:0 limit:5];
  [sfo getPassengerServicesWithOffset:0 limit:5];
  [sfo getShoppingWithOffset:0 limit:5];
  [sfo getThingsToDoWithOffset:0 limit:5];
}

#pragma mark SFO Protocol
- (void) didReceiveAirports:(NSArray *)results {
  NSLog(@"Airports: %@", results);
}
- (void) didReceiveDining:(NSArray *)results {
  NSLog(@"Dining: %@", results);
}
- (void) didReceivePassengerServices:(NSArray *)results {
  NSLog(@"Passenger Services: %@", results);
}
- (void) didReceiveShopping:(NSArray *)results {
  NSLog(@"Shopping: %@", results);
}
- (void) didReceiveThingsToDo:(NSArray *)results {
  NSLog(@"Things To Do: %@", results);
}

@end

And finally, the “utility” file. I don’t generally use AFNetworking. The standard library HTTP calls are good enough for me. Perhaps the completion block that is mostly redundant can be streamlined. I welcome your comments.

//
//  SFO.swift
//  YourProject
//
//  Created by Barrett Clark on 8/26/14.
//  Copyright (c) 2014 Barrett Clark. All rights reserved.
//

import Foundation

@objc protocol SFOProtocol {
  optional func didReceiveAirports(results: NSArray)
  optional func didReceiveDining(results: NSArray)
  optional func didReceiveShopping(results: NSArray)
  optional func didReceiveThingsToDo(results: NSArray)
  optional func didReceivePassengerServices(results: NSArray)
}

@objc class SFO: NSObject {
  var delegate: SFOProtocol?
  let queue = NSOperationQueue()
  var apiKey: NSString
  let baseURL = "http://www.flysfo.com/api"
  
  init(apiKey: NSString) {
    self.apiKey = apiKey
    super.init()
  }
  
  /*
   * Airlines
   * http://www.flysfo.com/api/airlines.json?limit=20&key=[Your API Key]
   */
  func getAirlines(offset: Int = 0, limit: Int = 30) {
    var request = requestForURL(limit: limit, offset: offset, endpoint: "airlines")
    
    let completion = { (response: NSURLResponse!, data: NSData!, error: NSError!) -> Void in
      let res = response as NSHTTPURLResponse!
      if ((error) != nil) {
        println(error.description)
        return
      }
      var error: NSError?
      if (data != nil) {
        var e: NSError?
        var jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions(0), error: &e) as NSArray
        self.delegate?.didReceiveAirports!(jsonResult)
      }
    }
    NSURLConnection.sendAsynchronousRequest(request, queue: self.queue, completionHandler: completion)
  }

  /*
   * Dining
   * http://www.flysfo.com/api/dining.json?limit=20&key=[Your API Key]
   */
  func getDining(offset: Int = 0, limit: Int = 30) {
    var request = requestForURL(limit: limit, offset: offset, endpoint: "dining")
    
    let completion = { (response: NSURLResponse!, data: NSData!, error: NSError!) -> Void in
      let res = response as NSHTTPURLResponse!
      if ((error) != nil) {
        println(error.description)
        return
      }
      var error: NSError?
      if (data != nil) {
        var e: NSError?
        var jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions(0), error: &e) as NSArray
        self.delegate?.didReceiveDining!(jsonResult)
      }
    }
    NSURLConnection.sendAsynchronousRequest(request, queue: self.queue, completionHandler: completion)
  }

  /*
   * Shopping
   * http://www.flysfo.com/api/shopping.json?limit=20&key=[Your API Key]
   */
  func getShopping(offset: Int = 0, limit: Int = 30) {
    var request = requestForURL(limit: limit, offset: offset, endpoint: "shopping")
    
    let completion = { (response: NSURLResponse!, data: NSData!, error: NSError!) -> Void in
      let res = response as NSHTTPURLResponse!
      if ((error) != nil) {
        println(error.description)
        return
      }
      var error: NSError?
      if (data != nil) {
        var e: NSError?
        var jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions(0), error: &e) as NSArray
        self.delegate?.didReceiveShopping!(jsonResult)
      }
    }
    NSURLConnection.sendAsynchronousRequest(request, queue: self.queue, completionHandler: completion)
  }

  /*
   * Things To Do
   * http://www.flysfo.com/api/things-to-do.json?limit=20&key=[Your API Key]
   */
  func getThingsToDo(offset: Int = 0, limit: Int = 30) {
    var request = requestForURL(limit: limit, offset: offset, endpoint: "things-to-do")
    
    let completion = { (response: NSURLResponse!, data: NSData!, error: NSError!) -> Void in
      let res = response as NSHTTPURLResponse!
      if ((error) != nil) {
        println(error.description)
        return
      }
      var error: NSError?
      if (data != nil) {
        var e: NSError?
        var jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions(0), error: &e) as NSArray
        self.delegate?.didReceiveThingsToDo!(jsonResult)
      }
    }
    NSURLConnection.sendAsynchronousRequest(request, queue: self.queue, completionHandler: completion)
  }

  /*
   * Passenger Services
   * http://www.flysfo.com/api/passenger-services.json?limit=20&key=[Your API Key]
   */
  func getPassengerServices(offset: Int = 0, limit: Int = 30) {
    var request = requestForURL(limit: limit, offset: offset, endpoint: "passenger-services")
    
    let completion = { (response: NSURLResponse!, data: NSData!, error: NSError!) -> Void in
      let res = response as NSHTTPURLResponse!
      if ((error) != nil) {
        println(error.description)
        return
      }
      var error: NSError?
      if (data != nil) {
        var e: NSError?
        var jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions(0), error: &e) as NSArray
        self.delegate?.didReceivePassengerServices!(jsonResult)
      }
    }
    NSURLConnection.sendAsynchronousRequest(request, queue: self.queue, completionHandler: completion)
  }

  private func requestForURL(#limit: Int, offset: Int, endpoint: NSString) -> NSMutableURLRequest{
    let theURL = "\(baseURL)/\(endpoint).json?limit=\(limit)&offset=\(offset)&key=\(apiKey)"
    let url = NSURL(string: theURL)
    var request = NSMutableURLRequest(URL: url)
    request.cachePolicy = .ReloadIgnoringLocalAndRemoteCacheData
    request.timeoutInterval = 30.0
    request.HTTPMethod = "GET"
    request.setValue("application/json", forHTTPHeaderField: "Accept-Encoding")
    return request
  }
}

Leave a Comment

Filed under iOS, programming