iOS HTTP メモ
- iOSのHTTP関係のプログラムやメモです
- 随時更新していく予定です
Flow
HTTP リクエストを発行しレスポンスを受信するまでのプログラムの流れはだいたい次の通り。
NSURLConnectionの場合
- リクエストヘッダ(NSURLRequest)を作る
- NSURLConnectionのクラスメソッドを用いリクエストを発行する
- レスポンスヘッダ(NSURLResponse)とレスポンスボディを取得する
NSURLSessionの場合
- セッションクラス(NSURLSession)を作る
- タスクを生成する
- タスクの実行する
// 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に任せる
- URLの設計:
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 } }
外部ライブラリ
- [Swift] HTTP通信OSS Alamofire 導入編
- [Swift] HTTP通信OSS Alamofire 応用編
- AFNetworkのSwift版 Alamofireを試してみた
- AFNetworking 2.0 のまとめ
- iOS開発でNetwork周りのManagerを作る (AFNetworking使用例)
- afnetworking-2-0-tutorial
- NSURLSession Tutorial
note
- 特にこだわりがないようであれば、Alamofireを使ったほうがよさそう(画像のキャッシュとか自分でコードを書く量が最終的に少なくてすみそう)
HTTPの確認に便利
- httpbin(1): HTTP Request & Response Service(jsonの確認にカナリ便利!)