Edited at

Alamofireでsession(cookie)を永続化する

More than 3 years have passed since last update.

Bridge-Headerを使えば簡単にObjective-Cのコードを使えるのでずっとAFNetworkingをつかってました。


だけど、今更だがSwiftだけにしてみようと思ってAlamofireを使ってみた。

転載:http://kixixixixi.hatenablog.com/entry/20151007/1444213987

HTTPリクエストを投げる際はいつもHelper作っているので今回もその方針でAlamofireを叩きにいくHelperメソッドをつくりました。

      func callAPI(

path path:String,
method:Alamofire.Method,
params:[String: AnyObject]?,
notificationName:Notice,
success:SuccessCallbackBlock,
failure:FailureCallbackBlock
)
{

Alamofire.request(
method,
APIHost + path,
parameters: params
)
.responseJSON { request, response, result in

if response?.statusCode >= 400
{
failure(error: result.error)
self.sendNotification(notificationName, success: false, responseObject: nil)

}
else
{
self.sendNotification(notificationName, success: true, responseObject: success(response: result.value))
}
}
}

このHelperを作っておいて

        callAPI(

path: "/login.json",
method: .GET,
params: nil,
notificationName: .Login,
success: { (response) -> (AnyObject?) in

if let my = response as? NSDictionary
{
// do something
}

return nil
},
failure: { (error) -> () in
// do something
}
)

こういった感じでAPIをたたく。


NSNocificationを使って通信結果のハンドリングしているのでsendnotificationメソッドやNoticeのenumは別で作ってあります。


APIHostはいわずもがな。

ブロックの型は以下のようにつくった。

public typealias SuccessCallbackBlock = (response:AnyObject?) -> (AnyObject?)

public typealias FailureCallbackBlock = (error: ErrorType?) -> ()

これでとりあえずできて、AFNetworkingよりswiftっぽくて使いやすいなと思ったけどアプリを再起動するとsessionが切れてしまうのがいただけない。cookieをどこにも保存してないからなー。


ということでHelperをいじってCookieを保存する機構を作ってSessionを永続化してみた。

    var manager : Alamofire.Manager?

func configureManager() -> Alamofire.Manager?
{
if manager == nil
{
if let cookiesData:NSData = NSUserDefaults.standardUserDefaults().objectForKey(CookieKey) as? NSData
{
for cookie:NSHTTPCookie in NSKeyedUnarchiver.unarchiveObjectWithData(cookiesData) as! [NSHTTPCookie]
{
NSHTTPCookieStorage.sharedHTTPCookieStorage().setCookie(cookie)
}
}

let cfg = NSURLSessionConfiguration.defaultSessionConfiguration()
cfg.HTTPCookieStorage = NSHTTPCookieStorage.sharedHTTPCookieStorage()
manager = Alamofire.Manager(configuration: cfg)
}
return manager
}

func callBasicAPI(
path path:String,
method:Alamofire.Method,
params:[String: AnyObject]?,
notificationName:Notice,
success:SuccessCallbackBlock,
failure:FailureCallbackBlock
)
{

configureManager()?.request(
method,
APIHost + path,
parameters: params
)
.responseJSON { request, response, result in

let cookies = NSHTTPCookie.cookiesWithResponseHeaderFields(response?.allHeaderFields as! [String:String], forURL: response!.URL!)
for var i = 0; i < cookies.count; i++
{
NSHTTPCookieStorage.sharedHTTPCookieStorage().setCookie(cookies[i])
}

let cookiesData:NSData = NSKeyedArchiver.archivedDataWithRootObject(NSHTTPCookieStorage.sharedHTTPCookieStorage().cookies!)
NSUserDefaults.standardUserDefaults().setObject(cookiesData, forKey: CookieKey)

if response?.statusCode >= 400
{
failure(error: result.error)
self.sendNotification(notificationName, success: false, responseObject: nil)

}
else
{
self.sendNotification(notificationName, success: true, responseObject: success(response: result.value))
}
}
}

Helperでシングルトンっぽいmanagerをつくり、そこで NSUserDefaults に保存しておいたCookieを引っ張ってきて当てる。


通信の成功時に都度、Hederに付与されたCookieを NSUserDefaults に保存。


これでsessionは永続化できました。


Helper作っておくと、モデル等からAPI叩きにいくときは意識しないでいいので楽でいいです。

以上。