読者です 読者をやめる 読者になる 読者になる

swiftでのapi通信処理を共通化する方法

はじめに

まだまだ初心者ですが
だいぶレイアウトが作れるようになってきたのでapiを作って動的に画面の内容を出せるようにしています。

やりたいこととしては
api通信の部分を別クラスにしたい(php開発で例えるとsql処理を別クラスにわけるようなイメージ)
apiから取得した値をviewにセットして画面に表示したい
phpでのサーバサイドの開発と違って基本的に通信周りは非同期処理になるのでそこがちょっとハマりポイントになるのかなぁとは感じました。(ajax使っていればそうでもないかもしれませんが、、、)

ちなみに、Alamofireというライブラリが非同期通信ではよく使われているようなので今回はこれを使ってみました。
https://github.com/Alamofire/Alamofire

実装方法

SampleViewController.swift

class SampleListViewController: UIViewController {

    // APIクラス
    var objApiSample = ApiSample()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // APIからデータを取得
        objApiSample.get(setView)
    }

    // API通信が完了したときに呼ばれるコールバックメソッド
    func setView() {
        if (objApiSample.result["error"] != nil) {
            // APIでレスポンスエラーなどがかえってきた場合
        }

        // APIで取得した値をラベルにセット
        var label = UILabel()
        label.text = objApiSample.result?["data"]?["name"] as? String        
        self.view.addSubView(label)
    }
}

ApiSample.swift

import UIKit
import Alamofire

class ApiSample: NSObject {
    
    // API結果保持用
    var result: Dictionary<String, AnyObject>! = ["key": []]
    
    func get(callBackClosure:() -> Void) -> Void {
        Alamofire
            .request(.GET, "http://example.com/path/to/")
            .responseJSON { request, response, JSON, error in
                var res: Array<Dictionary<String,AnyObject>>?
                if let r = JSON as? Array<Dictionary<String,AnyObject>> { res = r }
                
                self.result["error"] = error
                self.result["data"] = res
                
                callBackClosure()
        }
    }
}

今回、とりあえずこんな感じで実装してみました。
こんな感じにしておけば、ある程度はパターン化して作業効率が上がるのではないかなぁと思います

swiftが今ひとつわかってなくて、APIから取得したJSONを変数に入れるあたりがすっきりかけないのが課題ではありますが、、、

あと、リスト(UITableView)の中身を動的にするのもけっこうあるので次回はそれのサンプルも書いてみたいと思います

以上です

※こちらにもうちょっとちゃんとまとめてみましたkimagureneet.hatenablog.com