我有一个看起来像这样的api响应片段...
{
"status": "OK",
"predictions": [
{
"description": "Hilton Head Island, SC, USA",
"id": "67bd386c0fb3d4f77bf3cb283a6d75565ea11732",
"matched_substrings": [
{
"length": 6,
"offset": 0
}
],
"place_id": "ChIJrRnTjtx5_IgRPSii63qm5Sw",
"reference": "ChIJrRnTjtx5_IgRPSii63qm5Sw",
"structured_formatting": {
"main_text": "Hilton Head Island",
"main_text_matched_substrings": [
{
"length": 6,
"offset": 0
}
],
"secondary_text": "SC, USA"
},
"types": [
"locality",
"political",
"geocode"
]
}
}
由此,我需要main_text
和secondary_text
。为此,我做了一个像这样的模型课...
class FilteredLocations: Codable {
var locationDetails: [String: Any]
enum CodingKeys: String, CodingKey {
case locationDetails = "structured_formatting"
}
required init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
locationDetails = try? values.decode([String: Any].self, forKey: .locationDetails)//ERROR HERE
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(locationDetails, forKey: .locationDetails)//ERROR HERE
}
}
但是在上面的代码中,在提到的//ERROR HERE
处抛出了错误Reference to member 'locationDetails' cannot be resolved without a contextual type
我做错了什么...?
编辑1 :这就是我解析数据的方式。
if let productService = result?["predictions"] as? [[String: Any]] ,
let jsonData = try? JSONSerialization.data(withJSONObject: productService as Any, options: []) {
do {
let filteredLocations = try? JSONDecoder().decode(FilteredLocations.self, from: jsonData)
self.tableview.reloadData()
} catch {
print("error \(error.localizedDescription)")
}
}
编辑2 google api响应:
{
"predictions" : [
{
"description" : "Hilton Head Island, SC, USA",
"id" : "gfhgj3hgjhsgvh4hj4hgj424hfjhjha11732",
"matched_substrings" : [
{
"length" : 6,
"offset" : 0
}
],
"place_id" : "dfgegregergrgrergergewrer5Sw",
"reference" : "bvEQfdgetehetheterbgcbng5Sw",
"structured_formatting" : {
"main_text" : "Hilton Head Island",
"main_text_matched_substrings" : [
{
"length" : 6,
"offset" : 0
}
],
"secondary_text" : "SC, USA"
},
"terms" : [
{
"offset" : 0,
"value" : "Hilton Head Island"
},
{
"offset" : 20,
"value" : "SC"
},
{
"offset" : 24,
"value" : "USA"
}
],
"types" : [ "locality", "political", "geocode" ]
}
],
"status" : "OK"
}
编辑3 我如何进行api调用并获取要解析的数据。
WebServiceClient.shared.getNearbyLocationsSearchList(withParameters: parameters, inputText: searchText) { [weak self] (isSuccess, result) in
guard let `self` = self else { return }
if isSuccess, result != nil {
print("Successfully fetched nearby locations!")
if let productService = result?["predictions"] as? [[String: Any]] ,
let jsonData = try? JSONSerialization.data(withJSONObject: productService as Any, options: []) {
do {
let filteredLocations = try? JSONDecoder().decode([FilteredLocations].self, from: jsonData)
} catch {
print("error \(error.localizedDescription)")
}
}
}
编辑4 ,这是调用网络服务后从api上获得的result
。
{
description = "Houston, TX, USA";
id = 25faf0a7ef1056b980f3a19237cfa8e295668123;
"matched_substrings" = (
{
length = 1;
offset = 0;
}
);
"place_id" = ChIJAYWNSLS4QIYROwVl894CDco;
reference = ChIJAYWNSLS4QIYROwVl894CDco;
"structured_formatting" = {
"main_text" = Houston;
"main_text_matched_substrings" = (
{
length = 1;
offset = 0;
}
);
"secondary_text" = "TX, USA";
};
terms = (
{
offset = 0;
value = Houston;
},
{
offset = 9;
value = TX;
},
{
offset = 13;
value = USA;
}
);
types = (
locality,
political,
geocode
);
}
编辑5
答案 0 :(得分:1)
如果您引用的是此JSON(有效,不同于您所附加的JSON ...)
{
"status": "OK",
"predictions": [{
"description": "Hilton Head Island, SC, USA",
"id": "67bd386c0fb3d4f77bf3cb283a6d75565ea11732",
"matched_substrings": [{
"length": 6,
"offset": 0
}],
"place_id": "ChIJrRnTjtx5_IgRPSii63qm5Sw",
"reference": "ChIJrRnTjtx5_IgRPSii63qm5Sw",
"structured_formatting": {
"main_text": "Hilton Head Island",
"main_text_matched_substrings": [{
"length": 6,
"offset": 0
}],
"secondary_text": "SC, USA"
},
"types": [
"locality",
"political",
"geocode"
]
}]
}
然后这是如何为所有JSON数据创建结构的方法:
struct FilteredLocations: Codable {
let status: String
let predictions: [Prediction]
}
struct Prediction: Codable {
let description, id: String
let matchedSubstrings: [MatchedSubstring]
let placeID, reference: String
let structuredFormatting: StructuredFormatting
let types: [String]
enum CodingKeys: String, CodingKey {
case description, id
case matchedSubstrings = "matched_substrings"
case placeID = "place_id"
case reference
case structuredFormatting = "structured_formatting"
case types
}
}
struct MatchedSubstring: Codable {
let length, offset: Int
}
struct StructuredFormatting: Codable {
let mainText: String
let mainTextMatchedSubstrings: [MatchedSubstring]
let secondaryText: String
enum CodingKeys: String, CodingKey {
case mainText = "main_text"
case mainTextMatchedSubstrings = "main_text_matched_substrings"
case secondaryText = "secondary_text"
}
}
然后像这样解码:
let filteredLocations = try? JSONDecoder().decode(FilteredLocations.self, from: jsonData)
要编码数据:
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
do {
let jsonData = try encoder.encode(filteredLocations)
if let jsonString = String(data: jsonData, encoding: .utf8) {
print(jsonString)
// Prints out the JSON you just encoded.
}
} catch {
print(error.localizedDescription)
}
要获取主要文本和辅助文本,
main: filteredLocations.structuredFormatting.mainText
secondary: filteredLocations.structuredFormatting.secondaryText
我希望这个答案对您有用!
编辑1:
尝试以下代码:
WebServiceClient.shared.getNearbyLocationsSearchList(withParameters: parameters, inputText: searchText) { [weak self] (isSuccess, result) in
guard let `self` = self else { return }
if isSuccess, result != nil {
print("Successfully fetched nearby locations!")
if let jsonData = try? JSONSerialization.data(withJSONObject: result as Any, options: []) {
do {
let filteredLocations = try? JSONDecoder().decode([FilteredLocations].self, from: jsonData)
} catch {
print("error \(error.localizedDescription)")
}
}
}