作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有以下设置:
主视图
API 类
API 是主视图中的一个Observed Object
,一切运行良好。
我想添加到等式LocationManager Class
中,并且已经能够在另一个Observed Object
和View
更新时这样做当收到位置更新时。
我想要做的(但不确定正确的方法)是将位置传递给 API 类
以在 API 调用中使用。
执行此操作的建议流程是什么。
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)
}
}
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()
}
}
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/
我是一名优秀的程序员,十分优秀!