วิธีส่งคำขอ POST ด้วย BODY อย่างรวดเร็ว


101

ฉันกำลังพยายามส่งคำขอโพสต์พร้อมเนื้อหาอย่างรวดเร็วโดยใช้ Alamofire

ร่างกาย json ของฉันดูเหมือน:

{
    "IdQuiz" : 102,
    "IdUser" : "iosclient",
    "User" : "iosclient",
    "List":[
        {
        "IdQuestion" : 5,
        "IdProposition": 2,
        "Time" : 32
        },
        {
        "IdQuestion" : 4,
        "IdProposition": 3,
        "Time" : 9
        }
    ]
}

ฉันกำลังพยายามสร้างlet listด้วย NSDictionnary ซึ่งมีลักษณะดังนี้:

[[Time: 30, IdQuestion: 6510, idProposition: 10], [Time: 30, IdQuestion: 8284, idProposition: 10]]

และคำขอของฉันโดยใช้ Alamofire ดูเหมือนว่า:

Alamofire.request(.POST, "http://myserver.com", parameters: ["IdQuiz":"102","IdUser":"iOSclient","User":"iOSClient","List":list ], encoding: .JSON)
            .response { request, response, data, error in
            let dataString = NSString(data: data!, encoding:NSUTF8StringEncoding)
                println(dataString)
        }

คำขอมีข้อผิดพลาดและฉันเชื่อว่าปัญหาเกิดจากรายการพจนานุกรมทำให้หากฉันส่งคำขอโดยไม่มีรายการมันจะทำงานได้ดีดังนั้นมีความคิดอย่างไร


ฉันได้ลองใช้วิธีแก้ปัญหาที่แนะนำแล้ว แต่ฉันประสบปัญหาเดียวกัน:

 let json = ["List":list,"IdQuiz":"102","IdUser":"iOSclient","UserInformation":"iOSClient"]
        let data = NSJSONSerialization.dataWithJSONObject(json, options: NSJSONWritingOptions.PrettyPrinted,error:nil)
        let jsons = NSString(data: data!, encoding: NSUTF8StringEncoding)



    Alamofire.request(.POST, "http://myserver.com", parameters: [:], encoding: .Custom({
        (convertible, params) in
        var mutableRequest = convertible.URLRequest.copy() as! NSMutableURLRequest
        mutableRequest.HTTPBody = jsons!.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
        return (mutableRequest, nil)
    }))
        .response { request, response, data, error in
        let dataString = NSString(data: data!, encoding:NSUTF8StringEncoding)
           println(dataString)
    }


1
ขอบคุณสำหรับความคิดเห็นของคุณ แต่โพสต์ที่คุณให้มาไม่ได้ช่วยอะไรและฉันไม่ได้พยายามส่งต่อสตริงเป็นร่างกายดังนั้นโปรดอ่านโพสต์อย่างละเอียด
Stranger B.

@ ยัสเซอร์บ. แปลง JSON ของคุณเป็น NSString (มีวิธีการนั้น) จากนั้นใช้ลิงก์ของ @Bhavin?
Larme

@Larme มันจะมีประโยชน์มากถ้าคุณยกตัวอย่าง
Stranger B.

@Larme ฉันได้พยายามแก้ปัญหาปัญหา แต่ผมมีปัญหาเดียวกันคำขอไม่ทำงานจนกว่าฉันจะลบรายชื่อออกจากร่างกายลูกชาย
คนแปลกหน้าบี

คำตอบ:


100

คุณใกล้แล้ว การจัดรูปแบบพจนานุกรมพารามิเตอร์ดูไม่ถูกต้อง คุณควรลองทำสิ่งต่อไปนี้:

let parameters: [String: AnyObject] = [
    "IdQuiz" : 102,
    "IdUser" : "iosclient",
    "User" : "iosclient",
    "List": [
        [
            "IdQuestion" : 5,
            "IdProposition": 2,
            "Time" : 32
        ],
        [
            "IdQuestion" : 4,
            "IdProposition": 3,
            "Time" : 9
        ]
    ]
]

Alamofire.request(.POST, "http://myserver.com", parameters: parameters, encoding: .JSON)
    .responseJSON { request, response, JSON, error in
        print(response)
        print(JSON)
        print(error)
    }

หวังว่าจะแก้ปัญหาของคุณได้ หากไม่เป็นเช่นนั้นโปรดตอบกลับและฉันจะปรับคำตอบให้เหมาะสม


ฉันจะตั้งค่าคุณสมบัติบางส่วนของ JSON ของฉันไป null วิธีตั้งแต่ฉันไม่สามารถกำหนดnilเพื่อAnyObject?
Amp Tanawat

3
@JaseemAbbas ตรวจสอบรุ่น Alamofire ของคุณหากคุณใช้ v4.0 + ดูคำตอบของฉันด้านล่าง
Gianni Carlo

วิธีการส่งพารามิเตอร์ประเภทนี้ในกรณีที่เข้ารหัสคือ. urlEncoding
Pramod Shukla

1
ไม่สามารถแปลงค่าของประเภท 'Int' เป็นค่าพจนานุกรมที่คาดไว้ประเภท 'AnyObject'
myatmins

จะทำอย่างไรถ้าสมมติว่าค่าของพารามิเตอร์ "รายการ" มีองค์ประกอบรายการเช่น 1,000 รายการ
Nishad Arora

177

หากคุณใช้ Alamofire v4.0 + คำตอบที่ยอมรับจะมีลักษณะดังนี้:

let parameters: [String: Any] = [
    "IdQuiz" : 102,
    "IdUser" : "iosclient",
    "User" : "iosclient",
    "List": [
        [
            "IdQuestion" : 5,
            "IdProposition": 2,
            "Time" : 32
        ],
        [
            "IdQuestion" : 4,
            "IdProposition": 3,
            "Time" : 9
        ]
    ]
]

Alamofire.request("http://myserver.com", method: .post, parameters: parameters, encoding: JSONEncoding.default)
    .responseJSON { response in
        print(response)
    }

6
เยี่ยมมาก! กรุณาเปลี่ยนคำตอบที่ยอมรับนี้! :) หรือรวมกับโซลูชันปัจจุบันสำหรับโซลูชัน Alamofire 3 และ 4
Tom van Zummeren

1
เห็นด้วย - เป็นการระบุอย่างชัดเจนว่าJSONEncodingจะทำให้เข้าใจผิดประเภทที่ทำเพื่อฉัน
Thomas Verbeek

@Gianni Carlo ฉันใช้เหมือนกับคำตอบของคุณ แต่ในการตอบสนองความสำเร็จของฉันฉันได้รับข้อผิดพลาด
ราม

@Ramakrishna ที่อาจเกี่ยวข้องกับ API ที่คุณกำลังใช้อยู่ เพื่อแยกวิเคราะห์การตอบสนองฉันมักจะใช้ไลบรารี SwiftyJSON โปรดแจ้งให้เราทราบว่าคุณได้รับข้อผิดพลาดประเภทใด
Gianni Carlo

ขอบคุณสำหรับการตอบกลับของคุณ. ฉันมีทางออกแล้ว
ราม

37

ฉันไม่ชอบใด ๆ ของคำตอบอื่น ๆ เพื่อให้ห่างไกล (ยกเว้นอาจจะเป็นที่หนึ่งโดย SwiftDeveloper) เพราะพวกเขาทั้งสองต้องให้คุณ deserialize JSON ของคุณเพียงเพื่อให้มีการต่อเนื่องอีกครั้งหรือดูแลเกี่ยวกับโครงสร้างของ JSON ตัวเอง

คำตอบที่ถูกต้องถูกโพสต์โดย afrodev ในคำถามอื่น คุณควรไปโหวตให้คะแนน

ด้านล่างนี้เป็นเพียงการดัดแปลงของฉันโดยมีการเปลี่ยนแปลงเล็กน้อย (โดยเฉพาะชุดอักขระ UTF-8 ที่ชัดเจน)

let urlString = "https://example.org/some/api"
let json = "{\"What\":\"Ever\"}"

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

ฉันยอมรับว่าคำตอบของ @ SwiftDeveloper ดีกว่าและ (ตามความเห็นของฉัน) สมบูรณ์กว่าคำตอบที่ 'ถูกต้อง' ที่คุณพูดถึง แต่ฉันขอเถียงสองประเด็น หนึ่งคือ 'คำตอบที่ถูกต้อง' ที่คุณพูดถึงมีข้อบกพร่องที่toJSONStringไม่ใช่วิธีดั้งเดิมดังนั้นจึงเป็นกล่องดำที่คุณต้องนำไปใช้ สองคำตอบที่คุณให้คือ var jsonซึ่งเริ่มต้นด้วยสตริง json ในความเป็นจริงไม่มีใครมีพารามิเตอร์ในลักษณะนั้นเว้นแต่คุณจะแปลงและจัดเก็บไว้ในเครื่อง
Gianni Carlo

@GianniCarlo 1) ไม่มีtoJSONStringในคำตอบของฉัน 2) "ในความเป็นจริงไม่มีใครมีพารามิเตอร์แบบนั้น" - นั่นเป็นการตั้งสมมติฐานมากมาย JSON อาจมาจากส่วนต่างๆของแอปโดยไม่เกี่ยวข้องกับการร้องขอเลยและรหัสเครือข่ายที่ไม่รู้อะไรเลย
ชายฝั่งทะเลทิเบต

ขอบคุณที่ทำให้ชีวิตของฉันง่ายขึ้น !!! 1 ฉันใช้ Alamofire กับ Flask Backend จากบุรุษไปรษณีย์ทุกอย่างทำงานได้ดี แต่จาก Alamofire ไม่ได้ผล เนื้อหา HTTP และพารามิเตอร์ URL และวิธีการตั้งค่า ขอบคุณอีกครั้ง.
Vineel

8

Xcode 8.X, Swift 3.X

ใช้งานง่าย

    let params:NSMutableDictionary? = [
    "IdQuiz" : 102,
    "IdUser" : "iosclient",
    "User" : "iosclient",
    "List": [
        [
            "IdQuestion" : 5,
            "IdProposition": 2,
            "Time" : 32
        ],
        [
            "IdQuestion" : 4,
            "IdProposition": 3,
            "Time" : 9
        ]
    ]
];
            let ulr =  NSURL(string:"http://myserver.com" 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)

            }

8

คำตอบที่ยอมรับใน Xcode 11 - Swift 5 - Alamofire 5.0

func postRequest() {
    let parameters: [String: Any] = [
        "IdQuiz" : 102,
        "IdUser" : "iosclient",
        "User" : "iosclient",
        "List": [
            [
                "IdQuestion" : 5,
                "IdProposition": 2,
                "Time" : 32
            ],
            [
                "IdQuestion" : 4,
                "IdProposition": 3,
                "Time" : 9
            ]
        ]
    ]
    AF.request("http://myserver.com", method:.post, parameters: parameters,encoding: JSONEncoding.default) .responseJSON { (response) in
        print(response)
    }
}

สิ่งสำคัญ! ใช้การเข้ารหัส: JSONEncoding.default ฉันกระแทกหัวมาหลายชั่วโมงแล้ว ... ค่าเริ่มต้นคือการเข้ารหัสสำหรับพารามิเตอร์ GET
Reimond Hill

8

หากคุณใช้swift4และAlamofire v4.0รหัสที่ยอมรับจะมีลักษณะดังนี้:

            let parameters: Parameters = [ "username" : email.text!, "password" : password.text! ]
            let urlString = "https://api.harridev.com/api/v1/login"
            let url = URL.init(string: urlString)
            Alamofire.request(url!, method: .put, parameters: parameters, encoding: JSONEncoding.default, headers: nil).responseJSON { response in
                 switch response.result
                {
                case .success(let json):
                    let jsonData = json as! Any
                    print(jsonData)
                case .failure(let error):
                    self.errorFailer(error: error)
                }
            }

4

ฉันได้แก้ไขคำตอบของSwiftDeveloperเล็กน้อยเพราะมันไม่ได้ผลสำหรับฉัน ฉันเพิ่มการตรวจสอบความถูกต้องของ Alamofire ด้วย

let body: NSMutableDictionary? = [
    "name": "\(nameLabel.text!)",
    "phone": "\(phoneLabel.text!))"]

let url = NSURL(string: "http://server.com" as String)
var request = URLRequest(url: url! as URL)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let data = try! JSONSerialization.data(withJSONObject: body!, 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)
let alamoRequest = Alamofire.request(request as URLRequestConvertible)
alamoRequest.validate(statusCode: 200..<300)
alamoRequest.responseString { response in

    switch response.result {
        case .success:
            ...
        case .failure(let error):
            ...
    }
}

1
ยังคงใช้งานได้ใน Alamofire 4.9.1 และ Swift 5.1 ชื่นชมมาก
Abe

2

มีการเปลี่ยนแปลงเล็กน้อยที่ฉันต้องการแจ้งให้ทราบ คุณสามารถเข้าถึงคำขอ JSON ข้อผิดพลาดจากอ็อบเจ็กต์การตอบสนองต่อจากนี้

        let urlstring = "Add URL String here"
        let parameters: [String: AnyObject] = [
            "IdQuiz" : 102,
            "IdUser" : "iosclient",
            "User" : "iosclient",
            "List": [
                [
                    "IdQuestion" : 5,
                    "IdProposition": 2,
                    "Time" : 32
                ],
                [
                    "IdQuestion" : 4,
                    "IdProposition": 3,
                    "Time" : 9
                ]
            ]
        ]

        Alamofire.request(.POST, urlstring, parameters: parameters, encoding: .JSON).responseJSON { response in
            print(response.request)  // original URL request
            print(response.response) // URL response
            print(response.data)     // server data
            print(response.result)   // result of response serialization

            if let JSON = response.result.value {
                print("JSON: \(JSON)")
            }
            response.result.error
        }

2

Alamofire ดึงข้อมูลด้วย POST พารามิเตอร์และส่วนหัว

func feedbackApi(){
    DispatchQueue.main.async {
        let headers = [
            "Content-Type": "application/x-www-form-urlencoded",
            "Authorization": "------"
        ]
        let url = URL(string: "---------")
        var parameters = [String:AnyObject]()
        parameters =  [
            "device_id":"-----" as AnyObject,
            "user_id":"----" as AnyObject,
            "cinema_id":"-----" as AnyObject,
            "session_id":"-----" as AnyObject,
        ]
       Alamofire.request(url!, method: .post, parameters: parameters,headers:headers).responseJSON { response in
                switch response.result{
                case.success(let data):
                    self.myResponse = JSON(data)
                    print(self.myResponse as Any)
                    let slide = self.myResponse!["sliders"]
                    print(slide)
                    print(slide.count)
                    for i in 0..<slide.count{
                        let single = Sliders(sliderJson: slide[i])
                        self.slidersArray.append(single)
                    }
                    DispatchQueue.main.async {
                        self.getSliderCollection.reloadData()
                    }
                case .failure(let error):
                    print("dddd",error)
                }

        }
    }

}

1

นี่คือวิธีที่ฉันสร้างคำขอ Http POST ด้วยความรวดเร็วที่ต้องการพารามิเตอร์ด้วยการเข้ารหัส Json และส่วนหัว

สร้างไคลเอ็นต์ API BKCAPIClient เป็นอินสแตนซ์ที่ใช้ร่วมกันซึ่งจะรวมคำขอทุกประเภทเช่น POST, GET, PUT, DELETE เป็นต้น

func postRequest(url:String, params:Parameters?, headers:HTTPHeaders?, completion:@escaping (_ responseData:Result<Any>?, _ error:Error?)->Void){
    Alamofire.request(url, method: .post, parameters: params, encoding: JSONEncoding.default, headers: headers).responseJSON {
        response in
        guard response.result.isSuccess,
            (response.result.value != nil) else {
                debugPrint("Error while fetching data: \(String(describing: response.result.error))")
                completion(nil,response.result.error)
                return
        }
        completion(response.result,nil)
    }
}

สร้างคลาสการดำเนินการที่มีข้อมูลทั้งหมดที่จำเป็นสำหรับการร้องขอเฉพาะและยังมีตรรกะการแยกวิเคราะห์ภายในบล็อกการเสร็จสิ้น

func requestAccountOperation(completion: @escaping ( (_ result:Any?, _ error:Error?) -> Void)){
    BKCApiClient.shared.postRequest(url: BKCConstants().bkcUrl, params: self.parametrs(), headers: self.headers()) { (result, error) in
        if(error != nil){
            //Parse and save to DB/Singletons.
        }
        completion(result, error)
    }
}
func parametrs()->Parameters{
    return ["userid”:”xnmtyrdx”,”bcode":"HDF"] as Parameters
}
func headers()->HTTPHeaders{
    return ["Authorization": "Basic bXl1c2VyOm15cGFzcw",
            "Content-Type": "application/json"] as HTTPHeaders
}

เรียก API ใน View Controller ที่เราต้องการข้อมูลนี้

func callToAPIOperation(){
let accOperation: AccountRequestOperation = AccountRequestOperation()
accOperation.requestAccountOperation{(result, error) in

}}

1
func get_Contact_list()
{
    ApiUtillity.sharedInstance.showSVProgressHUD(text: "Loading..")
    let cont_nunber = contact_array as NSArray
    print(cont_nunber)

    let token = UserDefaults.standard.string(forKey: "vAuthToken")!
    let apiToken = "Bearer \(token)"


    let headers = [
        "Vauthtoken": apiToken,
        "content-type": "application/json"
    ]

    let myArray: [Any] = cont_nunber as! [Any]
    let jsonData: Data? = try? JSONSerialization.data(withJSONObject: myArray, options: .prettyPrinted)
    //        var jsonString: String = nil
    var jsonString = String()
    if let aData = jsonData {
        jsonString = String(data: aData, encoding: .utf8)!
    }

    let url1 = "URL"
    var request = URLRequest(url: URL(string: url1)!)
    request.httpMethod = "POST"
    request.allHTTPHeaderFields = headers
    request.httpBody = jsonData as! Data

    //        let session = URLSession.shared

    let task = URLSession.shared.dataTask(with: request) { data, response, error in
        guard let data = data, error == nil else {
            print("error=\(String(describing: error))")
            ApiUtillity.sharedInstance.dismissSVProgressHUD()
            return
        }

        print("response = \(String(describing: response))")


        let responseString = String(data: data, encoding: .utf8)
        print("responseString = \(String(describing: responseString))")

        let json =  self.convertStringToDictionary(text: responseString!)! as NSDictionary
        print(json)

        let status = json.value(forKey: "status") as! Int

        if status == 200
        {

            let array = (json.value(forKey: "data") as! NSArray).mutableCopy() as! NSMutableArray


        }
        else if status == 401
        {
            ApiUtillity.sharedInstance.dismissSVProgressHUD()

        }
        else
        {
            ApiUtillity.sharedInstance.dismissSVProgressHUD()
        }


    }
    task.resume()
}

func convertStringToDictionary(text: String) -> [String:AnyObject]? {
    if let data = text.data(using: String.Encoding.utf8) {
        do {
            let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String:AnyObject]
            return json
        } catch {
            print("Something went wrong")
        }
    }
    return nil
}

1

หากใครสงสัยว่าจะดำเนินการอย่างไรกับโมเดลและสิ่งต่างๆโปรดดูด้านล่าง

        var itemArr: [Dictionary<String, String>] = []
        for model in models {
              let object = ["param1": model.param1,
                            "param2": model.param2]
              itemArr.append(object as! [String : String])
        }

        let param = ["field1": someValue,
                     "field2": someValue,
                     "field3": itemArr] as [String : Any]

        let url: URLConvertible = "http://------"

        Alamofire.request(url, method: .post, parameters: param, encoding: JSONEncoding.default)
            .responseJSON { response in
                self.isLoading = false
                switch response.result {
                case .success:
                    break
                case .failure:
                    break
                }
        }

1

Alamofire ~ 5.2และSwift 5

คุณสามารถจัดโครงสร้างข้อมูลพารามิเตอร์ของคุณ

ทำงานกับjson api ปลอม

struct Parameter: Encodable {
     let token: String = "xxxxxxxxxx"
     let data: Dictionary = [
        "id": "personNickname",
        "email": "internetEmail",
        "gender": "personGender",
     ]
}

 let parameters = Parameter()

 AF.request("https://app.fakejson.com/q", method: .post, parameters: parameters).responseJSON { response in
            print(response)
        }
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.