APIKitを使って郵便番号検索アプリをテスト的に作ってみました🧐
現場で使っていきそうなので・・・
郵便番号APIにはzipcloudを使わせてもらいました。
環境:
swift5.0
xcode10.3
フォルダ構成
追加・変更したファイルは下記です。
APIというフォルダを作ってその中に郵便番号APIにリクエストするためのファイルを配置しました。
メインロジックはViewControllerに書きました。
ZipSearch
|_ API
|_ ZipRequest.swift
|_ ViewController.swift
|_ Main.storyboard
Main.storyboard
郵便番号を入力するテキストフィールドと検索ボタン、結果表示のためのラベルを配置してます。
ソース
ViewController.swift
import UIKit
import APIKit
class ViewController: UIViewController {
@IBOutlet weak var search_button: UIButton!
@IBOutlet weak var zipcode_text: UITextField!
@IBOutlet weak var result_text: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// ボタンイベント
search_button.addTarget(self, action: #selector(search_exec(_:)), for: UIControl.Event.touchUpInside)
}
@objc func search_exec(_ sender: UIButton) {
if zipcode_text.text == "" {
let title = "エラー"
let message = "郵便番号を入力してください。"
let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertController.Style.alert)
let ok_button = UIAlertAction(title: "OK", style: UIAlertAction.Style.cancel, handler: nil)
alert.addAction(ok_button)
present(alert, animated: true, completion: nil)
return
}
let request = ZipRequest(zipcode: zipcode_text.text!)
Session.send(request) { result in
switch result {
case .success(let zip_result):
self.result_text.text = zip_result.address_text
case .failure(let error):
print("error: \(error)")
}
}
}
}
viewDidLoadから始まって、やっているのは検索ボタンを押した時のイベントを設定しています。
ボタン押下時のsearch_execのなかで、郵便番号がからの時だけエラーのアラートを出してます。
ちゃんとやるなら数値のチェックとか、形式チェックとかが必要ですね😅
その直後で、ZipRequestに入力された郵便番号を渡して、Session.sendでリクエストしています。
ZipRequest.swift
import Foundation
import APIKit
struct ZipRequest: Request {
typealias Response = ZipResult
let zipcode: String
var baseURL: URL {
return URL(string: "http://zipcloud.ibsnet.co.jp")!
}
var method: HTTPMethod {
return .get
}
var path: String {
return "/api/search"
}
var parameters: Any? {
return ["zipcode": zipcode]
}
func response(from object: Any, urlResponse: HTTPURLResponse) throws -> ZipResult {
return try ZipResult(object: object as! [String : AnyObject])
}
}
struct ZipResult {
var address_text: String
init(object: [String: AnyObject]) throws {
self.address_text = "存在しませんでした。"
var data : [String: AnyObject]
if object["results"] is NSNull {
return
}
if let results: NSArray = object["results"] as! NSArray {
for result in results {
data = result as! [String: AnyObject]
self.address_text = (data["address1"] as! String) + (data["address2"] as! String) + (data["address3"] as! String)
}
}
}
}
ボタン押下時イベントから呼ばれるZipRequestの方では、APIKit.Requestのプロトコルを適合してごにょごにょ、必要な設定を書いてます。
Session.sendでAPIリクエストされて、responseが呼ばれます。
struct ZipResultの方は、受けたJSONデータを処理しています。
都道府県名+市区町村名+町域名でくっつけて、返すように定義しています。
動かしてみる
所感
APIを叩くまではすんなりできたけど、jsonを解析してデータを取り出すところに時間がかかりました。
codableとかdecodableを使うと、jsonデータを取り出すのが簡単なようなので、こっちを使っていきたいところです🤨
swiftの書き方に慣れてないところが多々あるので、書いていって慣れていきたいと思います😅
コメント