【Swift】AloamofireとSwiftyJsonについて整理
◼︎SwiftyJson整理
ただ、
http://qiita.com/yuta-t/items/1b6dfe34fa8537cf3329
の内容を書き写しただけのやつ
qiitaのapiの場合
[ { title: "AlamofireとswiftyJsonで〜", body: "はじめに〜", created_at: "2015-12-03" }, { title: "Optionalを〜", body: "この記事は〜", created_at: "2015-12-04" } ]
配列の中に辞書型
1つの辞書型が1つの記事
{ title: "AlamofireとswiftyJsonで〜", body: "はじめに〜", created_at: "2015-12-03" }
{title: "タイトル"}
キーと値
この表現形式をJSON。
◼︎Alamofireのrequestメソッド
引数はmethodとURLString。
methodはenumでどっかに定義、URLStringはURLをStringで書いてあるものでok
Alamofire.request(.GET, "https://qiita.com/api/v2/items")
requestメソッドに続けて、responseJSONメソッドを使用する。
responseJSONメソッドは1つの関数を引数に取るので、その関数をクロージャで
Alamofire.request(.GET, "https://qiita.com/api/v2/items") .responseJSON { response in // ここに処理を記述していく }
このresponseと定義したResponse型の引数は以下のような4つのプロパティをもつ
public let request: NSURLRequest? public let response: NSHTTPURLResponse? public let data: NSDAta? public let result: Result<Value, Error>
記事の取得に使うのは4番目のresultだけ。
resultの型はResult。
Resultはenumで定義されており、
Success or Failureを値に取り、
Successの場合には値を持っている。
Alamofireはこのvalueを取得するためにvalueというプロパティを用意してある。
Alamofire.request(.GET, "https://qiita.com/api/v2/items") .responseJSON { response in print(response.result.value) // responseのresultプロパティのvalueプロパティをコンソールに出力 }
ここまでで取得はできるので、ここからSwiftyJSONの出番。
SwiftyJSONはJSON型という、swiftyJSONが定義した型にデータを変換してからそのデータを扱う。
<ここでguardについて>=================================
◼︎swift2.0で追加されたguardの有効活用
//nilの場合にreturnしたい場合 func sample(num: Int?){ if num == nil{ return } //ここからメイン処理 print(num!) } //guardを使うと func sample(num: Int?){ guard let n = num else{ return } print(n) }
===================================================
JSON型はAnyObject型からイニシャライズすることができるので、
public struct JSON { public init(_ object: AnyObject){ self.object = object } }
先ほどのresponse.result.valueをアンラップして引数に渡してあげる
Alamofire.request(.GET, "https://qiita.com/api/v2/items") .responseJSON { response in guard let object = response.result.value else{ return } let json = JSON(object) }
これでJSON型に変換できました。
まずは記事の一覧を1つ1つの記事に分解していく。
これにはforEachメソッドを使用する.
(forEachメソッドはswiftの標準ライブラリにあるSequenceTypeプロトコルに定義されている。
JSON型はSequenceTypeプロトコルに準拠しているので、このメソッドが使える。)
実際に使うと...
let json = JSON(object) json.forEach{(String, JSON) in code }
ここでStringにはその要素が何番目かという情報が入り、
JSONには記事1つのデータが入る。
今回は記事が何番目かという情報は使わないので、変数名をつけずに
アンダースコアにしておく。
let json = JSON(object) json.forEach{(_, json) in //ここに処理を書いていく }
例えば記事のタイトルを取得したい時は
let json = JSON(object) json.forEach{(_, json) in json["title"]//jsonから"title"がキーのものを取得 }
(これはJSON型にsubsriptが実装されているから。
subscriptは配列や辞書型で扱うように、[]をメソッドとして使えるようにするもの)
しかし、subscriptの返り値はJSON型となっているので、
型の変換をしよう!
そのために、JSON構造体に定義されているstringプロパティを使う。
extension JSON{ //Optional String public var string: String? { get { switch self.type{ case .String: return self.object as? String default: return nil } } } ... }
stringプロパティはString型にキャストできればそれを、
できなければnilを返すメソッドで返り値はString?型となる。
printしてみると
let json = JSON(object) json.forEach { (_, json) in print(json["title"].string)//記事タイトルを表示 }
続いて、投稿者のユーザーIDを取得する。
qiitaAPIのドキュメントを見ると、投稿者のユーザーIDは
"user"というキー値の中の"id"というキーの値に格納されている。
つまり、二重の辞書型に入ってる。
が、これもSwiftyJSONで書ける。
let json = JSON(object) json.forEach { (_, json) in json["title"].string print(json["user"]["id"].string) //投稿者のユーザーIDを表示 }
ということで、タイトルとidを保存!!
//インスタンス変数 var articles: [[String: String?]] = [] // 記事を入れるプロパティを定義 let json = JSON(object) json.forEach{ (_, json) in let article: [String: String?] = [ "title": json["title"].string, "userId": json["user"]["id"].string ] self.articles.append(article)//配列に入れる } print(self.articles)
あとは、tableviewとかで
let article = articles[indexPath.row] cell.textLabel?.text = article["title"]!
みたいな感じで。