ios - 如何快速访问嵌套 JSON 对象中的值?
问题描述
我的目标是获取离我最近的餐厅并在表格视图中向用户显示这些餐厅。我需要解码这个 API 响应并访问它的一些值对(确切地说是“name”、“url”和“aggregate_rating”)。但是当我尝试序列化 JSON 响应并在终端上打印它时,这就是我得到的(我知道它很长)
{
restaurant = {
R = {
"has_menu_status" = {
delivery = "-1";
takeaway = "-1";
};
"res_id" = 16694062;
};
apikey = e06745d59aa6170842e9760500129d63;
"average_cost_for_two" = 50;
"book_again_url" = "";
"book_form_web_view_url" = "";
cuisines = Turkish;
currency = TL;
deeplink = "zomato://restaurant/16694062";
"events_url" = "https://www.zomato.com/izmir/sen-mutfak-altievler/events#tabtop?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1";
"featured_image" = "";
"has_online_delivery" = 0;
"has_table_booking" = 0;
id = 16694062;
"include_bogo_offers" = 1;
"is_book_form_web_view" = 0;
"is_delivering_now" = 0;
"is_table_reservation_supported" = 0;
"is_zomato_book_res" = 0;
location = {
address = "MOTOPORNE \U00c7IKMAZI SEHITLIK, NARLIDERE \nIZMIR, Altievler, Izmir";
city = Izmir;
"city_id" = 376;
"country_id" = 208;
latitude = "38.3997300000";
locality = Altievler;
"locality_verbose" = "Altievler, Izmir";
longitude = "27.0005000000";
zipcode = "";
};
"menu_url" = "https://www.zomato.com/izmir/sen-mutfak-altievler/menu?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1&openSwipeBox=menu&showMinimal=1#tabtop";
"mezzo_provider" = OTHER;
name = "Sen Mutfak";
offers = (
);
"opentable_support" = 0;
"photos_url" = "https://www.zomato.com/izmir/sen-mutfak-altievler/photos?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1#tabtop";
"price_range" = 2;
"switch_to_order_menu" = 0;
thumb = "";
url = "https://www.zomato.com/izmir/sen-mutfak-altievler?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1";
"user_rating" = {
"aggregate_rating" = "3.4";
"rating_color" = CDD614;
"rating_obj" = {
"bg_color" = {
tint = 500;
type = lime;
};
title = {
text = "3.4";
};
};
"rating_text" = Average;
votes = 7;
};
};
},
{
restaurant = {
R = {
"has_menu_status" = {
delivery = "-1";
takeaway = "-1";
};
"res_id" = 16689453;
};
apikey = e06745d59aa6170842e9760500129d63;
"average_cost_for_two" = 100;
"book_again_url" = "";
"book_form_web_view_url" = "";
cuisines = "Fresh Fish, Seafood";
currency = TL;
deeplink = "zomato://restaurant/16689453";
"events_url" = "https://www.zomato.com/izmir/bizim-gazino-narlidere/events#tabtop?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1";
"featured_image" = "";
"has_online_delivery" = 0;
"has_table_booking" = 0;
id = 16689453;
"include_bogo_offers" = 1;
"is_book_form_web_view" = 0;
"is_delivering_now" = 0;
"is_table_reservation_supported" = 0;
"is_zomato_book_res" = 0;
location = {
address = "Kumsal Sok. 110, Narlidere/Izmir";
city = Izmir;
"city_id" = 376;
"country_id" = 208;
latitude = "38.3995000000";
locality = Narlidere;
"locality_verbose" = "Narlidere, Izmir";
longitude = "26.9865000000";
zipcode = "";
};
"menu_url" = "https://www.zomato.com/izmir/bizim-gazino-narlidere/menu?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1&openSwipeBox=menu&showMinimal=1#tabtop";
"mezzo_provider" = OTHER;
name = "Bizim Gazino";
offers = (
);
"opentable_support" = 0;
"photos_url" = "https://www.zomato.com/izmir/bizim-gazino-narlidere/photos?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1#tabtop";
"price_range" = 3;
"switch_to_order_menu" = 0;
thumb = "";
url = "https://www.zomato.com/izmir/bizim-gazino-narlidere?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1";
"user_rating" = {
"aggregate_rating" = "3.5";
"rating_color" = 9ACD32;
"rating_obj" = {
"bg_color" = {
tint = 500;
type = lime;
};
title = {
text = "3.5";
};
};
"rating_text" = Good;
votes = 12;
};
};
},
{
restaurant = {
R = {
"has_menu_status" = {
delivery = "-1";
takeaway = "-1";
};
"res_id" = 16694494;
};
apikey = e06745d59aa6170842e9760500129d63;
"average_cost_for_two" = 50;
"book_again_url" = "";
"book_form_web_view_url" = "";
cuisines = Turkish;
currency = TL;
deeplink = "zomato://restaurant/16694494";
"events_url" = "https://www.zomato.com/izmir/\U00e7amalti-keyfi-altievler/events#tabtop?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1";
"featured_image" = "";
"has_online_delivery" = 0;
"has_table_booking" = 0;
id = 16694494;
"include_bogo_offers" = 1;
"is_book_form_web_view" = 0;
"is_delivering_now" = 0;
"is_table_reservation_supported" = 0;
"is_zomato_book_res" = 0;
location = {
address = "Narlidere Tansas Yolu \U00dczeri IZMIR, Altievler, Izmir";
city = Izmir;
"city_id" = 376;
"country_id" = 208;
latitude = "38.3985300000";
locality = Altievler;
"locality_verbose" = "Altievler, Izmir";
longitude = "27.0020200000";
zipcode = "";
};
"menu_url" = "https://www.zomato.com/izmir/\U00e7amalti-keyfi-altievler/menu?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1&openSwipeBox=menu&showMinimal=1#tabtop";
"mezzo_provider" = OTHER;
name = "\U00c7amalti Keyfi";
offers = (
);
"opentable_support" = 0;
"photos_url" = "https://www.zomato.com/izmir/\U00e7amalti-keyfi-altievler/photos?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1#tabtop";
"price_range" = 2;
"switch_to_order_menu" = 0;
thumb = "";
url = "https://www.zomato.com/izmir/\U00e7amalti-keyfi-altievler?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1";
"user_rating" = {
"aggregate_rating" = 0;
"rating_color" = CBCBCB;
"rating_obj" = {
"bg_color" = {
tint = 400;
type = grey;
};
title = {
text = "-";
};
};
"rating_text" = "Not rated";
votes = 1;
};
};
},
{
restaurant = {
R = {
"has_menu_status" = {
delivery = "-1";
takeaway = "-1";
};
"res_id" = 16696143;
};
apikey = e06745d59aa6170842e9760500129d63;
"average_cost_for_two" = 25;
"book_again_url" = "";
"book_form_web_view_url" = "";
cuisines = Patisserie;
currency = TL;
deeplink = "zomato://restaurant/16696143";
"events_url" = "https://www.zomato.com/izmir/nil-pastanesi-narlidere/events#tabtop?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1";
"featured_image" = "";
"has_online_delivery" = 0;
"has_table_booking" = 0;
id = 16696143;
"include_bogo_offers" = 1;
"is_book_form_web_view" = 0;
"is_delivering_now" = 0;
"is_table_reservation_supported" = 0;
"is_zomato_book_res" = 0;
location = {
address = "Mithatpasa Cad. No: 325/A, Narlidere / Izmir, Narlidere, Izmir";
city = Izmir;
"city_id" = 376;
"country_id" = 208;
latitude = "38.3944000000";
locality = Narlidere;
"locality_verbose" = "Narlidere, Izmir";
longitude = "27.0050000000";
zipcode = "";
};
"menu_url" = "https://www.zomato.com/izmir/nil-pastanesi-narlidere/menu?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1&openSwipeBox=menu&showMinimal=1#tabtop";
"mezzo_provider" = OTHER;
name = "Nil Pastanesi";
offers = (
);
"opentable_support" = 0;
"photos_url" = "https://www.zomato.com/izmir/nil-pastanesi-narlidere/photos?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1#tabtop";
"price_range" = 1;
"switch_to_order_menu" = 0;
thumb = "";
url = "https://www.zomato.com/izmir/nil-pastanesi-narlidere?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1";
"user_rating" = {
"aggregate_rating" = 0;
"rating_color" = CBCBCB;
"rating_obj" = {
"bg_color" = {
tint = 400;
type = grey;
};
title = {
text = "-";
};
};
"rating_text" = "Not rated";
votes = 3;
};
};
},
{
restaurant = {
R = {
"has_menu_status" = {
delivery = "-1";
takeaway = "-1";
};
"res_id" = 16696674;
};
apikey = e06745d59aa6170842e9760500129d63;
"average_cost_for_two" = 40;
"book_again_url" = "";
"book_form_web_view_url" = "";
cuisines = Izgara;
currency = TL;
deeplink = "zomato://restaurant/16696674";
"events_url" = "https://www.zomato.com/izmir/kanat\U00e7i-h\U00fcso-narlidere/events#tabtop?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1";
"featured_image" = "";
"has_online_delivery" = 0;
"has_table_booking" = 0;
id = 16696674;
"include_bogo_offers" = 1;
"is_book_form_web_view" = 0;
"is_delivering_now" = 0;
"is_table_reservation_supported" = 0;
"is_zomato_book_res" = 0;
location = {
address = "\U00c7ESME OTOBAN ALTI NO:2 TANSAS SERVIS YOLU \U00dcZERI\nBal\U00e7ova\nIZMIR, Narlidere, Izmir";
city = Izmir;
"city_id" = 376;
"country_id" = 208;
latitude = "38.3932000000";
locality = Narlidere;
"locality_verbose" = "Narlidere, Izmir";
longitude = "26.9890000000";
zipcode = "";
};
"menu_url" = "https://www.zomato.com/izmir/kanat\U00e7i-h\U00fcso-narlidere/menu?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1&openSwipeBox=menu&showMinimal=1#tabtop";
"mezzo_provider" = OTHER;
name = "Kanat\U00e7i H\U00fcso";
offers = (
);
"opentable_support" = 0;
"photos_url" = "https://www.zomato.com/izmir/kanat\U00e7i-h\U00fcso-narlidere/photos?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1#tabtop";
"price_range" = 2;
"switch_to_order_menu" = 0;
thumb = "";
url = "https://www.zomato.com/izmir/kanat\U00e7i-h\U00fcso-narlidere?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1";
"user_rating" = {
"aggregate_rating" = 0;
"rating_color" = CBCBCB;
"rating_obj" = {
"bg_color" = {
tint = 400;
type = grey;
};
title = {
text = "-";
};
};
"rating_text" = "Not rated";
votes = 3;
};
};
},
{
restaurant = {
R = {
"has_menu_status" = {
delivery = "-1";
takeaway = "-1";
};
"res_id" = 16696286;
};
apikey = e06745d59aa6170842e9760500129d63;
"average_cost_for_two" = 40;
"book_again_url" = "";
"book_form_web_view_url" = "";
cuisines = Cafe;
currency = TL;
deeplink = "zomato://restaurant/16696286";
"events_url" = "https://www.zomato.com/izmir/tar\U00e7in-altievler/events#tabtop?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1";
"featured_image" = "";
"has_online_delivery" = 0;
"has_table_booking" = 0;
id = 16696286;
"include_bogo_offers" = 1;
"is_book_form_web_view" = 0;
"is_delivering_now" = 0;
"is_table_reservation_supported" = 0;
"is_zomato_book_res" = 0;
location = {
address = "Yildirim Kemal Cad., Altievler Mah., No:16 Sahilevleri / Izmir, Altievler, Izmir";
city = Izmir;
"city_id" = 376;
"country_id" = 208;
latitude = "38.3976000000";
locality = Altievler;
"locality_verbose" = "Altievler, Izmir";
longitude = "26.9975000000";
zipcode = "";
};
"menu_url" = "https://www.zomato.com/izmir/tar\U00e7in-altievler/menu?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1&openSwipeBox=menu&showMinimal=1#tabtop";
"mezzo_provider" = OTHER;
name = "Tar\U00e7in";
offers = (
);
"opentable_support" = 0;
"photos_url" = "https://www.zomato.com/izmir/tar\U00e7in-altievler/photos?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1#tabtop";
"price_range" = 2;
"switch_to_order_menu" = 0;
thumb = "";
url = "https://www.zomato.com/izmir/tar\U00e7in-altievler?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1";
"user_rating" = {
"aggregate_rating" = 0;
"rating_color" = CBCBCB;
"rating_obj" = {
"bg_color" = {
tint = 400;
type = grey;
};
title = {
text = "-";
};
};
"rating_text" = "Not rated";
votes = 1;
};
};
},
{
restaurant = {
R = {
"has_menu_status" = {
delivery = "-1";
takeaway = "-1";
};
"res_id" = 16691486;
};
apikey = e06745d59aa6170842e9760500129d63;
"average_cost_for_two" = 70;
"book_again_url" = "";
"book_form_web_view_url" = "";
cuisines = "Restaurant Cafe";
currency = TL;
deeplink = "zomato://restaurant/16691486";
"events_url" = "https://www.zomato.com/izmir/mavi-yesil-restaurant-narlidere/events#tabtop?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1";
"featured_image" = "";
"has_online_delivery" = 0;
"has_table_booking" = 0;
id = 16691486;
"include_bogo_offers" = 1;
"is_book_form_web_view" = 0;
"is_delivering_now" = 0;
"is_table_reservation_supported" = 0;
"is_zomato_book_res" = 0;
location = {
address = "Mithatpasa Cad. No:465 \U00c7esme Otoban Girisi Karsisi, Narlidere, Izmir";
city = Izmir;
"city_id" = 376;
"country_id" = 208;
latitude = "38.3956092539";
locality = Narlidere;
"locality_verbose" = "Narlidere, Izmir";
longitude = "26.9942235947";
zipcode = "";
};
"menu_url" = "https://www.zomato.com/izmir/mavi-yesil-restaurant-narlidere/menu?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1&openSwipeBox=menu&showMinimal=1#tabtop";
"mezzo_provider" = OTHER;
name = "Mavi Yesil Restaurant";
offers = (
);
"opentable_support" = 0;
"photos_url" = "https://www.zomato.com/izmir/mavi-yesil-restaurant-narlidere/photos?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1#tabtop";
"price_range" = 3;
"switch_to_order_menu" = 0;
thumb = "";
url = "https://www.zomato.com/izmir/mavi-yesil-restaurant-narlidere?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1";
"user_rating" = {
"aggregate_rating" = 0;
"rating_color" = CBCBCB;
"rating_obj" = {
"bg_color" = {
tint = 400;
type = grey;
};
title = {
text = "-";
};
};
"rating_text" = "Not rated";
votes = 3;
};
};
},
{
restaurant = {
R = {
"has_menu_status" = {
delivery = "-1";
takeaway = "-1";
};
"res_id" = 16696730;
};
apikey = e06745d59aa6170842e9760500129d63;
"average_cost_for_two" = 50;
"book_again_url" = "";
"book_form_web_view_url" = "";
cuisines = Izgara;
currency = TL;
deeplink = "zomato://restaurant/16696730";
"events_url" = "https://www.zomato.com/izmir/mangal-borsasi-altievler/events#tabtop?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1";
"featured_image" = "";
"has_online_delivery" = 0;
"has_table_booking" = 0;
id = 16696730;
"include_bogo_offers" = 1;
"is_book_form_web_view" = 0;
"is_delivering_now" = 0;
"is_table_reservation_supported" = 0;
"is_zomato_book_res" = 0;
location = {
address = "Narlidere Sehitlik Karsisi, Altievler, Izmir";
city = Izmir;
"city_id" = 376;
"country_id" = 208;
latitude = "38.3960000000";
locality = Altievler;
"locality_verbose" = "Altievler, Izmir";
longitude = "26.9978000000";
zipcode = "";
};
"menu_url" = "https://www.zomato.com/izmir/mangal-borsasi-altievler/menu?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1&openSwipeBox=menu&showMinimal=1#tabtop";
"mezzo_provider" = OTHER;
name = "Mangal Borsasi";
offers = (
);
"opentable_support" = 0;
"photos_url" = "https://www.zomato.com/izmir/mangal-borsasi-altievler/photos?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1#tabtop";
"price_range" = 2;
"switch_to_order_menu" = 0;
thumb = "";
url = "https://www.zomato.com/izmir/mangal-borsasi-altievler?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1";
"user_rating" = {
"aggregate_rating" = 0;
"rating_color" = CBCBCB;
"rating_obj" = {
"bg_color" = {
tint = 400;
type = grey;
};
title = {
text = "-";
};
};
"rating_text" = "Not rated";
votes = 2;
};
};
},
{
restaurant = {
R = {
"has_menu_status" = {
delivery = "-1";
takeaway = "-1";
};
"res_id" = 16695847;
};
apikey = e06745d59aa6170842e9760500129d63;
"average_cost_for_two" = 40;
"book_again_url" = "";
"book_form_web_view_url" = "";
cuisines = "Turkish Pizza";
currency = TL;
deeplink = "zomato://restaurant/16695847";
"events_url" = "https://www.zomato.com/izmir/annem-pide-narlidere/events#tabtop?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1";
"featured_image" = "";
"has_online_delivery" = 0;
"has_table_booking" = 0;
id = 16695847;
"include_bogo_offers" = 1;
"is_book_form_web_view" = 0;
"is_delivering_now" = 0;
"is_table_reservation_supported" = 0;
"is_zomato_book_res" = 0;
location = {
address = "MITHAT PASA CAD. NO:349, Narlidere, Izmir";
city = Izmir;
"city_id" = 376;
"country_id" = 208;
latitude = "38.3945000000";
locality = Narlidere;
"locality_verbose" = "Narlidere, Izmir";
longitude = "27.0044000000";
zipcode = "";
};
"menu_url" = "https://www.zomato.com/izmir/annem-pide-narlidere/menu?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1&openSwipeBox=menu&showMinimal=1#tabtop";
"mezzo_provider" = OTHER;
name = "Annem Pide";
offers = (
);
"opentable_support" = 0;
"photos_url" = "https://www.zomato.com/izmir/annem-pide-narlidere/photos?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1#tabtop";
"price_range" = 2;
"switch_to_order_menu" = 0;
thumb = "";
url = "https://www.zomato.com/izmir/annem-pide-narlidere?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1";
"user_rating" = {
"aggregate_rating" = 0;
"rating_color" = CBCBCB;
"rating_obj" = {
"bg_color" = {
tint = 400;
type = grey;
};
title = {
text = "-";
};
};
"rating_text" = "Not rated";
votes = 2;
};
};
}
)
这是我的自定义结构
import Foundation
struct User_rating: Codable {
var aggregate_rating: String
}
struct Restaurant: Codable {
var name: String
var url: String
var thumb: String
var user_rating: User_rating
var photos_url: String
}
这是我序列化 JSON 响应的地方:
import UIKit
import Foundation
import CoreLocation
class RestaurantTableViewController: UITableViewController, CLLocationManagerDelegate {
let apiKey: String = "e06745d59aa6170842e9760500129d63"
let cellIdentifier: String = "restaurantCell"
var restaurants = [Restaurant]()
var restaurantImages: [URL] = []
var locationManager = CLLocationManager()
// MARK: Lifecycle methods
override func viewDidLoad() {
super.viewDidLoad()
let urlString = """
https://developers.zomato.com/api/v2.1/geocode?lat=\(locationManager.location.coordinate.latitude)&lon=\(locationManager.location.coordinate.longitude)
"""
let url = URL(string: urlString)
if url != nil {
var request = URLRequest(url: url!)
request.httpMethod = "GET"
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.addValue(apiKey, forHTTPHeaderField: "user-key")
URLSession.shared.dataTask(with: request) { (data, response, error) in
guard let data = data, error == nil else { return }
let httpResponse = response as! HTTPURLResponse
if httpResponse.statusCode == 200 {
do {
let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as! [String:Any]
print(json) // Prints the response given above
} catch _ {
}
}
}.resume()
}
}
}
我遵循了几个 SO 答案和其他指南。任何帮助表示赞赏。
解决方案
斯威夫特 5
您需要更换:
do {
let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as! [String:Any]
print(json) // Prints the response given above
} catch _ {
}
和
struct RestaurantWrapper {
let restaurant: Restaurant
}
do {
let decoder = JSONDecoder()
let list: [RestaurantWrapper] = try decoder.decode([RestaurantWrapper].self, from: data)
} catch let error {
print("ERROR: \(error)") //!!!!!!!!!!!!!!! never halt errors
}
推荐阅读
- java - 从模板字符串中查找值
- php - 根据内部数组的值和重复值重新排列多维数组
- php - 加入查询以获得不同的结果
- entity-framework - DbContext SaveChanges - System.Data.SqlClient.SqlException:执行超时已过期
- javascript - 在打开窗口的情况下打开 pdf 在 Chrome 中不起作用
- java - 如何解决tomcat上的以下异常
- sql - 我需要如何在表格中查找精确匹配
- asp.net - DataProtection API (C#) 的问题
- java - 如何在属性文件中保存复选框状态
- python-3.x - 无法获取数据框列中的值总和