LoginSignup
16
15

More than 5 years have passed since last update.

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

Last updated at Posted at 2015-10-09

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叩きにいくときは意識しないでいいので楽でいいです。

以上。

16
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
15