Amarronの日記

iOSやMac、Web系の記事を書きます。

iOS HTTP メモ

  • iOSのHTTP関係のプログラムやメモです
  • 随時更新していく予定です

Flow


HTTP リクエストを発行しレスポンスを受信するまでのプログラムの流れはだいたい次の通り。

NSURLConnectionの場合

  1. リクエストヘッダ(NSURLRequest)を作る
  2. NSURLConnectionのクラスメソッドを用いリクエストを発行する
  3. レスポンスヘッダ(NSURLResponse)とレスポンスボディを取得する

NSURLSessionの場合

  1. セッションクラス(NSURLSession)を作る
  2. タスクを生成する
  3. タスクの実行する
// playgroundの場合↓のコメントアウトを消す
// import XCPlayground

/*
* NSURLConnection(非同期)
*/
func myNSURLConnectionAsync() {
    // 通信先のURLを生成.
    let url:NSURL = NSURL(string:"http://httpbin.org/get")!
    // リクエストを生成.
    let request:NSURLRequest = NSURLRequest(URL:url)
    let queue:NSOperationQueue = NSOperationQueue()
    // NSURLConnectionを使ってアクセス
    NSURLConnection.sendAsynchronousRequest(request, queue: queue, completionHandler:{ (response: NSURLResponse!, data: NSData!, error: NSError!) -> Void in
        // 帰ってきたデータを文字列に変換.
        var result = NSString(data: data, encoding: NSUTF8StringEncoding)!
        println("myNSURLConnectionAsync->\(result)")
    })

    // playgroundの場合↓のコメントアウトを消す
    // XCPSetExecutionShouldContinueIndefinitely(continueIndefinitely: true)
}

/*
* NSURLConnection(同期)
*/
func myNSURLConnectionSync() {
    // 通信先のURLを生成.
    let url:NSURL = NSURL(string:"http://httpbin.org/get")!
    // リクエストを生成.
    let request:NSURLRequest = NSURLRequest(URL:url)
    // NSURLConnectionを使ってアクセス
    var response: NSURLResponse?
    var error: NSError?
    let data = NSURLConnection.sendSynchronousRequest(request, returningResponse: &response, error: &error)
    var result = NSString(data: data!, encoding: NSUTF8StringEncoding)!
    println("myNSURLConnectionSync->\(result)")
    
    // playgroundの場合↓のコメントアウトを消す
    // XCPSetExecutionShouldContinueIndefinitely(continueIndefinitely: true)
}

/*
* NSURLSession(非同期)
*/
func myNSURLSession() {
    // 通信先のURLを生成.
    let url:NSURL = NSURL(string: "http://httpbin.org/get")!
    // セッションの生成.
    let session = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration())
    // 通信のタスクを生成.
    let task = session.dataTaskWithURL(url, completionHandler: {
        (data, response, err) in
        
        // 帰ってきたデータを文字列に変換.
        var result = NSString(data: data, encoding: NSUTF8StringEncoding)!
        println("myNSURLSession->\(result)")
        
    })
    // タスクの実行.
    task.resume()

    // playgroundの場合↓のコメントアウトを消す
    // XCPSetExecutionShouldContinueIndefinitely(continueIndefinitely: true)
}

参考UTL:NSURLSession のまとめ

Json


jsonを取得しパース

func myNSURLConnectionSync() {
    // 通信先のURLを生成.
    let url:NSURL = NSURL(string:"http://httpbin.org/get")!
    // リクエストを生成.
    let request:NSURLRequest = NSURLRequest(URL:url)
    // NSURLConnectionを使ってアクセス
    var response: NSURLResponse?
    var error: NSError?
    let data = NSURLConnection.sendSynchronousRequest(request, returningResponse: &response, error: &error)
//    var result = NSString(data: data!, encoding: NSUTF8StringEncoding)!
//    println("myNSURLConnectionSync->\(result)")
    
    // Jsonでパース
    let json:NSDictionary = NSJSONSerialization.JSONObjectWithData(data!,
        options: NSJSONReadingOptions.AllowFragments, error: nil) as! NSDictionary
    for (name, value) in json {
        println("key:\(name) value:\(value)")
    }
}

GCD


GCDを使った非同期完了後の処理

func myNSURLConnectionAsync() {
    // 通信先のURLを生成.
    let url:NSURL = NSURL(string:"http://httpbin.org/get")!
    // リクエストを生成.
    let request:NSURLRequest = NSURLRequest(URL:url)
    let queue:NSOperationQueue = NSOperationQueue()
    // NSURLConnectionを使ってアクセス
    NSURLConnection.sendAsynchronousRequest(request, queue: queue, completionHandler:{ (response: NSURLResponse!, data: NSData!, error: NSError!) -> Void in
        // 帰ってきたデータを文字列に変換.
        var result = NSString(data: data, encoding: NSUTF8StringEncoding)!
        println("myNSURLConnectionAsync->\(result)")
        
        // GCD(Grand Central Dispatch)
         dispatch_async(dispatch_get_main_queue(), {
              // 完了後に実行する処理(self.tableView.reloadData()等)
          })
    })

}

参考URL:[Swift 1.1] swiftで api を叩いて、JSONをパースして、表示させる方法 (xcodeは6.1, iOSは8.1)

Auth


cookie


Cookieの永続化

// Cookieの永続化
import UIKit

class AppDelegate: UIResponder, UIApplicationDelegate {
    let SavedHTTPCookiesKey = "SavedHTTPCookies"

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
            self.window = UIWindow(frame: UIScreen.mainScreen().bounds)

        self.loadCookie()
        
        return true
    }
    func applicationDidEnterBackground(application: UIApplication) {
        
        self.saveCookie()
    }

    func saveCookie() {
        let cookiesData:NSData = NSKeyedArchiver.archivedDataWithRootObject(NSHTTPCookieStorage.sharedHTTPCookieStorage().cookies!)
        NSUserDefaults.standardUserDefaults().setObject(cookiesData, forKey: SavedHTTPCookiesKey)
    }
    
    func loadCookie() {
        if let cookiesData:NSData = NSUserDefaults.standardUserDefaults().objectForKey(SavedHTTPCookiesKey) as? NSData {
            for cookie:NSHTTPCookie in NSKeyedUnarchiver.unarchiveObjectWithData(cookiesData) as [NSHTTPCookie] {
                NSHTTPCookieStorage.sharedHTTPCookieStorage().setCookie(cookie)
            }
        }
    }
}

Custom URL Scheme


  • Custom URL Schemeの処理をシンプルに書く
    • URLの設計:scheme://controller/action?query
    • アプリ側は受け取ったcontrollerを元に、使用するcontrollerクラスを選び、そのcontrollerクラスにactionとqueryを渡す。
    • 各actionの挙動については各々のcontrollerに任せる
import UIKit

class AppDelegate: UIResponder, UIApplicationDelegate {
    func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject?) -> Bool {
        var result:Bool = true

        let schema:String = url.scheme!
        let host:String   = url.host!
        let action:String = url.lastPathComponent!
        let query:String  = url.query!
        return result
    }
}

外部ライブラリ


note

  • 特にこだわりがないようであれば、Alamofireを使ったほうがよさそう(画像のキャッシュとか自分でコードを書く量が最終的に少なくてすみそう) f:id:Amarron:20150401221639p:plain

HTTPの確認に便利


参考URL