代码之家  ›  专栏  ›  技术社区  ›  jackdm

使用Alamofire将Json发布到API?

  •  2
  • jackdm  · 技术社区  · 7 年前

    类型“[字符串:Any]”的值没有成员“data”

    在线: let jsonData = json.data(using: .utf8, allowLossyConversion: false)!

        func request(json: [String:Any]) {
    
        let url = URL(string: urlString)!
        let jsonData = json.data(using: .utf8, allowLossyConversion: false)!
    
        var request = URLRequest(url: url)
        request.httpMethod = HTTPMethod.post.rawValue
        request.setValue("application/json; charset=UTF-8", forHTTPHeaderField: "Content-Type")
        request.httpBody = jsonData
    
        Alamofire.request(request).responseJSON {
            (response) in
            print(response)
        }
    }
    

    这个想法是,当我通过func参数调用func时,我传入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)
    }
    

    然后我将其转换并发送到API(urlString)

    谢谢

    更新版本:

    func request(json: [String:Any]) {
    
        let url = URL(string: urlString)!
    
        do {
            let jsonData = try JSONSerialization.data(withJSONObject: json, options:[])
            var request = URLRequest(url: url)
            request.httpMethod = HTTPMethod.post.rawValue
            request.setValue("application/json; charset=UTF-8", forHTTPHeaderField: "Content-Type")
            request.httpBody = jsonData
    
            Alamofire.request(request).responseJSON {
                (response) in
                print(response)
            }
        } catch {
            print("Failed to serialise and send JSON")
        }
    }
    

    更新:添加了我的代码以拨打带有完成问题的电话:

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

    编辑:更新的有效载荷快照:

    API Payload Issue

    init?(_ json: JSON) {
        // Map API Key from top level
        guard let apiKey = json["apikey"].string else { return nil }
    
        // Map User at user level
        guard let userDataArray = json["user"].array else {
            fatalError("user data array NOT FOUND")
        }
        print("USER DATA IS \(userDataArray)")
        // assign user 
        for child in userDataArray {
            guard let userID = child["id"].int,
                let userEmail = child["email"].string,
                let lastName = child["lastname"].string,
                let firstName = child["firstname"].string,
                let company = child["company"].string,
                let userImage = child["image"].string,
                let jobTitle = child["jobtitle"].string
                else { return nil
            }
        }
    
        // Assign to model properties
        self.apiKey = apiKey
        self.userEmail = userEmail
        self.lastName = lastName
        self.firstName = firstName
        self.company = company
        self.userImage = userImage
        self.jobTitle = jobTitle
        self.userID = userID
    }
    
    1 回复  |  直到 7 年前
        1
  •  6
  •   Aleksandr Honcharov    7 年前

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

    /// 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)
    

    试试这个: 而不是你的 request.httpBody = jsonData 你可以通过 json 在里面 parameters .

    您的整个代码将是:

    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)]
        }
    }
    

    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):

    typealias APICompletionHandler = (_ data: JSON?, _ error: NSError?) -> Void
    

    句柄响应:

    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))
            }
        }
    

    GeneralServerResponse(取决于您的服务器API):

    import SwiftyJSON
    
    final class GeneralServerResponse {
        let data: JSON
        let status: Status
    
        init?(_ json: JSON) {
            guard let status = json["status"].int else {
                return nil
            }
    
            self.status = Status(status)
            self.data = json["data"]
        }
    
        enum Status {
            case ok
            case error
            case unauthorized
    
            init(_ input: Int) {
                if input >= 200 && input < 400 {
                    self = .ok
                } else if input == 403 {
                    self = .unauthorized
                } else {
                    self = .error
                }
            }
        }
    }
    

    这是外面:

    func +=<K, V> ( left: inout [K : V], right: [K : V]) { for (k, v) in right { left[k] = v } }
    

    请求示例:

    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)
        }
    }
    

    在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
        }
    }