尝试从函数中访问/修改SwiftUi变量

发布于 2025-01-30 05:15:59 字数 2133 浏览 2 评论 0原文

我正在尝试从JSON获取数据。到目前为止,我可以提取并打印它。

我现在的目标是能够在我的ContentView中使用它,以便可以在文本视图或类似内容中使用。我尝试创建@State变量,将其作为参数等等等。似乎没有任何作用。

我是Swiftui的新手,所以感谢您的帮助!

struct GeoService: Codable {
    var status: String
    var results: [GeoResult]
}

struct GeoResult: Codable {
    
    struct Geometry: Codable {
        
        struct Location: Codable {
            
            let lat: Float
            let lng: Float
            
            init() {
                lat = 32
                lng = 30
            }
        }
        let location: Location
    }
    let formatted_address: String
    let geometry: Geometry
}



struct ContentView: View {

//    @State private var results: Any ?????????
    
    var body: some View {
        NavigationView {
            Text("Test")
                .navigationTitle("Quotes")
                .task {
                    await handleData()
                }
        }
        
    }
    
    func handleData() async {
        let geoResult="""
        {
          "results": [
            {
              "formatted_address": "1600 Amphitheatre Parkway, Mountain View, CA 94043, USA",
              "geometry": {
                "location": {
                  "lat": 37.4224764,
                  "lng": -122.0842499
                }
              }
            },
            {
              "formatted_address": "Test addresss",
              "geometry": {
                "location": {
                  "lat": 120.32132145,
                  "lng": -43.90235469
                }
              }
            }
          ],
          "status": "OK"
        }
        """.data(using: .utf8)!
        
        let decoder = JSONDecoder()
        print("executing handleData()")
        do {
            let obj = try decoder.decode(GeoService.self, from: geoResult)
            for result in obj.results {
                print("Address: \(result.formatted_address)")
                print("Lat/long: (\(result.geometry.location.lat), \(result.geometry.location.lng))")
            }
        } catch {
            print("Did not work :(")
        }
    }
}

I am trying to get data from JSON. So far, I can extract it and print it.

My goal now is to be able to use it in my ContentView so that it can be used in a Text View or something similar. I have tried creating @State variables, passing it as a parameter, etc. etc. and nothing seems to work.

I'm fairly new to SwiftUI, so I appreciate the help!

struct GeoService: Codable {
    var status: String
    var results: [GeoResult]
}

struct GeoResult: Codable {
    
    struct Geometry: Codable {
        
        struct Location: Codable {
            
            let lat: Float
            let lng: Float
            
            init() {
                lat = 32
                lng = 30
            }
        }
        let location: Location
    }
    let formatted_address: String
    let geometry: Geometry
}



struct ContentView: View {

//    @State private var results: Any ?????????
    
    var body: some View {
        NavigationView {
            Text("Test")
                .navigationTitle("Quotes")
                .task {
                    await handleData()
                }
        }
        
    }
    
    func handleData() async {
        let geoResult="""
        {
          "results": [
            {
              "formatted_address": "1600 Amphitheatre Parkway, Mountain View, CA 94043, USA",
              "geometry": {
                "location": {
                  "lat": 37.4224764,
                  "lng": -122.0842499
                }
              }
            },
            {
              "formatted_address": "Test addresss",
              "geometry": {
                "location": {
                  "lat": 120.32132145,
                  "lng": -43.90235469
                }
              }
            }
          ],
          "status": "OK"
        }
        """.data(using: .utf8)!
        
        let decoder = JSONDecoder()
        print("executing handleData()")
        do {
            let obj = try decoder.decode(GeoService.self, from: geoResult)
            for result in obj.results {
                print("Address: \(result.formatted_address)")
                print("Lat/long: (\(result.geometry.location.lat), \(result.geometry.location.lng))")
            }
        } catch {
            print("Did not work :(")
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

花落人断肠 2025-02-06 05:15:59

我将GET请求移至其自己的类中,因此我们可以利用observableObject发布数据。发布数据允许订阅视图在发布的数据更改时更新数据。在这种情况下,您的contentView是通过@obseverobject var geodata订阅数据:worldesedata代码行。

此外,我添加了如何在您视图中访问两个相关数据,并将其显示在列表中以易于阅读。这应该使您了解如何访问/显示数据。

希望这为您提供足够的信息来调整答案,以使其按照自己的意愿进行工作。

import SwiftUI

struct GeoService: Codable {
    var status: String?
    var results: [GeoResult]?
}

struct GeoResult: Codable {

 struct Geometry: Codable {
    
    struct Location: Codable {
        
        let lat: Float
        let lng: Float
        
        init() {
            lat = 32
            lng = 30
        }
    }
    let location: Location
}

let formatted_address: String
    let geometry: Geometry
}

struct ContentView: View {
 @ObservedObject var geoData: ResponseData

 var body: some View {
    NavigationView {
        if #available(iOS 15.0, *) {
            List {
                Text(geoData.geoResultsData?.results?[0].formatted_address ?? "Loading")
                Text(String(geoData.geoResultsData?.results?[0].geometry.location.lat ?? 0))
            }
            .navigationTitle("Quotes")
            .task {
                await geoData.handleData()
                print(geoData.geoResultsData, "yessssss")
            }
        } else {
            Text("failure")
        }
    }
  }
}

class ResponseData: ObservableObject {

@Published var geoResultsData: GeoService?

func handleData() async {
    let geoResult="""
    {
      "results": [
        {
          "formatted_address": "1600 Amphitheatre Parkway, Mountain View, CA 94043, USA",
          "geometry": {
            "location": {
              "lat": 37.4224764,
              "lng": -122.0842499
            }
          }
        },
        {
          "formatted_address": "Test addresss",
          "geometry": {
            "location": {
              "lat": 120.32132145,
              "lng": -43.90235469
            }
          }
        }
      ],
      "status": "OK"
    }
    """.data(using: .utf8)!
    
    let decoder = JSONDecoder()
    print("executing handleData()")
    do {
        let obj = try decoder.decode(GeoService.self, from: geoResult)
        geoResultsData = obj
    } catch {
        print("Did not work :(")
    }
  }
}

编辑:

您需要在应用程序中初始化一些数据。如果需要,您可以暂时将其作为空的初始化。这可以通过执行以下操作来完成:contentView(geodata:ponsponsedata.init())

I moved the get request to its own class so we can leverage ObservableObject and Publish the data. Publishing the data allows the subscribing views to update data when the published data changes. In this case, your ContentView is subscribing to the data via the @ObservedObject var geoData: ResponseData line of code.

Additionally, I added how to access two pieces of relevant data in your view, and displayed it in a list for easy reading. This should give you an idea of how to access/display the data.

Hopefully this provides enough information for you to tweak the answer to get it work the way you desire.

import SwiftUI

struct GeoService: Codable {
    var status: String?
    var results: [GeoResult]?
}

struct GeoResult: Codable {

 struct Geometry: Codable {
    
    struct Location: Codable {
        
        let lat: Float
        let lng: Float
        
        init() {
            lat = 32
            lng = 30
        }
    }
    let location: Location
}

let formatted_address: String
    let geometry: Geometry
}

struct ContentView: View {
 @ObservedObject var geoData: ResponseData

 var body: some View {
    NavigationView {
        if #available(iOS 15.0, *) {
            List {
                Text(geoData.geoResultsData?.results?[0].formatted_address ?? "Loading")
                Text(String(geoData.geoResultsData?.results?[0].geometry.location.lat ?? 0))
            }
            .navigationTitle("Quotes")
            .task {
                await geoData.handleData()
                print(geoData.geoResultsData, "yessssss")
            }
        } else {
            Text("failure")
        }
    }
  }
}

class ResponseData: ObservableObject {

@Published var geoResultsData: GeoService?

func handleData() async {
    let geoResult="""
    {
      "results": [
        {
          "formatted_address": "1600 Amphitheatre Parkway, Mountain View, CA 94043, USA",
          "geometry": {
            "location": {
              "lat": 37.4224764,
              "lng": -122.0842499
            }
          }
        },
        {
          "formatted_address": "Test addresss",
          "geometry": {
            "location": {
              "lat": 120.32132145,
              "lng": -43.90235469
            }
          }
        }
      ],
      "status": "OK"
    }
    """.data(using: .utf8)!
    
    let decoder = JSONDecoder()
    print("executing handleData()")
    do {
        let obj = try decoder.decode(GeoService.self, from: geoResult)
        geoResultsData = obj
    } catch {
        print("Did not work :(")
    }
  }
}

EDIT:

You will need to initialize some data within your app. You can initialize it as empty for the time being, if desired. This can be done by doing something like the following: ContentView(geoData: ResponseData.init())

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文