gpt4 book ai didi

ios - 如何在 SwiftUI 中的两个观察对象之间传递数据

转载 作者:行者123 更新时间:2023-11-30 10:25:22 26 4
gpt4 key购买 nike

我有以下设置:

主视图

API 类

API 是主视图中的一个Observed Object,一切运行良好。

我想添加到等式LocationManager Class中,并且已经能够在另一个Observed ObjectView更新时这样做当收到位置更新时。

我想要做的(但不确定正确的方法)是将位置传递给 API 类 以在 API 调用中使用。

执行此操作的建议流程是什么。

1 我的观点

struct TempMainView: View {


@ObservedObject var api = APIFetcher()
@ObservedObject var locationMan = LocationMan()

// HOW TO MAKE API CALL ONCE LOCATION IS KNOWN

var body: some View {

Text(api.sampleText)

}

}

2 我的 API 类

public class APIFetcher: ObservableObject {

@Published var sampleText: String = "Local"

init() {
self.load()
}

func load(){

//
// HIT API without LOCATION
//

let url = URL(string: "https://example.com/api/nolocation")!

URLSession.shared.dataTask(with: url) {(data,response,error) in
do {
if let d = data {
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .secondsSince1970
let newString = try decoder.decode(String.self, from: d)
DispatchQueue.main.async {
self.sampleText = newString
}
}
} catch {
print ("Error - \(error)")
}

}.resume()
}

func loadWithCoordinates(){

let coordinates: CLLocationCoordinate2D

//
// HIT API with LOCATION
// (HOW TO CALL THIS WHEN THERE IS A KNOWN LOCATION)
//

let stringFromCoordinates = String("\(coordinates.longitude),\(coordinates.latitude)")

let url = URL(string: "https://example.com/api/location/\(stringFromCoordinates)")!

URLSession.shared.dataTask(with: url) {(data,response,error) in
do {
if let d = data {
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .secondsSince1970
let newString = try decoder.decode(String.self, from: d)
DispatchQueue.main.async {
self.sampleText = newString
}
}
} catch {
print ("Error - \(error)")
}

}.resume()
}
}

3 位置经理类

class LocationManager: NSObject, ObservableObject {

private let locationManager = CLLocationManager()

@Published var location: CLLocation? {
willSet { objectWillChange.send() }
}

override init() {
super.init()

self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
}




}
extension LocationManager: CLLocationManagerDelegate {

func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
//
}

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {

guard let location = locations.last else { return }
self.location = location
//
}
}

最佳答案

我可能只会监听发出的通知。为了清楚起见,我删除了失败的 URL 响应处理代码:

struct TempMainView: View {
@ObservedObject var api = APIFetcher()
var locationMan = LocationManager()
let locationChange = NotificationCenter.default.publisher(for: .location)
var body: some View {
Text(api.sampleText)
.onReceive(locationChange) { note in
let loc = note.userInfo!["location"]! as! CLLocation
self.api.loadWithCoordinates(coordinates: loc.coordinate)
}
}
}
public class APIFetcher: ObservableObject {
@Published var sampleText: String = "Local"
init() {
self.load()
}
func load(){
let url = URL(string: "https://example.com/api/nolocation")!
URLSession.shared.dataTask(with: url) {(data,response,error) in
DispatchQueue.main.async {
self.sampleText = "loaded w/o location"
}
}.resume()
}

func loadWithCoordinates(coordinates: CLLocationCoordinate2D){
let stringFromCoordinates = String("\(coordinates.longitude),\(coordinates.latitude)")
let url = URL(string: "https://example.com/api/location/\(stringFromCoordinates)")!
URLSession.shared.dataTask(with: url) {(data,response,error) in
DispatchQueue.main.async {
self.sampleText = "loaded from \(stringFromCoordinates)"
}
}.resume()
}
}

class LocationManager: NSObject, ObservableObject {
private let locationManager = CLLocationManager()
override init() {
super.init()
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
}
}
extension Notification.Name {
static let location = Notification.Name("location")
}
extension LocationManager: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let location = locations.last else { return }
let note = Notification(name: .location, object: nil, userInfo: ["location": location])
NotificationCenter.default.post(note)
}
}

关于ios - 如何在 SwiftUI 中的两个观察对象之间传递数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60087818/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com