[英]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.所以我终于得到了用户当前位置的 isoCountrycode,需要将它连接到 API url 的末尾,以便 ZE6B391A8D2C4D45902A23A8B658570 响应相关信息。
The location's isoCountrycode is found in model/LocationViewModel.swift该位置的 isoCountrycode 位于 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.eg "https://emergency-phone-numbers.herokuapp.com/country/" + countrycode我需要使用它的视图在这里(位于views/HomeAPIContentView.swift),我会将它添加到API URL.eg“https://emergency-phone-numbers.herokuapp.com/国家/" + 国家代码
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.如果我可以从视图中访问 cc 变量,这听起来很容易,但我不知道该怎么做。 Please advise.
请指教。
Thanks in advance.提前致谢。
You have a log way to go but here is some help您有 go 的日志方式,但这里有一些帮助
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)
}
}
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.