[iOSアプリ開発初期格差コース]Part 2.天候アプリケーションの作成


天気アプリ


Intro


[機能の説明]
→都市名を入力し、現在の天気情報を取得して画面に表示する
→入力した都市名が正しくない場合、サーバから受信したエラーメッセージがalertと表示されます
[使用するテクノロジー]
→ Current Weather API
→ URLSession

URLセッションによるHTTP通信

  • ネットワーク通信
    →インターネット上の通信
    →大量の情報を交換するため、インターネット上には厳格なプロトコルが存在し、プロトコル
  • と呼ぶ.
  • ハイパーテキスト転送プロトコル:ハイパーテキストを転送するためのプロトコル
    →リクエストとレスポンスで構成
    →クライアントからWebサーバにリクエストを送信すると、Webサーバはダウングレード応答を行う
    →サーバから必要なすべての情報を取得すると、接続は終了します
    →リクエストの送信と応答の受信時にパケットに情報を入れて転送し、パケットのヘッダには送信者と受信者のアドレス、パケットのライフサイクルなどが含まれ、Bodyには転送したい実際の内容
  • が含まれている.
  • HTTP Method
    →GET:クライアントがサーバにリソースを要求するため
    →POST:クライアントがサーバ上で新しいリソースを作成する
    →PUT:クライアントがサーバ上のすべてのリソースを変更するために使用する
    →PATCH:クライアントがサーバリソースの一部を変更するために使用
    →DELETE:クライアントによるサーバ上のリソースの削除
    →HEAD:クライアントがサーバーを正常に稼働していることを確認する
    →OPTIONS:クライアントがサーバ上のURLがどのような方法をサポートしているかをチェックするときに使用する
    →接続:クライアントがエージェントを介してサーバとSSL通信したい場合に使用
    →TRACE:
  • クライアントとサーバ間の通信管理とデバッグ用
  • HTTP Status
    →100番情報:要求情報の処理中
    →200回クイックアクセス:通常処理要求
    →300対Redirection:要求完了に必要なその他の操作
    →400番クライアントエラー:サーバが要求を理解できない
    →500台サーバエラー:サーバ処理要求失敗
  • URLSSession:特定のURLを使用してデータをダウンロードおよびアップロードするAPI
    →URLSessionConfigurationで作成
    →生成されたURLセッションで1つ以上のURLセッションを作成し、実際のサーバと通信できる
    →共有セッション/URLセッション.shared():基本リクエストを発行するセッションに単一の色調として使用できます.自分で作成したセッションのようにカスタマイズすることはできませんが、簡単に作成および使用できます.
    →デフォルトセッション(Default Session)/URLSSession(構成:.default):共有セッションと似ていますが、必要な設定を直接行い、キャッシュやCookieなどをディスクに格納できます.データを順番に利用するよう依頼を指定できます
    →テンポラリ・セッション/URLセッション(構成:.テンポラリ):共有セッションと似ていますが、キャッシュ、Cookie、およびユーザー認証情報はディスクに格納されません.したがって、セッションの有効期限が切れるとデータは消失します.
    →バックグラウンドセッション(Background Session)/URL Session(configuration:.background):アプリケーションが実行されていない場合、バックグラウンドでコンテンツのアップロードとダウンロード操作
  • を実行できます.
  • URLSessionTask
    →URLSessionDataTask:データオブジェクト要求と応答データを使用し、通常は短くて頻繁な要求に使用する
    →URLSessionUploadTask:データオブジェクトまたはファイル形式のデータをアップロードする操作を行います.アプリケーションが実行されていない場合のバックグラウンドアップロードのサポート
    →URLSessionDownloadTask:データを受信し、ファイル形式でデータを保存します.アプリケーションが実行されていない場合のバックグラウンドダウンロードのサポート
    →URLSessionStreamTask:TCP/IP接続を作成するためのTask
    →URLSessionWebSocketTask:Webソケットプロトコル規格で通信するTask
  • URLSession Life Cycle
    →セッション構成の決定とセッションの作成
    →通信するURLとRequestオブジェクトを設定する
    →使用するTaskを特定し、対応するCompletion HandlerまたはDelegateメソッドを作成する
    →該当するTaskを実行する
    →Task完了後にCompletion Handlerモジュール
  • を呼び出す

    Openweather API


    https://openweathermap.org
  • アカウントの作成-ログイン-API-現在のWeather Data-Subscribe(Free)-Get APIキー-MyAPIキー
  • JSON:ネットワークを介してデータを交換する際によく使われる軽量レベルのデータフォーマット
    →名前と値のペアで構成され、各ペアはカンマで区切られます
    →nameはStringタイプでなければなりません.valueはデータ型/配列/オブジェクトです.
    →オブジェクトは括弧で囲み、配列は角括弧で囲み
  • を表す.

    きのうインプリメンテーション

    //
    //  ViewController.swift
    //  Weather
    //
    //  Created by TAEJANIM on 2021/11/23.
    //
    
    import UIKit
    
    class ViewController: UIViewController {
    
        @IBOutlet weak var cityNameTextField: UITextField!
        @IBOutlet weak var cityNameLabel: UILabel!
        @IBOutlet weak var weatherDescriptionLabel: UILabel!
        @IBOutlet weak var tempLabel: UILabel!
        @IBOutlet weak var maxTempLabel: UILabel!
        @IBOutlet weak var minTempLabel: UILabel!
        @IBOutlet weak var weatherStackView: UIStackView!
        
        override func viewDidLoad() {
            super.viewDidLoad()
        }
    
        @IBAction func tapFetchWeatherButton(_ sender: UIButton) {
            if let cityName = self.cityNameTextField.text {
                self.getCurrentWeather(cityName: cityName)
                self.view.endEditing(true)
            }
        }
        
        func configureView(weatherInformation: WeatherInformation) {
            self.cityNameLabel.text = weatherInformation.name
            if let weather = weatherInformation.weather.first {
                self.weatherDescriptionLabel.text = weather.description
            }
            self.tempLabel.text = "\(Int(weatherInformation.temp.temp - 273.15))℃"
            self.minTempLabel.text = "최저: \(Int(weatherInformation.temp.minTemp - 273.15))℃"
            self.maxTempLabel.text = "최대: \(Int(weatherInformation.temp.maxTemp - 273.15))℃"
        }
        
        func showAlert(message: String) {
            let alert = UIAlertController(title: "에러", message: message, preferredStyle: .alert)
            alert.addAction(UIAlertAction(title: "확인", style: .default, handler: nil))
            self.present(alert, animated: true, completion: nil)
        }
        
        func getCurrentWeather(cityName: String) {
            guard let url = URL(string: "https://api.openweathermap.org/data/2.5/weather?q=\(cityName)&appid=34c0b6b89d88c55c93ede507f662a185") else { return }
            let session = URLSession(configuration: .default)
            session.dataTask(with: url) { [weak self] data, response, error in
                let successRange = (200..<300)
                guard let data = data, error == nil else { return }
                let decoder = JSONDecoder()
                if let response = response as? HTTPURLResponse, successRange.contains(response.statusCode) {
                    guard let weatherInformation = try? decoder.decode(WeatherInformation.self, from: data) else { return }
                    DispatchQueue.main.async {
                        self?.weatherStackView.isHidden = false
                        self?.configureView(weatherInformation: weatherInformation)
                    }
                } else {
                    guard let errorMessage = try? decoder.decode(ErrorMessage.self, from: data) else { return }
                    DispatchQueue.main.async {
                        self?.showAlert(message: errorMessage.message)
                    }
                }
                
            }.resume()
        }
    }
    //
    //  WeatherInformation.swift
    //  Weather
    //
    //  Created by TAEJANIM on 2021/11/23.
    //
    
    import Foundation
    
    struct WeatherInformation: Codable {
        let weather: [Weather]
        let temp: Temp
        let name: String
        
        enum CodingKeys: String, CodingKey {
            case weather
            case temp = "main"
            case name
        }
    }
    
    struct Weather: Codable {
        let id: Int
        let main: String
        let description: String
        let icon: String
    }
    
    struct Temp: Codable {
        let temp: Double
        let feelsLike: Double
        let minTemp: Double
        let maxTemp: Double
        
        enum CodingKeys: String, CodingKey {
            case temp
            case feelsLike = "feels_like"
            case minTemp = "temp_min"
            case maxTemp = "temp_max"
        }
    }
    //
    //  ErrorMessage.swift
    //  Weather
    //
    //  Created by TAEJANIM on 2021/11/23.
    //
    
    import Foundation
    
    struct ErrorMessage: Codable {
        let message: String
    }

    Outro

  • HTTP:クライアントがサーバに要求すると、対応する応答結果が返されます.クライアントはこの結果を返します.
  • URL Session:API
  • は、アップル社がHTTP、HTTPSプロトコルを通じてサーバとデータを交換する.
  • Codable:自分を外部表現に変換できるタイプを指す.オブジェクトがCoodableを使用する場合は、オブジェクトをJSONとして作成するか、JSONデータをオブジェクト
  • として作成することができます.

    結果