尝试从函数中 access/modify SwiftUI 变量
Trying to access/modify SwiftUI variable from within a function
我正在尝试从 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 :(")
}
}
}
我将 get 请求移到了它自己的 class,这样我们就可以利用 ObservableObject
和 Publish
数据。发布数据允许订阅视图在发布的数据发生变化时更新数据。在这种情况下,您的 ContentView
通过 @ObservedObject var geoData: ResponseData
代码行订阅数据。
另外,我在您的视图中添加了如何访问两条相关数据,并以列表形式显示,以便于阅读。这应该让您了解如何 access/display 数据。
希望这能为您提供足够的信息来调整答案,使其按照您想要的方式工作。
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: ResponseData.init())
我正在尝试从 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 :(")
}
}
}
我将 get 请求移到了它自己的 class,这样我们就可以利用 ObservableObject
和 Publish
数据。发布数据允许订阅视图在发布的数据发生变化时更新数据。在这种情况下,您的 ContentView
通过 @ObservedObject var geoData: ResponseData
代码行订阅数据。
另外,我在您的视图中添加了如何访问两条相关数据,并以列表形式显示,以便于阅读。这应该让您了解如何 access/display 数据。
希望这能为您提供足够的信息来调整答案,使其按照您想要的方式工作。
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: ResponseData.init())