Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
73 views
in Technique[技术] by (71.8m points)

ios - How to access variable in model from view in Swift

So I finally have the isoCountrycode from the user's current location and need to concatenate it on the end of an API url in order that the URL will respond with the relevant information.

The location's isoCountrycode is found in model/LocationViewModel.swift

Code:

import Foundation
import Combine
import CoreLocation

class LocationViewModel: NSObject, ObservableObject{
  
  @Published var userLatitude: Double = 0
  @Published var userLongitude: Double = 0
  
  private let locationManager = CLLocationManager()
  
  override init() {
    super.init()
    self.locationManager.delegate = self
    self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
    self.locationManager.requestWhenInUseAuthorization()
    self.locationManager.startUpdatingLocation()
  }
}

extension LocationViewModel: CLLocationManagerDelegate {
  
  func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    guard let location = locations.last else { return }
    userLatitude = location.coordinate.latitude
    userLongitude = location.coordinate.longitude
    print(location)
    
    CLGeocoder().reverseGeocodeLocation(location) { (placemark, error) in
        if error != nil
        {
            print("there is an error")
        }
        else
        {
            if let place = placemark?[0]
            {
                let countrycode = place.isoCountryCode
            }
        }
    }
    
  }
}

And the view where I need to use it is here (located in views/HomeAPIContentView.swift), where I would add it to the end of the API URL .e.g "https://emergency-phone-numbers.herokuapp.com/country/" + countrycode

Code for view file is here:


import SwiftUI

struct Response: Decodable {
    var content: [Result]
}

struct Result : Decodable {
    var code: String
    var fire: String
    var name: String
    var police: String
    var medical: String
}

struct HomeAPIContentView: View {
    @State private var content = [Result]()
    @ObservedObject var locationViewModel = LocationViewModel()

    var body: some View {
        List(content, id: .code) { item in
            VStack(alignment: .center) {
                Text("Latitude: (locationViewModel.userLatitude)")
                Text("Longitude: (locationViewModel.userLongitude)")
                Text(item.name)
                    .font(.headline)
                HStack {
                    Text("Medical:")
                    Text(item.medical)
                        .foregroundColor(Color.red)
                    Text("Police:")
                    Text(item.police)
                        .foregroundColor(Color.red)
                    Text("Fire:")
                    Text(item.fire)
                        .foregroundColor(Color.red)
                }
            }
        }
        .onAppear(perform: loadData)
    }
    func loadData() {
        
        let url = URL(string: "https://emergency-phone-numbers.herokuapp.com/country/us")!

        URLSession.shared.dataTask(with: url) { data, response, error in
            if let error = error { print(error); return }
            do {
                let decodedResponse = try JSONDecoder().decode(Result.self, from: data!)
                // we have good data – go back to the main thread
                DispatchQueue.main.async {
                    // update our UI
                    self.content = [decodedResponse]
                }
                
            } catch {
                print(error)
            }
        }.resume()
        
    }
}

If I could access the cc variable from the view, it sounds like an easy enough thing to do but I have no idea how to do that. Please advise.

Thanks in advance.

question from:https://stackoverflow.com/questions/65890208/how-to-access-variable-in-model-from-view-in-swift

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You have a log way to go but here is some help

import Foundation
import Combine
import CoreLocation

class LocationViewModel: NSObject, ObservableObject{
    //MARK: Properties
    @Published var content = [MyResult]()
    @Published var userLatitude: Double = 0
    @Published var userLongitude: Double = 0
    @Published var isoCountryCode = ""{
        didSet{
            //load the data once you have a countrycode
            loadData()
        }
    }
    
    private let locationManager = CLLocationManager()
    //MARK: init
    override init() {
        super.init()
        self.locationManager.delegate = self
        self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
        self.locationManager.requestWhenInUseAuthorization()
        self.locationManager.requestLocation()
    }
    //MARK: Functions
    func loadData() {
        
        let url = URL(string: "https://emergency-phone-numbers.herokuapp.com/country/(isoCountryCode)")!
        
        URLSession.shared.dataTask(with: url) { data, response, error in
            if let error = error { print(error); return }
            do {
                let decodedResponse = try JSONDecoder().decode(MyResult.self, from: data!)
                // we have good data – go back to the main thread
                DispatchQueue.main.async {
                    // update our UI
                    self.content = [decodedResponse]
                }
                
            } catch {
                print(error)
            }
        }.resume()
        
    }
}

extension LocationViewModel: CLLocationManagerDelegate {
    
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        guard let location = locations.last else { return }
        userLatitude = location.coordinate.latitude
        userLongitude = location.coordinate.longitude
        print(location)
        
        CLGeocoder().reverseGeocodeLocation(location) { (placemark, error) in
            if error != nil
            {
                print("there is an error (error)")
            }
            else
            {
                if let place = placemark?[0]
                {
                    self.isoCountryCode = place.isoCountryCode ?? ""
                }
            }
        }
        
    }
    //You have to respond to errors
    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        print(error)
    }
    //You have to respond to changes in autorization too
    func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
        
    }
}

import SwiftUI

struct Response: Decodable {
    var content: [MyResult]
}
//Result already exists in Swift you will cause issues if you use names that are already used
struct MyResult : Decodable {
    var code: String
    var fire: String
    var name: String
    var police: String
    var medical: String
}

struct HomeAPIContentView: View {
    
    @StateObject var locationViewModel = LocationViewModel()
    
    var body: some View {
        List(locationViewModel.content, id: .code) { item in
            VStack(alignment: .center) {
                Text("Latitude: (locationViewModel.userLatitude)")
                Text("Longitude: (locationViewModel.userLongitude)")
                Text(item.name)
                    .font(.headline)
                HStack {
                    Text("Medical:")
                    Text(item.medical)
                        .foregroundColor(Color.red)
                    Text("Police:")
                    Text(item.police)
                        .foregroundColor(Color.red)
                    Text("Fire:")
                    Text(item.fire)
                        .foregroundColor(Color.red)
                }
            }
        }
        
    }
    
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...