はじめに
本稿ではAlamofireとCodableを利用して、APIからデータを取得する処理について説明します。
最近仕事でCodableを使ってみたのですが、意外と使いやすくて初心者の方にもオススメできる機能だったので、備忘録もかねてまとめてみました。
環境
macOS 10.13.4
swift 4.1
xcode 9.4.1
Alamofireの導入
AlamofireはiOSアプリ開発では有名な、汎用的な通信ライブラリです。
インストールはまずPodfileに下の記述をします。
pod 'Alamofire'
その後、ターミナル上で以下のコマンドを叩きます。
pod install
これでAlamofireのインポートは完了です。
※注意
Alamofireをインポートしようとすると、no such module というエラーが出るかもしれません。
その場合は、command + b で一度ビルドしてください。エラーが消えます。
Codableの利用
Codableはswift4から追加された内部機能です。
Foundationパッケージ内に定義されているため、Codableを利用する際は必ずFoundationをインポートしましょう。
今回は以下のようなJSONを返すAPIを想定してモデルを作成します。
{
"id": 0,
"userName": "dack",
"imageUrl": "https://hogehoge/image.png"
}
さて、まずCodableを利用して、APIから取得したデータを保持するモデルを作成します。
Codableを利用する際は、変数名をJSONのキー名と一致させます。そうすると、以下のようなモデルとなります。
import Foundation
struct UserModel: Codable {
let id: Int
let userName: String
let imageUrl: String
}
これでモデルは完成です。
JSONのデコード
モデルが完成したので、実際にAlamofireで取得したJSONをデコードしてモデルに格納します。
AlamofireでJSONを取得し、デコードする処理は以下のようになります。
import Alamofire
func request() {
// APIリクエスト
Alamofire.request("https://hogehoge/get"
method: .get,
parameters: nil,
encoding: JSONEncoding.default,
headers: nil)
.response { response in
guard let data = response.data else { return }
let userModel: UserModel = JSONDecoder().decode(UserModel.self, from: data)
print(userModel)
// printの出力結果
// (id: 0, userName: dack, imageUrl: https://hogehoge/image.png)
})
}
返却されるJSONと対応していれば、Codableで作成したモデルにデコード結果がそのまま反映されます。
後は使いたいようにモデルに格納された値を良しなに使用しましょう。
ネストしたJSONのデコード
上記のような単純なJSONなら分かりやすいですが、実際の現場だとJSONがネストすることはザラです。
ですが、Codableを利用すれば簡単にネストしたJSONもデコードしてモデルに格納できます。
例として以下のようなJSONをデコードします。
{
"id": 0,
"name": "dack",
"information": {
"age": 25,
"sex": "male",
"job": "engineer"
},
"follows": ["john", "nancy", "zushi"]
}
このJSONをデコードするモデルは以下のようになります。
import Foundation
struct UserModel: Codable {
let id: Int
let name: String
let information: InformationModel
let follows: [String]
}
struct InformationModel: Codable {
let age: Int
let sex: String
let job: String
}
JSONのオブジェクト = SwiftのStruct(構造体)と考えると分かりやすいですね。
AlamofireでJSONを取得して、デコードした結果をモデルに格納する方法は変わらず簡単にできます。
func request() {
// APIリクエスト
Alamofire.request("https://hogehoge/get2"
method: .get,
parameters: nil,
encoding: JSONEncoding.default,
headers: nil)
.response { response in
guard let data = response.data else { return }
let userModel: UserModel = JSONDecoder().decode(UserModel.self, from: data)
print(userModel)
// printの出力結果
// (id: 0, userName: dack, information: (age: 25, sex: male, job: engineer), follows: (john, nancy, zushi))
})
}
以上で、AlamofireとCodableを利用したAPIからデータの取得ができるようになりました。
モデルをCodableで作成して、Alamofireで取得したJSONをデコードするだけなので、見た目以上に簡単に実現できます。
ただし、JSONのキー名とモデルの変数名が異なるとデコードできずにモデルにデータを格納することができないため、注意が必要です。
最後に
いかがでしたでしょうか?
JSONのシリアライズにはObjectMapperやSwiftyJson等の有名なライブラリがありますが、Codableは内部機能でモデルも構造体で定義できるためとっつきやすいかと思います。是非使ってみて下さい。