如何在 Moya 中添加参数?

Posted

技术标签:

【中文标题】如何在 Moya 中添加参数?【英文标题】:How to add parameters in Moya? 【发布时间】:2020-03-10 02:39:55 【问题描述】:

所以我一直在编写Gary Tokman 的本教程来构建一个餐厅查看应用程序,它很棒。从头到尾,一切都运行良好。

目的是更改或添加参数,包括“术语”或“类别”。现在,这会将搜索更改为特定企业,而不仅仅是餐馆。

这是我卡住的地方 我似乎找不到执行此参数的正确语法。

这是 Business Endpoint 文档:https://www.yelp.com/developers/documentation/v3/business_search

这些是 swift 文件的代码

网络服务文件

import Foundation
import Moya

enum YelpService 
enum BusinessesProvider: TargetType 
    case search(lat: Double, long: Double)
    case details(id: String)

    var baseURL: URL 
        return URL(string: "https://api.yelp.com/v3/businesses")!
    

    var path: String 
        switch self 
        case .search:
            return "/search"
        case let .details(id):
            return "/\(id)"
        
    

    var method: Moya.Method 
        return .get
    

    var sampleData: Data 
        return Data()
    

    var task: Task 
        switch self 
        case let .search(lat, long):
            return .requestParameters(
                parameters: [ "latitude": lat, "longitude": long, "limit": 30], encoding: URLEncoding.queryString)
        case .details:
            return .requestPlain
        
    

    var headers: [String : String]? 
        return ["Authorization": "Bearer \(apiKey)"]
    


AppDelegate 文件

import UIKit
import Moya
import CoreLocation

@UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate 

    let window = UIWindow()
    let locationService = LocationService()
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let service = MoyaProvider<YelpService.BusinessesProvider>()
    let jsonDecoder = JSONDecoder()
    var navigationController: UINavigationController?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions:
        [UIApplication.LaunchOptionsKey: Any]?) -> Bool 

        jsonDecoder.keyDecodingStrategy = .convertFromSnakeCase

        locationService.didChangeStatus =  [weak self] success in
            if success 
                self?.locationService.getLocation()
            
        

        locationService.newLocation =  [weak self] result in
            switch result 
            case .success(let location):
                self?.loadBusinesses(with: location.coordinate)
            case .failure(let error):
                assertionFailure("Error getting the users location \(error)")
            
        

        switch locationService.status 
        case .notDetermined, .denied, .restricted:
            let locationViewController = storyboard.instantiateViewController(withIdentifier:
                "LocationViewController")
                as? LocationViewController
            locationViewController?.delegate = self
            window.rootViewController = locationViewController
        default:
            let nav = storyboard
                .instantiateViewController(withIdentifier: "StoreNavigationController") as? UINavigationController
            self.navigationController = nav
            window.rootViewController = nav
            locationService.getLocation()
            (nav?.topViewController as? StoreTableViewController)?.delegate = self
        
        window.makeKeyAndVisible()

        return true
    

    private func loadDetails(for viewController: UIViewController, withId id: String) 
        service.request(.details(id: id))  [weak self] (result) in
            switch result 
            case .success(let response):
                guard let strongSelf = self else  return 
                if let details = try? strongSelf.jsonDecoder.decode(Details.self, from: response.data) 
                    let detailsViewModel = DetailsViewModel(details: details)
                    (viewController as? DetailsStoreViewController)?.viewModel = detailsViewModel
                
            case .failure(let error):
                print("Failed to get details \(error)")
            
        
    

    private func loadBusinesses(with coordinate: CLLocationCoordinate2D) 
        service.request(.search(lat: coordinate.latitude, long: coordinate.longitude))  [weak self] (result) in
            guard let strongSelf = self else  return 
            switch result 
            case .success(let response):
                let root = try? strongSelf.jsonDecoder.decode(Root.self, from: response.data)
                let viewModels = root?.businesses
                    .compactMap(StoreListViewModel.init)
                    .sorted(by:  $0.distance < $1.distance)
                if let nav = strongSelf.window.rootViewController as? UINavigationController,
                    let storeListViewController = nav.topViewController as? StoreTableViewController 
                    storeListViewController.viewModels = viewModels ?? []
                 else if let nav = strongSelf.storyboard
                    .instantiateViewController(withIdentifier: "StoreNavigationController") as?
                        UINavigationController 
                    strongSelf.navigationController = nav
                    strongSelf.window.rootViewController?.present(nav, animated: true) 
                        (nav.topViewController as? StoreTableViewController)?.delegate = self
                        (nav.topViewController as? StoreTableViewController)?.viewModels = viewModels ?? []
                    
                
            case .failure(let error):
                print("Error: \(error)")
            
        
    


extension AppDelegate: LocationActions, ListActions 
    func didTapAllow() 
        locationService.requestLocationAuthorization()
    

    func didTapCell(_ viewController: UIViewController, viewModel: StoreListViewModel) 
        loadDetails(for: viewController, withId: viewModel.id)
    

我有什么遗漏或需要添加/更改的吗?

【问题讨论】:

【参考方案1】:

欢迎来到 ***!

首先,试着回到研究那个网络库 Moya。以下是其用法示例: https://github.com/Moya/Moya/tree/master/docs/Examples


所以基本上你的问题是如何在 Moya 中添加参数?

这很容易,尤其是如果您很好地掌握了 Moya 的使用。

让我们添加参数term。我会让你在这个答案之后自己添加另一个参数categories

在您的枚举BusinessProvider 中,有一个案例search,对吧?而且您已经可以看到两个现有参数,我们为什么不添加一个名为term 的新参数?

case search(lat: Double, long: Double, term: String)

既然您在task 中添加参数,而不是在path 中,那么让我们转到task 变量。请记住,您可以在 task 中添加参数,但在 `task 中执行此操作更实用。

让我们在搜索任务

中添加新参数
case let .search(lat, long, term):
            return .requestParameters(
                parameters: [ "latitude": lat, "longitude": long, "term": term, "limit": 30], encoding: URLEncoding.queryString)

瞧!现在,您的 search 案例中有一个新的 term 参数。

【讨论】:

欢迎您!如果帖子回答了您的问题/疑问,请考虑将其标记为答案。

以上是关于如何在 Moya 中添加参数?的主要内容,如果未能解决你的问题,请参考以下文章

如何阻止 MOYA/Alamfire 转义我的身体 json 参数?

如何在 moya 中通过 POST 请求传递 JSON 正文

我们如何使用 Moya 调试/查看通过 API 设置的请求?

如何向 Moya.Response JSON 添加一个字段,该字段不在来自 http 响应的真实有效负载中

使用 Moya 将参数附加到每个网络调用

如何在 Moya 中传递 URLRequest