So senden Sie schnell eine POST-Anfrage mit BODY


97

Ich versuche mit Alamofire eine Post-Anfrage mit einer schnellen Leiche zu stellen.

Mein json Körper sieht aus wie:

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

Ich versuche let listmit NSDictionnary Folgendes zu machen :

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

und meine Anfrage mit Alamofire sieht so aus:

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

Die Anfrage hat einen Fehler und ich glaube, das Problem liegt in der Wörterbuchliste. Wenn ich eine Anfrage ohne die Liste mache, funktioniert sie einwandfrei.


Ich habe die vorgeschlagene Lösung ausprobiert, stehe aber vor dem gleichen Problem:

 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
Vielen Dank für Ihren Kommentar, aber der Beitrag, den Sie zur Verfügung gestellt haben, hilft nicht weiter, und ich versuche nicht, eine Zeichenfolge als Body zu übergeben. Können Sie den Beitrag also sorgfältig lesen
Stranger B.

@ YasserB. Konvertieren Sie Ihren JSON in einen NSString (es gibt eine Methode dafür) und verwenden Sie dann den Link von @Bhavin?
Larme

@Larme es wäre wirklich hilfreich, wenn Sie ein Beispiel geben
Stranger B.

@Larme Ich habe die vorgeschlagene Lösung versucht, aber ich habe das gleiche Problem, die Anfrage funktioniert nicht, es sei denn, ich lösche die Liste aus dem Sohn Körper
Fremder B.

Antworten:


97

Du bist nah dran. Die Formatierung des Parameterwörterbuchs sieht nicht korrekt aus. Sie sollten Folgendes versuchen:

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

Hoffentlich hat das Ihr Problem behoben. Wenn nicht, antworten Sie bitte und ich werde meine Antwort entsprechend anpassen.


Wie stelle ich eine Eigenschaft meiner JSON zu null, da ich nicht zuordnen kann nilzu AnyObject?
Amp Tanawat

3
@JaseemAbbas überprüfen Sie Ihre Version von Alamofire, wenn Sie auf v4.0 sind + überprüfen Sie meine Antwort unten
Gianni Carlo

Wie man diese Art von Parameter sendet, falls die Codierung .urlEncoding ist
Pramod Shukla

1
Der Wert vom Typ 'Int' kann nicht in den erwarteten Wörterbuchwert vom Typ 'AnyObject'
konvertiert werden

Wie geht das, wenn der Wert des Parameters "List" 1000 Listenelemente enthält?
Nishad Arora vor

175

Wenn Sie Alamofire v4.0 + verwenden, sieht die akzeptierte Antwort folgendermaßen aus:

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
Toll! Ändern Sie die akzeptierte Antwort bitte auf diese! :) oder kombinieren Sie mit der aktuellen für Alamofire 3 und 4 Lösungen.
Tom van Zummeren

1
Einverstanden - es ist die ausdrückliche Angabe JSONEncoding, den Typ, der es für mich getan hat , zu disambiguieren.
Thomas Verbeek

@ Gianni Carlo Ich habe dasselbe wie Ihre Antwort verwendet, aber in meiner Erfolgsantwort erhalte ich Fehler.
Ramakrishna

@ Ramakrishna, die möglicherweise mit der von Ihnen verwendeten API zusammenhängen. Um die Antwort zu analysieren, die ich normalerweise in der SwiftyJSON-Bibliothek verwende, lassen Sie mich wissen, welche Art von Fehlern Sie erhalten
Gianni Carlo

Danke für deine Antwort. Ich habe die Lösung.
Ramakrishna

34

Ich weiß nicht wie alle anderen Antworten bisher (außer vielleicht die einem von SwiftDeveloper), weil sie entweder Sie benötigen , um Ihre JSON deserialisieren, denn es ist nur wieder serialisiert werden, oder kümmert sich um die Struktur des JSON selbst.

Die richtige Antwort wurde von afrodev in einer anderen Frage veröffentlicht. Du solltest es verbessern.

Unten ist nur meine Anpassung mit einigen geringfügigen Änderungen (hauptsächlich expliziter UTF-8-Zeichensatz).

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

Ich bin damit einverstanden, dass die Antwort von @ SwiftDeveloper besser und (meiner Meinung nach) vollständiger ist als die von Ihnen erwähnte "richtige". Aber ich würde zwei Punkte argumentieren. Erstens, dass die von Ihnen erwähnte „richtige Antwort“ den Fehler aufweist, der toJSONStringkeine native Methode ist. Es handelt sich also im Grunde genommen um eine Black Box, die Sie implementieren müssen. Zweitens liefert die Antwort, die Sie geben, eine Variable, jsondie als JSON-Zeichenfolge beginnt. Realistisch gesehen hat niemand die Parameter auf diese Weise, es sei denn, Sie konvertieren und speichern sie lokal auf diese Weise.
Gianni Carlo

@ GianniCarlo 1) toJSONStringin meiner Antwort steht nein , 2) "realistisch gesehen hat niemand die Parameter so" - das macht viele Annahmen; Der JSON kann aus ganz unterschiedlichen Teilen der App stammen, die überhaupt nichts mit der Anforderung zu tun haben und von denen der Netzwerkcode nichts weiß.
Seeküste von Tibet

Vielen Dank, dass Sie mir das Leben leichter gemacht haben !!! 1 Ich verwende Alamofire mit Flask Backend. Von Postman hat alles gut funktioniert. Aber von Alamofire funktioniert es nicht. HTTP-Body- und URL-Parameter und deren Einstellung. Danke noch einmal.
Vineel

8

Xcode 8.X, Swift 3.X.

Einfache Verwendung;

    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)

            }

7

Wenn Sie verwenden swift4und Alamofire v4.0dann würde der akzeptierte Code folgendermaßen aussehen:

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

5

Akzeptierte Antwort in 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)
    }
}

4

Ich habe die Antwort von SwiftDeveloper leicht bearbeitet , weil sie bei mir nicht funktioniert hat. Ich habe auch die Alamofire-Validierung hinzugefügt.

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
Funktioniert immer noch in Alamofire 4.9.1 und Swift 5.1. Sehr geschätzt
Abe

2

Es gibt einige Änderungen, die ich mitteilen möchte. Sie können von nun an auf Anforderungs-, JSON- und Fehler vom Antwortobjekt zugreifen.

        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 Daten mit POST, Parameter und Headern abrufen

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

Hier ist, wie ich eine HTTP-POST-Anforderung mit Swift erstellt habe, die Parameter mit Json-Codierung und mit Headern benötigt.

API-Client BKCAPIClient als gemeinsam genutzte Instanz erstellt, die alle Arten von Anforderungen wie POST, GET, PUT, DELETE usw. enthält.

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

Erstellt eine Operationsklasse, die alle für eine bestimmte Anforderung erforderlichen Daten sowie eine Analyselogik innerhalb des Abschlussblocks enthält.

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 aufrufen In jedem View Controller, in dem wir diese Daten benötigen

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

Wenn sich jemand fragt, wie er mit Modellen und anderen Dingen vorgehen soll, siehe unten

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

0

Alamofire ~ 5.2 und Swift 5

Sie können Ihre Parameterdaten strukturieren

Arbeite mit gefälschter 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)
        }
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.