[英]Yelp API Business Details Endpoint
能夠從業務匹配端點檢索業務 ID 后,我現在嘗試使用該業務 ID 將其匯集到業務詳細信息端點。 我只是在學習調用 API,所以請耐心等待。 謝謝!
以下代碼允許我進行業務匹配:
調用 API -->
import Foundation
import Moya
private let apiKey = ""
enum YelpService {
enum BusinessMatch: TargetType {
case match(name: String, address1: String, city: String, state: String, country: String)
public var baseURL: URL { return NSURL(string: "https://api.yelp.com")! as URL
}
public var path: String {
switch self {
case .match:
return "/v3/businesses/matches"
}
}
var method: Moya.Method {
return.get
}
var sampleData: Data {
return Data()
}
var task: Task {
switch self {
case let .match(name, address1, city, state, country):
return .requestParameters(parameters: ["name": name, "address1": address1, "city": city, "state": state, "country": country, "limit": 1], encoding: URLEncoding.queryString)
}
}
var headers: [String : String]? {
return ["Authorization": "Bearer \(apiKey)"]
}
}
}
返回業務匹配端點 -->
import UIKit
import CoreData
import Moya
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
let service = MoyaProvider<YelpService.BusinessMatch>()
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions:[UIApplication.LaunchOptionsKey: Any]?) -> Bool {
service.request(.match(name: "Sushi Damo", address1:
"330 W 58th St", city: "New York", state: "NY", country: "US")) { (result) in
switch result {
case .success(let response):
print(try? JSONSerialization.jsonObject(with: response.data, options: []))
case .failure(let error):
print("Error: \(error)")
}
}
return true
}
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}
// MARK: - Core Data stack
lazy var persistentContainer: NSPersistentContainer = {
/*
The persistent container for the application. This implementation
creates and returns a container, having loaded the store for the
application to it. This property is optional since there are legitimate
error conditions that could cause the creation of the store to fail.
*/
let container = NSPersistentContainer(name: "APITest")
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
// Replace this implementation with code to handle the error appropriately.
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
/*
Typical reasons for an error here include:
* The parent directory does not exist, cannot be created, or disallows writing.
* The persistent store is not accessible, due to permissions or data protection when the device is locked.
* The device is out of space.
* The store could not be migrated to the current model version.
Check the error message to determine what the actual problem was.
*/
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
return container
}()
// MARK: - Core Data Saving support
func saveContext () {
let context = persistentContainer.viewContext
if context.hasChanges {
do {
try context.save()
} catch {
// Replace this implementation with code to handle the error appropriately.
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
}
}
}
致電業務匹配端點后,我收到以下信息:
Optional({
businesses = (
{
alias = "sushi-damo-new-york";
coordinates = {
latitude = "40.76778";
longitude = "-73.98358";
};
"display_phone" = "(212) 707-8609";
id = J85NKgA4tOgBAoqxu0vBNw;
location = {
address1 = "330 W 58th St";
address2 = "";
address3 = "";
city = "New York";
country = US;
"display_address" = (
"330 W 58th St",
"New York, NY 10019"
);
state = NY;
"zip_code" = 10019;
};
name = "Sushi Damo";
phone = "+12127078609";
}
);
})
我希望能夠從任何業務匹配結果中自動提取該業務 ID。 問題出在以下代碼中。
調用 API -->
enum YelpDetails {
enum BusinessDetail: TargetType {
case BusinessID(id: String)
public var baseURL: URL { return NSURL(string: "https://api.yelp.com")! as URL
}
public var path: String {
switch self {
case .BusinessID:
return "https://api.yelp.com/v3/businesses/{id}"
}
}
var method: Moya.Method {
return.get
}
var sampleData: Data {
return Data()
}
var task: Task {
switch self {
case let .BusinessID(id):
return .requestParameters(parameters: ["BusinessID": id], encoding: URLEncoding.queryString)
}
}
var headers: [String : String]? {
return ["Authorization": "Bearer \(apiKey)"]
}
}
}
從業務詳細信息端點返回結果 -->
let information = MoyaProvider<YelpDetails.BusinessDetail>()
func call(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions:[UIApplication.LaunchOptionsKey: Any]?) -> Bool {
information.request(.BusinessID(id: "J85NKgA4tOgBAoqxu0vBNw")) {
(result) in
switch result {
case .success(let response):
print(try? JSONSerialization.jsonObject(with:
response.data, options: []))
case .failure(let error):
print("Error: \(error)")
}
}
return true
}
通常,當您從網絡中獲取 JSON 數據時,您想要做的是將其序列化為您可以在 Swift 中使用的對象。 幸運的是,Swift 有工具可以輕松地將 json 轉換為對象,然后再轉換回來,即Codable
協議。 查看此視頻了解更多信息。 但本質上,這需要查看我們從服務器獲得的響應並創建一個反映該響應的struct
或class
。 因此,在您的情況下,從服務器返回的原始 json 如下所示:
{
"businesses": [
{
"id": "J85NKgA4tOgBAoqxu0vBNw",
"alias": "sushi-damo-new-york",
"name": "Sushi Damo",
"coordinates": {
"latitude": 40.76778,
"longitude": -73.98358
},
"location": {
"address1": "330 W 58th St",
"address2": "",
"address3": "",
"city": "New York",
"zip_code": "10019",
"country": "US",
"state": "NY",
"display_address": [
"330 W 58th St",
"New York, NY 10019"
]
},
"phone": "+12127078609",
"display_phone": "(212) 707-8609"
}
]
}
這是一個包含一個關鍵businesses
的字典,它具有一組字典的值,其中包含描述業務的鍵值對。 對於上面的 JSON,數組中只有一個元素。
所以現在我們對響應的樣子有了一些了解,我們可以開始創建一些符合Codable
結構。 我們知道我們需要一個帶有屬性businesses
頂級struct
,它是一個包含描述每個業務的結構的數組。
struct BusinessesResponse: Codable {
let businesses: [BusinessResponse]
}
接下來創建BusinessResponse
。 現在,如果您只關心id
,則可以將BusinessResponse
設為:
struct BusinessResponse: Codable {
let id: String
}
然后在此處更新您的回復方式:
service.request(.match(name: "Sushi Damo", address1:
"330 W 58th St", city: "New York", state: "NY", country: "US")) { (result) in
switch result {
case .success(let response):
print(try? JSONSerialization.jsonObject(with: response.data, options: []))
case .failure(let error):
print("Error: \(error)")
}
}
與其將我們想要解碼的 JSON 對象序列化為我們的BusinessesResponse
結構,我們可以通過將switch
語句更新為:
switch result {
case .success(let response):
let businessesResponse = try? JSONDecoder().decode(BusinessesResponse.self, from: response.data)
let firstID = businessesResponse?.businesses.first?.id
// Do something with ID
case .failure(let error):
print("Error: \(error)")
}
我認為下一個請求不會按書面形式進行。 在此請求中,通過 URL 路徑發送參數,即企業的 id。 所以, path
應該是:
public var path: String {
switch self {
case let .BusinessID(id):
return "v3/businesses/\(id)"
}
}
因此task
不再需要處理參數,應該是:
var task: Task {
switch self {
case .BusinessID:
return .requestParameters(parameters:[:], encoding: URLEncoding.queryString)
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.