書くこと
Alamofire を利用した API 呼び出しを利用してアプリを実装する
書いた理由
Alamofire を利用した API 呼び出し方法を忘れた時に確認する
参考にした記事
標準とAlamofireでAPIコール処理を書き比べてみる(Swift)
上記記事に紹介されていたコードに、UIを実装した
(すごくわかりやすい記事です)
前提条件
- テキストフィールド、ボタンおよび検索結果を表示するラベルは
Main.storyboard
で設定 - 上記要素は、
ViewController.swift
に紐づけている -
CocoaPods
を利用してAlamofire
はすでに導入済である
アプリの機能
テキストフィールドに郵便番号を入力し[Seach]ボタンをタップすると、ラベル(水色)にその郵便番号に対応する住所を表示する。
・郵便番号が入力されていない場合や入力した文字が7桁ではない場合はアラートを表示する
コード例
AddressModel.swift
// このコードは参考にした記事より流用した
struct AddressModel: Decodable {
var results: [Result]
struct Result: Decodable {
var address1: String
var address2: String
var address3: String
var kana1: String
var kana2: String
var kana3: String
}
}
ViewController.swift
import UIKit
import Alamofire
class ViewController: UIViewController {
private var addresses: AddressModel?
@IBOutlet weak var zipCodeTextField: UITextField!
@IBOutlet weak var seachButton: UIButton!
@IBOutlet weak var resultLabel: UILabel!
@IBAction func tapSeachButton(_ sender: Any) {
self.getAddress(zipCode: zipCodeTextField.text)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
private func getAddress(zipCode: String?) {
self.validate(zipCode: zipCode)
let baseUrl = "https://zipcloud.ibsnet.co.jp/api/"
let searchUrl = "\(baseUrl)search"
let parameters: [String: Any] = ["zipcode": zipCode!]
let headers: HTTPHeaders = ["Content-Type": "application/json"]
self.requestAPI(url: searchUrl, parameters: parameters, headers: headers)
}
private enum ErrorType:String {
case zipCodeNil = "郵便番号が確認できません"
case zipCodeBrank = "郵便番号を入力してください"
case zipCodeLengthNot7 = "郵便番号は7桁で入力してください"
}
private func validate(zipCode: String?){
guard let zipCode = zipCode else { self.showAlert(error: .zipCodeNil); return }
if zipCode == "" { self.showAlert(error: .zipCodeBrank); return }
if zipCode.lengthOfBytes(using: .utf8) != 7 { self.showAlert(error: .zipCodeLengthNot7); return }
}
private func showAlert(error: ErrorType) {
let alert = UIAlertController(title: "検索に失敗しました", message: error.rawValue, preferredStyle: .alert)
let action = UIAlertAction(title: "OK", style: .default, handler: nil)
alert.addAction(action)
self.present(alert, animated: true, completion: nil)
}
private func requestAPI(url:String,parameters:[String:Any],headers:HTTPHeaders) {
AF.request(url, method: .get, parameters: parameters, encoding: URLEncoding(destination: .queryString), headers: headers).responseJSON { response in
guard let data = response.data else { return }
do {
try self.parse(data: data)
} catch let error {
print("Error: \(error)")
self.showError()
}
}
}
private func parse(data:Data) throws {
self.addresses = try JSONDecoder().decode(AddressModel.self, from: data)
if let address = self.addresses {
self.show(result: "\(address.results[0].address1) \(address.results[0].address2) \(address.results[0].address3)")
}
}
private func show(result:String){
resultLabel.text = result
}
private func showError(){
resultLabel.text = "検索結果が取得できませんでした"
}
}