LoginSignup
2
5

More than 3 years have passed since last update.

[iOS/Swift]Alamofire を利用したアプリ実装(郵便番号検索アプリを例に)

Last updated at Posted at 2020-11-21

書くこと

Alamofire を利用した API 呼び出しを利用してアプリを実装する

書いた理由

Alamofire を利用した API 呼び出し方法を忘れた時に確認する

参考にした記事

標準とAlamofireでAPIコール処理を書き比べてみる(Swift)

上記記事に紹介されていたコードに、UIを実装した
(すごくわかりやすい記事です)

前提条件

  1. テキストフィールド、ボタンおよび検索結果を表示するラベルは Main.storyboard で設定
  2. 上記要素は、ViewController.swift に紐づけている
  3. 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 = "検索結果が取得できませんでした"
    }
}

参考資料

Alamofire
標準とAlamofireでAPIコール処理を書き比べてみる(Swift)

2
5
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
2
5