json - 如何在 DetailViewController 中获取 JSONData? swift

标签 json swift api

我有 2 个 Controller :CollectionViewControllerDetailViewController。在 CollectionViewController 中,我获取了数据并获得了 coctails。现在我想要获取 coctails?.drinks?[indexPath.row] 并传入 DetailViewController,我需要再次 fetchRequest 但需要使用另一个 API 和新 url。但是加载DetailViewController时,方法networkDataService.fetchDrink(drinkName: drinkName)不起作用。 我做错了什么?

struct Coctail: Codable {
   let drinks: [Drink]?
}

struct Drink: Codable {
   let strDrink : String?
   let strDrinkThumb : URL?
}

class NetworkDataService {

let networkManager = NetworkManager.shared

func fetchCoctails(completion: @escaping (Coctail?) -> Void) {
    let url = "https://www.thecocktaildb.com/api/json/v1/1/filter.php?c=Cocktail"
    networkManager.fetchData(url: url, completion: completion)
}

func fetchDrink(drinkName: String, completion: @escaping (Coctail?) -> Void) {
    let url = "https://www.thecocktaildb.com/api/json/v1/1/search.php?s=\(drinkName)"
    networkManager.fetchData(url: url, completion: completion)
   }
}

class CollectionViewController: UICollectionViewController {

var coctails: Coctail?
let networkDataService = NetworkDataService()

override func viewDidLoad() {
    super.viewDidLoad()

    networkDataService.fetchCoctails() { (coctails) in
        self.coctails = coctails

        DispatchQueue.main.async {
            self.collectionView.reloadData()
        }
    }

}

// MARK: UICollectionViewDataSource

override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return coctails?.drinks?.count ?? 0
}

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell

    let drink = coctails?.drinks?[indexPath.row]

    cell.config(drink: drink)

    return cell
}

// MARK: - Navigation

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

    guard let indexPath = collectionView.indexPathsForSelectedItems?.first else { return }
    let drink = coctails?.drinks?[indexPath.row]

    let destination = segue.destination as! DetailViewController
    destination.drinkName = drink?.strDrink ?? ""
   }
}

class DetailViewController: UIViewController {

var drinkName = ""
var coctail: Coctail?
let networkDataService = NetworkDataService()

override func viewDidLoad() {
    super.viewDidLoad()

    networkDataService.fetchDrink(drinkName: drinkName) { (coctail) in
        self.coctail = coctail
    }
}

最佳答案

如果您在 strDrink 中使用饮料名称,那么问题是您发送的内容类似于:

'57 Chevy with a White License Plate

这意味着 URL 将类似于:

https://www.thecocktaildb.com/api/json/v1/1/search.php?s='57 Chevy with a White License Plate

并且不会自动翻译成 URL 编码的 URL。

此方法的问题是您需要在将名称发送到 API 之前对名称进行 url 编码。像这样的东西:

networkDataService.fetchDrink(drinkName: drinkName.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)) { (coctail) in
    self.coctail = coctail
}

这样你会得到像这样的 URL:

https://www.thecocktaildb.com/api/json/v1/1/search.php?s=%2757%20Chevy%20with%20a%20White%20License%20Plate

指的是这个 URL 编码的字符串: Swift - encode URL

另一方面,您的 API 会返回饮料的 ID idDrink,它应该用于获取详细信息,而不是运行搜索然后根据特定名称提取第一个。稍后还可能发生的情况是,您可能有两个 Jack Daniel's,具有不同的值,您将始终显示第一个。

关于json - 如何在 DetailViewController 中获取 JSONData? swift ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56883689/

相关文章:

php - JQuery/CSS 日历

javascript - Youtube 数据 API 视频嵌入限制

ios - firebaseobserveSingleEvent 在 swift 中已弃用

api - Flutter从API获取数据以构建方法

jquery - JSONP解析错误

jquery - 使用 jQuery 通过 JSON 显示数据的最佳方式

ios - RxSwift 中 Disposables.create() 的目的

macos - 无法使用 AVAudioPlayer 播放专辑

c# - 延迟 API 操作

java - 无法扩展MapActivity类?