[SWIFT] Créez une application qui utilise l'API météo pour déterminer si vous avez besoin d'un parapluie.

introduction

Les débutants ont créé un portfolio pour l'apprentissage et le portfolio. Cela fait environ 1 à 2 mois que j'ai commencé à le créer, alors j'aimerais des conseils sur le refactoring et le codage.

Aperçu de l'application

Si vous êtes salarié, j'ai pensé que ce serait pratique s'il y avait une application qui pourrait vérifier instantanément si vous aviez besoin d'un parapluie aujourd'hui.

J'appuie sur le bouton ↓ Déterminez la latitude et la longitude de votre position actuelle à partir du GPS ↓ Géocodage inversé à partir de la latitude / longitude ↓ Déterminez la préfecture dans laquelle vous vous trouvez ↓ Calculez la probabilité de précipitations de la préfecture dans laquelle vous vous trouvez à partir de l'API météo ↓ Montrez si vous avez besoin d'un parapluie ou non

Une telle application avait déjà été publiée, mais ce n'était pas celle que je voulais, alors j'ai également essayé de créer un portfolio.

Environnement d'exploitation

Cible version
iOS 14.0
macOS Catalina 10.15.7
Xcode 12.0
Swift 5.3

API météo utilisée OpenWeatherMap

Installer le pod

Cette fois J'ai installé "Alaomofire" et "SwiftyJSON".

Podfile


pod "Alamofire"
pod "SwiftyJSON"

Site de référence

Créer Main.storyboad

Main.storyboad スクリーンショット 2020-10-20 21.01.42.png

Cette fois, j'ai créé HomeVC et UmbrellaVC. Déplacer vers Home VC après le lancement de l'application → Appuyez sur le bouton "Informations de localisation" → Déplacer vers Umbrella VC ① Pour le libellé, appelez la préfecture de votre position actuelle obtenue par géocodage inversé. ② Pour l'étiquette, appelez la probabilité de précipitations de votre emplacement actuel à partir de l'API météo. ③ Pour l'étiquette, juger si un parapluie est nécessaire ou non à partir de la probabilité de précipitations

Mettre en place

Tout d'abord, créez un modèle des données à acquérir par l'API météo.

CityModel

CityModel.swift


import Foundation

struct cityModel:Decodable{
    
    var list: [List]

    struct List:Decodable {
        var pop:Double
    }
    
}

Je pense que la structure décrite ici dépend des données API à acquérir. Dans l'API météo "Open Weather" utilisée cette fois, l'acquisition ci-dessus a été obtenue.

Données JSON acquises par OpenWeather

La valeur numérique de l'item "pop" ici est la valeur numérique à acquérir cette fois (type Double) スクリーンショット 2020-10-20 21.14.22.png

Site de référence


UmbrellaVC

UmbrellaVC.swift



import UIKit
import CoreLocation

class UmbrellaVC: UIViewController {
    
    @IBOutlet weak var label1: UILabel!
    var locationText:String = "Préfecture d'Osaka"
    
    @IBOutlet weak var label2: UILabel!
    var popText:Int = 0
    
    @IBOutlet weak var label3: UILabel!
    var umbrellaJudgement:String = "J'ai besoin d'un parapluie"
    
    override func viewDidLoad() {
        super.viewDidLoad()
        label1.text = locationText
        label2.text = "\(popText)" + "%"
        label3.text = umbrellaJudgement
        
        self.label3.layer.borderWidth = 2.0
        self.label3.layer.borderColor = UIColor.black.cgColor
        self.label3.layer.cornerRadius = 20

        //Changez la couleur des lettres qui apparaissent en fonction de la probabilité de précipitations pour que vous puissiez voir d'un coup d'œil
        if popText >= 30{
            label3.textColor = .orange
            
        }else if popText >= 70{
            label3.textColor = .red
        }
    }
}

Attribuez une variable à chaque étiquette.

Affectez à la variable définie par UmbrellaVC.

HomeVC

HomeVC.swift


import UIKit
import CoreLocation
import Alamofire
import SwiftyJSON

class HomeVC: UIViewController,CLLocationManagerDelegate {
    
    //Mettez la valeur initiale dans chaque variable
    var latitudeNow: Double = 39.0000
    var longitudeNow: Double = 140.0000
    var locationManager: CLLocationManager!
    var administrativeArea:String = ""
    var locationNow: String = ""
    private var citymodel: cityModel?
    var doubleOfMaximumPop:Double = 100.0
    var maxPop:Int = 30
    var Judge:String = ""

 override func viewDidLoad() {
        super.viewDidLoad()

        //Paramètres de disposition de l'affichage d'image
        umbrellaImage.image = UIImage(named:"umbrellaImage")
        umbrellaImage.layer.cornerRadius = 10
                
        //Appeler locationManager pendant viewDidload (mettre à jour les informations de localisation)
        locationManagerDidChangeAuthorization(CLLocationManager())
        
        //Appelez la fonction d'acquisition météo
        getWeatherData()

    }

    //Obtenez des informations de localisation lorsque vous appuyez sur un bouton
    @IBAction func buttonTapped(_ sender: Any) {
        
        //Appuyez sur le bouton pour arrêter la mise à jour de locationManager
        stopLocationManager()
        
   }

    //Appuyez sur le bouton pour passer à la séquence et lister la préfecture dans le Label 1 dans Umbrella VC
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if(segue.identifier == "toUmbrellaVC") {
            let  locationNow: UmbrellaVC = (segue.destination as? UmbrellaVC)!
            locationNow.locationText = administrativeArea
            
            let popNow:UmbrellaVC = (segue.destination as? UmbrellaVC)!
            popNow.popText = Int(maxPop)
            
            let umbJud:UmbrellaVC = (segue.destination as? UmbrellaVC)!
            umbJud.umbrellaJudgement = Judge
            
        }
    }

    //Gestionnaire de localisation @ iOS 14 Mettre à jour les informations de localisation
    func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
        locationManager = CLLocationManager()
        
        let status = manager.authorizationStatus
        
        switch status {
        case .authorizedAlways, .authorizedWhenInUse:
            locationManager.delegate = self
            locationManager.startUpdatingLocation()
            
        case .notDetermined, .denied, .restricted:
            showAlert()
            
        default:print("Non traité")
        }
    }

    //Arrêter de mettre à jour les informations de locationManager
        func stopLocationManager(){
            locationManager.stopUpdatingLocation()
        }

    //Fonction d'affichage des alertes
    func showAlert(){
        let alertTitle = "L'acquisition d'informations de localisation n'est pas autorisée."
        let alertMessage = ""Confidentialité" de l'application de paramétrage>Veuillez changer de "Service de localisation"."
        let alert: UIAlertController = UIAlertController(
            title: alertTitle, message: alertMessage, preferredStyle: UIAlertController.Style.alert
        )
        //Bouton OK
        let defaultAction: UIAlertAction = UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil)
        
        //Action ajoutée à UIAlertController
        alert.addAction(defaultAction)
        present(alert, animated: true, completion: nil)
        
    }

    //Une fonction qui stocke les informations de localisation lors de sa mise à jour
    //Le gestionnaire de localisation ne démarrera que si les informations de localisation sont mises à jour * Important
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        
        
        let location = locations.first
        let latitude = location!.coordinate.latitude
        let longitude = location!.coordinate.longitude
        //Stocker les informations de localisation
        self.latitudeNow = Double(latitude)
        self.longitudeNow = Double(longitude)
        
        //Après avoir acquis les informations de localisation, un géocodage inversé est effectué pour déterminer la préfecture.
        let locationA = CLLocation(latitude: latitudeNow, longitude: longitudeNow)
        
        let geocoder: CLGeocoder = CLGeocoder()
        geocoder.reverseGeocodeLocation(locationA) { [self](placemarks, error) in
            if let placemark = placemarks?.first {
                self.administrativeArea = placemark.administrativeArea!

            } else {
                self.administrativeArea = "bb"
            }
        }
    }

    //Obtenez la probabilité de précipitations maximale jusqu'à 18 heures plus tard à l'aide de l'API de prévisions météorologiques
    //Dans OpenWeatherMap, il y a des frais pour acquérir la probabilité de précipitation quotidienne, et l'acquisition de la probabilité de précipitation toutes les 3 heures est gratuite, alors utilisez-la.(Comme il était censé être vu avant d'aller travailler le matin, il a été jugé qu'il n'y avait pas de problème)
    private func getWeatherData()  {

        let id = "Entrez l'ID API"
        let baseUrl = "http://api.openweathermap.org/data/2.5/forecast?lat=" + "\(latitudeNow)" + "&lon=" + "\(longitudeNow)" + "&exclude=daily&lang=ja&cnt=6&.pop&appid=" + "\(id)"
        
        AF.request(baseUrl, method: .get).responseJSON { [self] response in
            guard let data = response.data else {
                return
            }
            do {
                let citymodel = try JSONDecoder().decode(cityModel.self, from: data)
                
                //Lister les données API
                let popNumber = citymodel.list.map{ $0.pop }
            
                //Obtenez le maximum de données dans la liste
                var doubleOfMaximumPop = popNumber.max()
                
                //Convertir en affichage en pourcentage des données maximales
                let maxPop = doubleOfMaximumPop! * 100
                
                //Déterminez s'il y a des données
                if doubleOfMaximumPop == nil{
                    print(Error.self)
                }else {
                    //Si vous avez les données
                    if doubleOfMaximumPop != nil{
                        //Obtenez un maximum de données
                        doubleOfMaximumPop = self.doubleOfMaximumPop
                    }else {
                        //Si les nombres sont identiques, choisissez l'un d'entre eux
                        doubleOfMaximumPop = popNumber[0]
                    }
                }

                //Assignez la valeur numérique obtenue par la fonction getweather à maxPop à la variable
                self.maxPop = Int(maxPop)
                
                //Jugez si un parapluie est nécessaire par maxPop et remplacez la sentence jugée par Juge.
                if self.maxPop <= 30 {
                    self.Judge = "⛅️ Aucun parapluie requis ⛅️"
                }else if self.maxPop >= 70 {
                    self.Judge = "☔️ J'ai besoin d'un parapluie ☔️"
                }else {
                    self.Judge = "☂️ Tranquillité d'esprit si vous avez un parapluie pliant ☂️"
                }
                
            }catch let error {
                print("Error:\(error)")
            }
        }
    }
}

Il n'est pas lisible car on ne sait presque pas ce que représente le nom de la variable. Le nom de la variable est difficile ...

Des difficultés

-Puisque je n'ai pas compris le flux de mise à jour des informations de localisation avec LocationManager → géocodage inversé pour acquérir des données, des problèmes tels que l'acquisition de données mais ne pas être affectées à des variables se sont produits.

Liste des sites de référence

Modifications de l'emplacement principal dans iOS 14 Assignez des variables à l'intérieur de la fonction à des variables en dehors de la fonction [Notes sur Codale] (https://qiita.com/s_emoto/items/deda5abcb0adc2217e86)

Entrée
---
** Lecture **
・ Introduction au développement d'applications iPhone "super" qui ne sera jamais frustré ・ Cours intensif de développement d'applications iPhone qui peut être maîtrisé en seulement 2 jours ~~ (Vous ne pouvez en aucun cas le maîtriser en 2 jours) ~~
**Udemy**
・ IOS12: Apprenez à coder et à créer de vraies applications iOS 12 dans Swift 4.2 C'était assez difficile en anglais, mais c'était facile à comprendre car il m'a appris le concept etc. avec des diagrammes d'images. iOS est mis à jour de temps en temps, alors j'ai pensé que je devais suivre de nouvelles connaissances.
** Sortie **
--- **Qiita**

De nombreuses personnes ont posté le code source sur Qiita, j'ai donc pu le créer jusqu'à présent. Je l'ai créé avec l'espoir qu'il serait utile à des personnes dans des circonstances similaires.

Recommended Posts