Yêu cầu ĐĂNG với một chuỗi đơn giản trong nội dung với Alamofire


84

Làm cách nào để gửi một yêu cầu POST với một chuỗi đơn giản trong phần thân HTTP với Alamofire trong ứng dụng iOS của tôi?

Theo mặc định, Alamofire cần các tham số cho một yêu cầu:

Alamofire.request(.POST, "http://mywebsite.com/post-request", parameters: ["foo": "bar"])

Các tham số này chứa các cặp khóa-giá trị. Nhưng tôi không muốn gửi yêu cầu có chuỗi khóa-giá trị trong phần thân HTTP.

Ý tôi là một cái gì đó như thế này:

Alamofire.request(.POST, "http://mywebsite.com/post-request", body: "myBodyString")

Câu trả lời:


88

Ví dụ của bạn Alamofire.request(.POST, "http://mywebsite.com/post-request", parameters: ["foo": "bar"])đã chứa chuỗi "foo = bar" làm nội dung của nó. Nhưng nếu bạn thực sự muốn chuỗi với định dạng tùy chỉnh. Bạn có thể làm được việc này:

Alamofire.request(.POST, "http://mywebsite.com/post-request", parameters: [:], encoding: .Custom({
            (convertible, params) in
            var mutableRequest = convertible.URLRequest.copy() as NSMutableURLRequest
            mutableRequest.HTTPBody = "myBodyString".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
            return (mutableRequest, nil)
        }))

Lưu ý: parameterskhông nênnil

CẬP NHẬT (Alamofire 4.0, Swift 3.0):

Trong Alamofire 4.0 API đã thay đổi. Vì vậy, để mã hóa tùy chỉnh, chúng tôi cần giá trị / đối tượng phù hợp với ParameterEncodinggiao thức.

extension String: ParameterEncoding {

    public func encode(_ urlRequest: URLRequestConvertible, with parameters: Parameters?) throws -> URLRequest {
        var request = try urlRequest.asURLRequest()
        request.httpBody = data(using: .utf8, allowLossyConversion: false)
        return request
    }

}

Alamofire.request("http://mywebsite.com/post-request", method: .post, parameters: [:], encoding: "myBody", headers: [:])

Điều này hoạt động hoàn hảo, không chỉ đối với đơn giản mà tất cả các loại chuỗi được ánh xạ kiểu JSON.
Sahil Kapoor

đã cứu ngày của tôi :) Cảm ơn (y)
ishhhh

1
@silmaril trong tình huống của tôi, tôi chỉ có thể nhận được yêu cầu thô từ chương trình phụ trợ nếu tôi sử dụng phương pháp PUT, bạn có thể vui lòng giúp tôi không, tại sao yêu cầu POST không thể nhìn thấy bất cứ điều gì
AJ

1
.Custom không còn khả dụng trong Alamofire 4 Swift 3 và tôi không thể tìm thấy giải pháp thay thế, có gợi ý nào không?
Raheel Sadiq

@Silmaril tôi đăng câu hỏi quá, xin vui lòng trả lời rằng vì vậy tôi có thể đóng nó: stackoverflow.com/questions/39573514/...
Raheel Sadiq

64

Bạn có thể làm được việc này:

  1. Tôi đã tạo một đối tượng Alamofire yêu cầu riêng biệt.
  2. Chuyển đổi chuỗi thành dữ liệu
  3. Đưa dữ liệu vào httpBody

    var request = URLRequest(url: URL(string: url)!)
    request.httpMethod = HTTPMethod.post.rawValue
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    
    let pjson = attendences.toJSONString(prettyPrint: false)
    let data = (pjson?.data(using: .utf8))! as Data
    
    request.httpBody = data
    
    Alamofire.request(request).responseJSON { (response) in
    
    
        print(response)
    
    }
    

5
Đây phải là câu trả lời được chấp nhận. Nó đơn giản, thực hiện chính xác những gì cần thiết và không có tiện ích mở rộng hoặc chuyển đổi không cần thiết. Cảm ơn, anh bạn.
Sea Coast of Tibet

2
Tái bút Tôi đã "mượn" câu trả lời của bạn cho một câu hỏi khác - stackoverflow.com/a/42411188/362305
Sea Coast of Tibet

2
là những gì attendences, bạn có thể plz gửi một đoạn đầy đủ hơn
SyraKozZ

@SyraKozZ Không quan trọng sự tham dự là gì, suy nghĩ duy nhất quan trọng là pjson là một chuỗi json. Bạn có thể đặt bất kỳ chuỗi json nào ở đó.
afrodev 20/09/2018

13

Nếu bạn sử dụng Alamofire, chỉ cần loại mã hóa thành "URLEncoding.httpBody" là đủ

Với điều đó, bạn có thể gửi dữ liệu của mình dưới dạng một chuỗi trong httpbody mặc dù bạn đã định nghĩa nó json trong mã của mình.

Nó đã làm việc cho tôi ..

CẬP NHẬT cho

  var url = "http://..."
    let _headers : HTTPHeaders = ["Content-Type":"application/x-www-form-urlencoded"]
    let params : Parameters = ["grant_type":"password","username":"mail","password":"pass"]

    let url =  NSURL(string:"url" as String)

    request(url, method: .post, parameters: params, encoding: URLEncoding.httpBody , headers: _headers).responseJSON(completionHandler: {
        response in response

        let jsonResponse = response.result.value as! NSDictionary

        if jsonResponse["access_token"] != nil
        {
            access_token = String(describing: jsonResponse["accesstoken"]!)

        }

    })

1
tôi sẽ cập nhật câu trả lời của tôi và viết mã một được sử dụng, vì tôi couldnt tìm thấy làm thế nào để viết mã như một bình luận từ đây .. Xin lỗi vì trễ @ Badr Filali.
Cemal BAYRI

Cảm ơn những gì tuyệt vời
Badr Filali

1
Làm việc cho tôi, nhưng cơ thể của tôi cần phải là JSON, vì vậy, tôi đã thay đổi mã hóa: URLEncoding.httpBody thành mã hóa: JSONEncoding.default và mọi thứ hoạt động tốt.
Ângelo Polotto

Vâng @AngeloPolotto cảm ơn bạn đã tiếp tục :) Đây là về loại dịch vụ mã hóa. Có thể được sử dụng tùy thuộc vào api còn lại của bạn dưới dạng mã hóa URLEncoding hoặc JSONEncoding.
Cemal BAYRI

Cảm ơn bạn đã trả lời. Nhưng vấn đề tôi đang gặp phải là khi tôi gửi một biến thay vì double quotes stringsvà nhận được mã lỗi 400. Làm thế nào tôi sẽ giải quyết điều đó?
viper

8

Tôi đã sửa đổi câu trả lời của @ Silmaril để mở rộng Trình quản lý của Alamofire. Giải pháp này sử dụng EVReflection để tuần tự hóa một đối tượng trực tiếp:

//Extend Alamofire so it can do POSTs with a JSON body from passed object
extension Alamofire.Manager {
    public class func request(
        method: Alamofire.Method,
        _ URLString: URLStringConvertible,
          bodyObject: EVObject)
        -> Request
    {
        return Manager.sharedInstance.request(
            method,
            URLString,
            parameters: [:],
            encoding: .Custom({ (convertible, params) in
                let mutableRequest = convertible.URLRequest.copy() as! NSMutableURLRequest
                mutableRequest.HTTPBody = bodyObject.toJsonString().dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
                return (mutableRequest, nil)
            })
        )
    }
}

Sau đó, bạn có thể sử dụng nó như thế này:

Alamofire.Manager.request(.POST, endpointUrlString, bodyObject: myObjectToPost)

5

Nếu bạn muốn đăng chuỗi dưới dạng phần thân thô theo yêu cầu

return Alamofire.request(.POST, "http://mywebsite.com/post-request" , parameters: [:], encoding: .Custom({
            (convertible, params) in
            let mutableRequest = convertible.URLRequest.copy() as! NSMutableURLRequest

            let data = ("myBodyString" as NSString).dataUsingEncoding(NSUTF8StringEncoding)
            mutableRequest.HTTPBody = data
            return (mutableRequest, nil)
        }))

Hi JITHINRAJ tôi đăng một câu hỏi ở đây stackoverflow.com/questions/40385992/... Tôi muốn gửi một cơ thể xml
mike vorisis

5

Tôi đã làm điều đó cho mảng từ chuỗi. Giải pháp này được điều chỉnh cho chuỗi trong nội dung.

Cách "bản địa" từ Alamofire 4:

struct JSONStringArrayEncoding: ParameterEncoding {
    private let myString: String

    init(string: String) {
        self.myString = string
    }

    func encode(_ urlRequest: URLRequestConvertible, with parameters: Parameters?) throws -> URLRequest {
        var urlRequest = urlRequest.urlRequest

        let data = myString.data(using: .utf8)!

        if urlRequest?.value(forHTTPHeaderField: "Content-Type") == nil {
            urlRequest?.setValue("application/json", forHTTPHeaderField: "Content-Type")
        }

        urlRequest?.httpBody = data

        return urlRequest!
    }
}

Và sau đó thực hiện yêu cầu của bạn với:

Alamofire.request("your url string", method: .post, parameters: [:], encoding: JSONStringArrayEncoding.init(string: "My string for body"), headers: [:])

4

Tôi đã sử dụng câu trả lời của @afrodev làm tài liệu tham khảo. Trong trường hợp của tôi, tôi lấy tham số cho hàm của mình dưới dạng chuỗi phải được đăng theo yêu cầu. Vì vậy, đây là mã:

func defineOriginalLanguage(ofText: String) {
    let text =  ofText
    let stringURL = basicURL + "identify?version=2018-05-01"
    let url = URL(string: stringURL)

    var request = URLRequest(url: url!)
    request.httpMethod = HTTPMethod.post.rawValue
    request.setValue("text/plain", forHTTPHeaderField: "Content-Type")
    request.httpBody = text.data(using: .utf8)

    Alamofire.request(request)
        .responseJSON { response in
            print(response)
    }
}

Chính xác những gì bạn không nhận được?
GeoSD

3

Dựa trên câu trả lời của Illya Krit

Chi tiết

  • Phiên bản Xcode 10.2.1 (10E1001)
  • Swift 5
  • Alamofire 4.8.2

Giải pháp

import Alamofire

struct BodyStringEncoding: ParameterEncoding {

    private let body: String

    init(body: String) { self.body = body }

    func encode(_ urlRequest: URLRequestConvertible, with parameters: Parameters?) throws -> URLRequest {
        guard var urlRequest = urlRequest.urlRequest else { throw Errors.emptyURLRequest }
        guard let data = body.data(using: .utf8) else { throw Errors.encodingProblem }
        urlRequest.httpBody = data
        return urlRequest
    }
}

extension BodyStringEncoding {
    enum Errors: Error {
        case emptyURLRequest
        case encodingProblem
    }
}

extension BodyStringEncoding.Errors: LocalizedError {
    var errorDescription: String? {
        switch self {
            case .emptyURLRequest: return "Empty url request"
            case .encodingProblem: return "Encoding problem"
        }
    }
}

Sử dụng

Alamofire.request(url, method: .post, parameters: nil, encoding: BodyStringEncoding(body: text), headers: headers).responseJSON { response in
     print(response)
}

Спасибо вам большое!
Исмаил Хасбулатов

2
func paramsFromJSON(json: String) -> [String : AnyObject]?
{
    let objectData: NSData = (json.dataUsingEncoding(NSUTF8StringEncoding))!
    var jsonDict: [ String : AnyObject]!
    do {
        jsonDict = try NSJSONSerialization.JSONObjectWithData(objectData, options: .MutableContainers) as! [ String : AnyObject]
        return jsonDict
    } catch {
        print("JSON serialization failed:  \(error)")
        return nil
    }
}

let json = Mapper().toJSONString(loginJSON, prettyPrint: false)

Alamofire.request(.POST, url + "/login", parameters: paramsFromJSON(json!), encoding: .JSON)

Mapper là gì?
Ahmadreza

2

Trường hợp của tôi, đăng alamofire với content-type: "Content-Type": "application / x-www-form-urlencoded", tôi đã phải thay đổi mã hóa của yêu cầu đăng alampfire

từ: JSONENCODING.DEFAULT đến: URLEncoding.httpBody

đây:

let url = ServicesURls.register_token()
    let body = [
        "UserName": "Minus28",
        "grant_type": "password",
        "Password": "1a29fcd1-2adb-4eaa-9abf-b86607f87085",
         "DeviceNumber": "e9c156d2ab5421e5",
          "AppNotificationKey": "test-test-test",
        "RegistrationEmail": email,
        "RegistrationPassword": password,
        "RegistrationType": 2
        ] as [String : Any]


    Alamofire.request(url, method: .post, parameters: body, encoding: URLEncoding.httpBody , headers: setUpHeaders()).log().responseJSON { (response) in

0
let parameters = ["foo": "bar"]
              
    // All three of these calls are equivalent
    AF.request("https://httpbin.org/post", method: .post, parameters: parameters)
    AF.request("https://httpbin.org/post", method: .post, parameters: parameters, encoder: URLEncodedFormParameterEncoder.default)
    AF.request("https://httpbin.org/post", method: .post, parameters: parameters, encoder: URLEncodedFormParameterEncoder(destination: .httpBody))
    
    

-3

Xcode 8.X, Swift 3.X

Sử dụng dễ dàng;

 let params:NSMutableDictionary? = ["foo": "bar"];
            let ulr =  NSURL(string:"http://mywebsite.com/post-request" as String)
            let request = NSMutableURLRequest(url: ulr! as URL)
            request.httpMethod = "POST"
            request.setValue("application/json", forHTTPHeaderField: "Content-Type")
            let data = try! JSONSerialization.data(withJSONObject: params!, options: JSONSerialization.WritingOptions.prettyPrinted)

            let json = NSString(data: data, encoding: String.Encoding.utf8.rawValue)
            if let json = json {
                print(json)
            }
            request.httpBody = json!.data(using: String.Encoding.utf8.rawValue);


            Alamofire.request(request as! URLRequestConvertible)
                .responseJSON { response in
                    // do whatever you want here
                   print(response.request)  
                   print(response.response) 
                   print(response.data) 
                   print(response.result)

            }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.