【问题标题】:How to pass raw JSON Body with POST request in Moya request如何在 Moya 请求中通过 POST 请求传递原始 JSON 正文
【发布时间】:2021-11-01 13:01:26
【问题描述】:

我正在使用Moya 库在我的项目中调用 api。

现在是在正文中通过 POST 请求传递原始 json 对象(将多个对象作为单个对象)所需的 API 之一。它在邮递员中工作正常。

查看下面的截图,

还检查原始正文 json,

    {
            "geometry": {
                "location": {
                    "lat": "22.7195687",
                    "lng": "75.8577258"
                }
            },
            "icon": "https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/geocode-71.png",
            "name": "Indore",
            "photos": [
                {
                    "photo_reference": "Aap_uECCOLowEnJ2yBUzF0nwRjV5jBx2_JWsofVosuLVvlr-ClIMHNR5-QGIe4phK-3_Bj_laHD_XH_LvlmGDzm33KvxuO1XzaZocxTLOVUdSGI3_otXvpx_FbuzmwiibZiylQEMkekTLKbLdXjK8H3w10nOcoJE-InDVvf5P7Cvyum_kk9k"
                }
            ],
            "place_id": "ChIJ2w1BG638YjkR9EBiNdrEbgk",
            "reference": "ChIJ2w1BG638YjkR9EBiNdrEbgk",
            "types": [
                "locality",
                "political"
            ],
            "vicinity": "Indore"
        },
        {
            "geometry": {
                "location": {
                    "lat": "22.7429365",
                    "lng": "75.8867267"
                }
            },
            "icon": "https://maps.gstatic.com/mapfiles/place_api/icons/v1/png_71/generic_business-71.png",
            "name": "Visual Maker",
            "photos": [
                {
                    "photo_reference": "Aap_uED84yCmvAirxt-dSdPPSE3O_eBSunEiSOM1Uzr0kNNMiJBVvPtBuCuwck2Ek0CDg7S8JP09Iva3Rjhq63O1Tyql_CTeMRF_GWC19QfZUFwwvadcRbfLWo6Wqn4ndCTCh5A6RV212PJcB0HZqe6YV7FphiV_XjkP9pCvk5JLDKNrvOXz"
                }
            ],
            "place_id": "ChIJGwLEIlr9YjkRnr8uTQiQ8KU",
            "reference": "ChIJGwLEIlr9YjkRnr8uTQiQ8KU",
            "types": [
                "university",
                "general_contractor",
                "point_of_interest",
                "establishment"
            ],
            "vicinity": "behind Anop Cinema, K/112, LIG Colony, Indore"
        },
 }

这是两个对象,但可以是多个对象

下面是我的Moya api调用类。

import Moya
import Result
import Alamofire
import UIKit

private func JSONResponseDataFormatter(_ data: Data) -> Data {
    do {
        let dataAsJSON = try JSONSerialization.jsonObject(with: data)
        let prettyData =  try JSONSerialization.data(withJSONObject: dataAsJSON, options: .prettyPrinted)
        return prettyData
    } catch {
        return data // fallback to original data if it can't be serialized.
    }
}

private extension String {
    var urlEscaped: String {
        return self.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)!
    }
}

let MyAPIProvider = MoyaProvider<EBabuAPI>( plugins: [VerbosePlugin(verbose: true)])

enum MyAPI {
    case topPlaceVibeAvg(geometry : [Any], icon:[String], name:[String], photos:[Any], placeIds:[String], reference:[String], types:[Any], vicinity:[Any])
}

extension EBabuAPI: TargetType {
    
    var headers: [String : String]? {
        switch self {
        default:
            return ["Authorization": SharedPreference.authToken()]
        }
    }
    
    var baseURL : URL {
        return URL(string: Constants.API.baseURL)! //["Authorization": "Bearer \(Helpers.userToken())"]
    }
    
    var path: String {
        switch self {
        case .topPlaceVibeAvg:
            return "places/topPlaceVibeAvg"
        }
    }
    
    public var method: Moya.Method {
        switch self {
        case .topPlaceVibeAvg :
            return .post
        }
    }
    
    var sampleData: Data {
        return "".data(using: .utf8)!
    }
    
    var task: Task {
        switch self {
        case .topPlaceVibeAvg(let geometry,let icon, let name, let photos, let placeIds, let reference, let types, let vicinity):
            return .requestParameters(parameters: ["geometry":geometry, "icon":icon, "name":name, "photos":photos, "place_id":placeIds, "reference":reference, "types":types, "vicinity":vicinity], encoding: JSONEncoding.default)
        }
    }
    
    func dicToStrig(data : AnyObject) -> String {
        do {
            let jsonData = try JSONSerialization.data(withJSONObject: data, options: [])
            let jsonString = String(data: jsonData, encoding: String.Encoding.ascii)!
            return  jsonString
            
        } catch {
            //handle error
            print("error",error)
        }
        return ""
    }
    
    var parameterEncoding: ParameterEncoding {
        switch self {
            
        default:
            return JSONEncoding.default
        }
    }
}

struct JsonArrayEncoding: Moya.ParameterEncoding {
    
    public static var `default`: JsonArrayEncoding { return JsonArrayEncoding() }
    
    public func encode(_ urlRequest: URLRequestConvertible, with parameters: Parameters?) throws -> URLRequest {
        var req = try urlRequest.asURLRequest()
        let json = try JSONSerialization.data(withJSONObject: parameters!["jsonArray"]!, options: JSONSerialization.WritingOptions.prettyPrinted)
        req.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
        req.httpBody = json
        return req
    }
}

正如每个人都可以看到上面的代码,我正在尝试调用 topPlaceVibeAvg api,并成功调用他们的键和值 api,但它没有提供与邮递员屏幕截图相同的正确响应。

这里是 api 响应: { 数据 = ( ); message = "平均获取成功!"; 状态码 = 200; 成功 = 1; }

我在下面使用ViewModel(placesViewModel) 来调用api。

    var icon = [String]()
    var name = [String]()
    var name = [Any]()
    var placeIds = [String]()
    var reference = [String]()
    var testTypes = [Any]()
    var vicinity = [Any]()
    
    var geometry = [Any]()
    var photos = [Any]()

func topPlaceVibeAvg(_ completion: @escaping ((JSONDictionary) -> ())) {
        if !isPullToRefresh {  Loader.show("Looking around....") }
        
        APIController.makeRequest(.topPlaceVibeAvg(geometry: geometry, icon: icon, name: name, photos: photos, placeIds: placeIds, reference: reference, types: types, vicinity: vicinity)) { (data, error) in
            Loader.hide()
            if error == nil {
                completion(data!)
            } else {
                ToastAndAlertManager.showToastWithTitle((error?.desc)!, colorCode: ToastColor.error.rawValue)
            }
        }
    }

这是我的ViewController api 类

    placesViewModel.geometry = self.nearByPlacesArray.map{$0.geometry}
    placesViewModel.icon = self.nearByPlacesArray.map{$0.icon}
    placesViewModel.name = self.nearByPlacesArray.map{$0.name}
    placesViewModel.photos = self.nearByPlacesArray.map{$0.photos}
    placesViewModel.placeIds = self.nearByPlacesArray.map{$0.placeId}
    placesViewModel.reference = self.nearByPlacesArray.map{$0.reference}
    placesViewModel.testTypes = self.nearByPlacesArray.map{$0.types}
    placesViewModel.vicinity = self.nearByPlacesArray.map{$0.vicinity}
      
    placesViewModel.topPlaceVibeAvg { (data) in
         print(data)
    }
Note : **nearByPlacesArray** is main array & i'm to sorting my required array object from here

我真的尝试过解决问题,我已经搜索过这件事但没有得到任何答案。

有人知道这个吗?

【问题讨论】:

    标签: ios json swift alamofire moya


    【解决方案1】:

    要在请求正文中发送复杂的参数,您可以使用 Moya 函数:

    requestCompositeData(bodyData: Data, urlParameters: [String: Any])
    

    Moya 对此功能有这样的评论:

    带有数据的请求体集,结合url参数

    所以这个函数允许我们在请求正文中发送任何内容。

    例如这样的事情是一个很好的方法:

    import Moya
    import SwiftyJSON
    
    // Data task in MoyaProvider
    
    var task: Task {
            switch self {
            case .categoriesAndSubCategories:
                
                let graphQLJson = JSON([
                    [
                        "query": "query categories { categories { id, title, description, slug, adsStats, subcategories { id, title, slug } } }"
                    ]
                ])
                
                return .requestCompositeData(bodyData: try! graphQLJson.rawData(), urlParameters: [:])
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-12-02
      • 2020-05-11
      • 1970-01-01
      • 1970-01-01
      • 2018-11-27
      • 2015-03-20
      • 1970-01-01
      • 2017-11-30
      相关资源
      最近更新 更多