我尝试从看起来像this的API中获取信息:
我可以使用以下方法解析信息:
override func viewDidLoad() {
super.viewDidLoad()
getAPI()
}
func getAPI() {
let task = URLSession.shared.dataTask(with: url) {(data, response, error) in
if error == nil {
guard let urlContent = data else { return }
do {
let JSONResult = try JSONSerialization.jsonObject(with: urlContent, options: .mutableContainers)
print("JSON Result:", JSONResult)
print("-----------------")
print(type(of: JSONResult))
} catch {
print("JSON processing failed.")
}
} else {
print("Error serializing JSON:", error!)
}
}
task.resume()
}
但是我在从API检索单个数据时遇到麻烦(例如“ x”,“ y”和“ companyZoneId”)。我尝试从JSONResult(JSONResult.first)中提取第一个元素,但是它仅显示数组中第一个元素的组成部分(因此,我假设我在array(?)中有一个数组。
如何获取和存储这些元素?因为那样的话我想在地图上显示这些位置,但这是我以后要处理的另一步。目前,我一直坚持从该API数组的每个元素中检索单个信息,而我会根据您的专业知识为我提供指导。
我在这里阅读了不同的教程,并在youtube上看到了一些视频,但没有一个能帮助我解决这种特殊情况。
感谢您的帮助。
问候!
答案 0 :(得分:0)
找到了我的答案: 首先,我创建了一个包含所有API元素的结构:
dfb
然后,我创建了一种方法来从API中获取所需的元素:
struct MyInfo: Codable {
let id: String
let name: String
let x: Double // Longitude
let y: Double // Latitude
let licencePlate: String?
let range: Int?
let batteryLevel: Int?
let seats: Int?
let model: String?
let resourceImageId: String?
let pricePerMinuteParking: Int?
let pricePerMinuteDriving: Int?
let realTimeData: Bool?
let engineType: String?
let resourceType: String?
let companyZoneId: Int
let helmets: Int?
let station: Bool?
let availableResources: Int?
let spacesAvailable: Int?
let allowDropoff: Bool?
let bikesAvailable: Int?
}
现在,我还有一个无法解决的问题:我无法将x和y值(来自jsonResult)分配给类内部的全局变量(self.lonX和self.latY)。
我该如何实现?我做了另一个应用程序,在该应用程序中我做了类似的事情(创建了一个全局变量结构,我分配了从API获取的值以供其他地方使用),但现在看来它不起作用。
我在寻找您的经验和提示。
感谢您的帮助。
答案 1 :(得分:0)
我建议您使用quicktype。只需将您的json粘贴在那里,它将为您生成模型对象以对其进行解码。这就是使用json所得到的:
// MARK: - WelcomeElement
class WelcomeElement: Codable {
let id, name: String
let x, y: Double
let licencePlate: String?
let range, batteryLevel, seats: Int?
let model: Model?
let resourceImageID: ResourceImageID?
let pricePerMinuteParking, pricePerMinuteDriving: Int?
let realTimeData: Bool
let engineType: String?
let resourceType: ResourceType?
let companyZoneID: Int
let helmets: Int?
let station: Bool?
let availableResources, spacesAvailable: Int?
let allowDropoff: Bool?
let bikesAvailable: Int?
enum CodingKeys: String, CodingKey {
case id, name, x, y, licencePlate, range, batteryLevel, seats, model
case resourceImageID = "resourceImageId"
case pricePerMinuteParking, pricePerMinuteDriving, realTimeData, engineType, resourceType
case companyZoneID = "companyZoneId"
case helmets, station, availableResources, spacesAvailable, allowDropoff, bikesAvailable
}
init(id: String, name: String, x: Double, y: Double, licencePlate: String?, range: Int?, batteryLevel: Int?, seats: Int?, model: Model?, resourceImageID: ResourceImageID?, pricePerMinuteParking: Int?, pricePerMinuteDriving: Int?, realTimeData: Bool, engineType: String?, resourceType: ResourceType?, companyZoneID: Int, helmets: Int?, station: Bool?, availableResources: Int?, spacesAvailable: Int?, allowDropoff: Bool?, bikesAvailable: Int?) {
self.id = id
self.name = name
self.x = x
self.y = y
self.licencePlate = licencePlate
self.range = range
self.batteryLevel = batteryLevel
self.seats = seats
self.model = model
self.resourceImageID = resourceImageID
self.pricePerMinuteParking = pricePerMinuteParking
self.pricePerMinuteDriving = pricePerMinuteDriving
self.realTimeData = realTimeData
self.engineType = engineType
self.resourceType = resourceType
self.companyZoneID = companyZoneID
self.helmets = helmets
self.station = station
self.availableResources = availableResources
self.spacesAvailable = spacesAvailable
self.allowDropoff = allowDropoff
self.bikesAvailable = bikesAvailable
}
}
enum Model: String, Codable {
case askoll = "Askoll"
case bmw1Series = "BMW 1 Series"
case bmwX1 = "BMW X1"
case citroenCZero = "Citroen C-Zero"
case mini3Door = "MINI 3-Door"
case miniConvertible = "MINI Convertible"
}
enum ResourceImageID: String, Codable {
case vehicleGenDN = "vehicle_gen_dn"
case vehicleGenDNBmwS1 = "vehicle_gen_dn_bmw_s1"
case vehicleGenEcooltra = "vehicle_gen_ecooltra"
case vehicleGenEmov = "vehicle_gen_emov"
}
enum ResourceType: String, Codable {
case car = "CAR"
case electricCar = "ELECTRIC_CAR"
case moped = "MOPED"
}
typealias Welcome = [WelcomeElement]
然后只使用JSONDecoder
let welcome = try? newJSONDecoder().decode(Welcome.self, from: jsonData)
答案 2 :(得分:0)
您使用结构完成此操作的方式很棒。您还可以通过使用与JSON相同的结构强制转换结果来获取值({}
是字典,[]
是数组)
例如,如果您的结果返回为:
{"Food": [
"category": "Meat",
"safeTimeLeftOut": "2 Hours"
],
[
"category": "Dairy",
"safeTimeLeftOut: "3 Hours"
]
}
这是[String:Any]类型的结果,需要这样转换。
let result = JSONResult as? [String:Any]
现在您可以将结果转换为适当的类型
let jsonDict = result["Food"] as? [[[String:String]]] //Array of Array of Dictionaries with key/value String
foodDict将为:[[[[“ category”:“肉”],[“ safeTimeLeftOut”:“ 2小时”]]],[[“ category”:“乳制品”],[“ safeTimeLeftOut:” 3小时“ ]]]
然后您可以遍历它以获得每本字典
for arrOfDicts in jsonDict {
print(arrOfDicts) //prints the whole array of dictionaries
for foodDict in arrOfDicts {
print(foodDict) //prints 1 JSON array
//if you want a value:
if let category = foodDict["category"] {
print(category) //prints the value of the key "category"
}
}
}