Ios 使用Alamofire将Json发布到API?

Ios 使用Alamofire将Json发布到API?,ios,json,swift,alamofire,Ios,Json,Swift,Alamofire,我想发布我在服务类中创建的JSON对象,并传递给networkService 这是我的网络服务,但我得到一个错误 类型“[String:Any]”的值没有成员“data” 行:让jsonData=json.data(使用:.utf8,allowLossyConversion:false) 这个想法是当我通过func参数调用func时传入JSON 这是传入的JSON对象: func loginUser(data: Array<String>, deviceToken: Stri

我想发布我在服务类中创建的JSON对象,并传递给networkService

这是我的网络服务,但我得到一个错误

类型“[String:Any]”的值没有成员“data”

行:
让jsonData=json.data(使用:.utf8,allowLossyConversion:false)

这个想法是当我通过func参数调用func时传入JSON

这是传入的JSON对象:

    func loginUser(data: Array<String>, deviceToken: String) {
    // create JSON
    let json = [ "login-email" : data[0],
                "login-password" : data[1],
                "login-secret" : "8A145C555C43FBA5",
                "devicetoken" : deviceToken
                ]

    networkManager.request(json: json)
}
更新:添加了我的代码以拨打带有完成问题的电话:

 func sendLoginRequest() {
        let userLogin = UserService.init(loginEmail: userEmail, loginPassword: userPassword, loginSecret: loginSecret, deviceToken: deviceToken)
        networkService.logUserIn(request: userLogin) { (<#JSON?#>, <#NSError?#>) in
            <#code#>
        }
    }

我只是展示一下我是如何处理这个问题的

您不必将参数转换为JSON。这是阿拉莫菲尔的密码

/// A dictionary of parameters to apply to a `URLRequest`.
public typealias Parameters = [String: Any]
使用此方法而不是您的:

Alamofire.request(url, method: method, parameters: parameters, encoding: encoding, headers: customHeaders)
试试这个: 您可以在
参数中传递
json
而不是
request.httpBody=jsonData

您的整个代码将是:

func request(json: [String:Any]) {

    Alamofire.request(urlString, method: .post, parameters: json, encoding: JSONEncoding.default).responseJSON {
        (response) in
        print(response)
    }

}
如果您对我的方法感兴趣:

func makePick(request: MakePickRequest, completionHandler: @escaping APICompletionHandler) {
        let parameters = request.converToParameters()
        Alamofire.request(Endpoints.makePick, method: .post, parameters: parameters, encoding: JSONEncoding.default).responseJSON { response in
            self.handleResponse(response: response, completionHandler: completionHandler)
        }
    }
struct MakePickRequest: GeneralRequest {
    let eventId: Int64
    let sportId: String
    let pickType: PickType
    let betType: BetType
    let amount: Int

    func converToParameters() -> [String : String] {
        return ["event_id": String(eventId), "sport_id": sportId,
        "pick_type": pickType.rawValue, "bet_type": betType.rawValue,
        "amount": String(amount)]
    }
}
请求:

func makePick(request: MakePickRequest, completionHandler: @escaping APICompletionHandler) {
        let parameters = request.converToParameters()
        Alamofire.request(Endpoints.makePick, method: .post, parameters: parameters, encoding: JSONEncoding.default).responseJSON { response in
            self.handleResponse(response: response, completionHandler: completionHandler)
        }
    }
struct MakePickRequest: GeneralRequest {
    let eventId: Int64
    let sportId: String
    let pickType: PickType
    let betType: BetType
    let amount: Int

    func converToParameters() -> [String : String] {
        return ["event_id": String(eventId), "sport_id": sportId,
        "pick_type": pickType.rawValue, "bet_type": betType.rawValue,
        "amount": String(amount)]
    }
}
具有端点的结构:

struct Endpoints {
    // Development baseURL
    static let baseURL = "http://myurl/"

    private static let apiVersion = "api/v1/"

    static var fullPath: String {
        return "\(baseURL)\(apiVersion)"
    }

    // MARK: - User endpoints (POST)
    static var login: String {
        return "\(fullPath)users/login"
    }

    static var signUp: String {
        return "\(fullPath)users/signup"
    }

    ...
}
在任何类之外(但必须导入SwiftyJSON):

句柄响应:

private func handleResponse(response: DataResponse<Any>, completionHandler: APICompletionHandler) {
        self.printDebugInfo(response)
        switch response.result {
        case .success(let value):
            self.handleJSON(data: value, handler: completionHandler)
        case .failure(let error):
            print(error)
            completionHandler(nil, error as NSError?)
        }
    }

 private func handleJSON(data: Any, handler: APICompletionHandler) {
        let json = JSON(data)
        let serverResponse = GeneralServerResponse(json)
        if (serverResponse?.status == .ok) {
            handler(serverResponse?.data, nil)
        } else {
            handler(nil, self.parseJsonWithErrors(json))
        }
    }
SessionManager扩展为所有请求添加标题:

extension SessionManager {
    func apiRequest(url: URLConvertible, method: HTTPMethod, parameters: Parameters? = nil, encoding: ParameterEncoding, headers: HTTPHeaders? = nil)  -> DataRequest {
        var customHeaders: HTTPHeaders = ["api-key" : "1wFVerFztxzhgt"]
        if let headers = headers {
            customHeaders += headers
        }
        return request(url, method: method, parameters: parameters, encoding: encoding, headers: customHeaders)
    }
}
在APIManager类中:

private let manager: SessionManager

init() {
     manager = Alamofire.SessionManager.default
}
呼叫示例:

apiClient.makePick(request: request) { data, error in
        if let error = error {
            print(error.localizedDescription)
            return
        }
        if let data = data {
            // data is a JSON object, here you can parse it and create objects
        }
    }
课程示例:

import SwiftyJSON

final class MyClass {
    let id: Int
    let username: String
    let parameter: Double

    init?(_ json: JSON) {
        guard let id = json["id"].int, let username = json["username"].string,
            let parameter = json["parameter"].double else {
                return nil
        }

        self.id = id
        self.username = username
        self.parameter = parameter
    }
}

数据(使用:allowLossyConversion:)
这是一个
字符串
对象方法。不是字典方法(
json
[String:Any]
)。你想要的是使用JSONSerialization。谢谢,我会研究一下,看看我是否能用这种方法解决问题。
让jsonData=尝试JSONSerialization.data(使用JSONObject:json,选项:[])
或者你也可以使用Alamofire来管理参数并将它们放入正文中。我已经用新代码更新了OP,这样行吗?我不想使用Alamofire来处理它们,因为我有太多的服务和调用,所以我只想传递一个预定义的对象。多亏了这一点,当我使用Alamofire.request(url,方法:.post,参数:json,编码:JSONECODING.default)时,我得到了“调用中的额外参数”{出于兴趣,您如何处理大量端点?我看到您在示例中引用了一个结构体?我将在回答中添加如何处理端点,请稍候。另外,请尝试在该函数中添加正确的参数。它肯定会起作用。@jackdm,只需传递第一个参数urlString,它可以是普通字符串。@jackdm,现在可以起作用了。我忘了添加。responseJSON。检查我的更新答案谢谢,你有更多关于API结构的详细信息可以链接吗?我正在构建我的API结构,这看起来是一个很好的方法。当你将response:response传递给“handle response”时,此时的数据类型是什么?
func makePick(request: MakePickRequest, completionHandler: @escaping APICompletionHandler) {
        var parameters = ["auth_token": Preferences.getAuthToken()]
        parameters += request.converToParameters()
        manager.apiRequest(url: Endpoints.makePick, method: .post, parameters: parameters, encoding: JSONEncoding.default).responseJSON { response in
            self.handleResponse(response: response, completionHandler: completionHandler)
        }
    }
extension SessionManager {
    func apiRequest(url: URLConvertible, method: HTTPMethod, parameters: Parameters? = nil, encoding: ParameterEncoding, headers: HTTPHeaders? = nil)  -> DataRequest {
        var customHeaders: HTTPHeaders = ["api-key" : "1wFVerFztxzhgt"]
        if let headers = headers {
            customHeaders += headers
        }
        return request(url, method: method, parameters: parameters, encoding: encoding, headers: customHeaders)
    }
}
private let manager: SessionManager

init() {
     manager = Alamofire.SessionManager.default
}
apiClient.makePick(request: request) { data, error in
        if let error = error {
            print(error.localizedDescription)
            return
        }
        if let data = data {
            // data is a JSON object, here you can parse it and create objects
        }
    }
import SwiftyJSON

final class MyClass {
    let id: Int
    let username: String
    let parameter: Double

    init?(_ json: JSON) {
        guard let id = json["id"].int, let username = json["username"].string,
            let parameter = json["parameter"].double else {
                return nil
        }

        self.id = id
        self.username = username
        self.parameter = parameter
    }
}