POST विधि के साथ स्विफ्ट में HTTP अनुरोध


188

मैं URL में POST 2 मापदंडों के लिए स्विफ्ट में एक HTTP अनुरोध चलाने की कोशिश कर रहा हूं।

उदाहरण:

संपर्क: www.thisismylink.com/postName.php

पैरामीटर:

id = 13
name = Jack

ऐसा करने का सबसे सरल तरीका क्या है?

मैं भी प्रतिक्रिया नहीं पढ़ना चाहता। मैं सिर्फ एक PHP फ़ाइल के माध्यम से अपने डेटाबेस में परिवर्तन करने के लिए भेजना चाहता हूं।


जवाबों:


409

स्विफ्ट 3 में और बाद में आप कर सकते हैं:

let url = URL(string: "http://www.thisismylink.com/postName.php")!
var request = URLRequest(url: url)
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
let parameters: [String: Any] = [
    "id": 13,
    "name": "Jack & Jill"
]
request.httpBody = parameters.percentEncoded()

let task = URLSession.shared.dataTask(with: request) { data, response, error in
    guard let data = data, 
        let response = response as? HTTPURLResponse, 
        error == nil else {                                              // check for fundamental networking error
        print("error", error ?? "Unknown error")
        return
    }

    guard (200 ... 299) ~= response.statusCode else {                    // check for http errors
        print("statusCode should be 2xx, but is \(response.statusCode)")
        print("response = \(response)")
        return
    }

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

task.resume()

कहाँ पे:

extension Dictionary {
    func percentEncoded() -> Data? {
        return map { key, value in
            let escapedKey = "\(key)".addingPercentEncoding(withAllowedCharacters: .urlQueryValueAllowed) ?? ""
            let escapedValue = "\(value)".addingPercentEncoding(withAllowedCharacters: .urlQueryValueAllowed) ?? ""
            return escapedKey + "=" + escapedValue
        }
        .joined(separator: "&")
        .data(using: .utf8)
    }
}

extension CharacterSet { 
    static let urlQueryValueAllowed: CharacterSet = {
        let generalDelimitersToEncode = ":#[]@" // does not include "?" or "/" due to RFC 3986 - Section 3.4
        let subDelimitersToEncode = "!$&'()*+,;="

        var allowed = CharacterSet.urlQueryAllowed
        allowed.remove(charactersIn: "\(generalDelimitersToEncode)\(subDelimitersToEncode)")
        return allowed
    }()
}

यह दोनों मूलभूत नेटवर्किंग त्रुटियों के साथ-साथ उच्च-स्तरीय HTTP त्रुटियों के लिए जाँच करता है। यह भी ठीक से प्रतिशत क्वेरी के मापदंडों से बच जाता है।

ध्यान दें, मैं एक प्रयोग nameकी Jack & Jillउचित वर्णन करने के लिए, x-www-form-urlencodedका परिणाम name=Jack%20%26%20Jillहै, जो कि "प्रतिशत इनकोडिंग" (यानी खाली स्थान बना दिया है %20और &मूल्य में साथ बदल दिया है %26)।


स्विफ्ट 2 प्रतिपादन के लिए इस उत्तर का पिछला संशोधन देखें ।


7
FYI करें, यदि आप वास्तविक अनुरोध करना चाहते हैं (प्रतिशत से बचकर, जटिल अनुरोधों को बनाते हुए, प्रतिक्रियाओं की पार्सिंग को सरल बनाएं ), AFNetworking के लेखक से, AlamoFire का उपयोग करने पर विचार करें । लेकिन अगर आप केवल एक तुच्छ POSTअनुरोध करना चाहते हैं, तो आप ऊपर उपयोग कर सकते हैं।
रोब

2
धन्यवाद रोब, यह वही था जो मैं देख रहा था! एक साधारण POST से ज्यादा कुछ नहीं। बहुत बढ़िया जवाब!
अंगदान

1
कई अलग-अलग समाधानों की तलाश में कुछ घंटों के बाद, लाइनें 3 और 4 मेरे जीवन को बचा रही हैं क्योंकि मुझे मेरे जीवन के लिए नहीं मिल सका NSJSONSerialization.dataWithJSONObject काम करने के लिए!
जोर्क

1
@complexi - के बीच कनेक्शन $_POSTऔर फ़ाइल नाम खींचने के बजाय , मैं इसे कुछ सरल करने के लिए कम करूंगा: यदि URL सही नहीं मिलता है तो PHP स्क्रिप्ट बिल्कुल भी नहीं चलेगी। लेकिन यह हमेशा ऐसा नहीं होता है कि आपको फ़ाइल नाम शामिल करना चाहिए (जैसे कि सर्वर URL रूटिंग कर सकता है या डिफ़ॉल्ट फ़ाइल नाम हो सकता है)। इस मामले में, ओपी ने हमें एक URL दिया, जिसमें एक फ़ाइल नाम शामिल था, इसलिए मैंने बस उसी URL का उपयोग किया जैसा उसने किया था।
रोब

1
अलमोफायर URLSessionइस संबंध में बेहतर और कोई बुरा नहीं है । सभी नेटवर्किंग एपीआई स्वाभाविक रूप से अतुल्यकालिक हैं, साथ ही साथ उन्हें होना चाहिए। अब, यदि आप अतुल्यकालिक अनुरोधों से निपटने के अन्य सुंदर तरीकों की तलाश कर रहे हैं, तो आप उन्हें URLSessionअतुल्यकालिक, कस्टम Operationउपवर्ग में लपेटकर विचार कर सकते हैं (या तो अनुरोध या Alamofire वाले) । या आप कुछ वादों के पुस्तकालय का उपयोग कर सकते हैं, जैसे प्रोमिसिट।
रोब

69

स्विफ्ट 4 और इसके बाद के संस्करण

@IBAction func submitAction(sender: UIButton) {

    //declare parameter as a dictionary which contains string as key and value combination. considering inputs are valid

    let parameters = ["id": 13, "name": "jack"]

    //create the url with URL
    let url = URL(string: "www.thisismylink.com/postName.php")! //change the url

    //create the session object
    let session = URLSession.shared

    //now create the URLRequest object using the url object
    var request = URLRequest(url: url)
    request.httpMethod = "POST" //set http method as POST

    do {
        request.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted) // pass dictionary to nsdata object and set it as request body
    } catch let error {
        print(error.localizedDescription)
    }

    request.addValue("application/json", forHTTPHeaderField: "Content-Type")
    request.addValue("application/json", forHTTPHeaderField: "Accept")

    //create dataTask using the session object to send data to the server
    let task = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in

        guard error == nil else {
            return
        }

        guard let data = data else {
            return
        }

        do {
            //create json object from data
            if let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any] {
                print(json)
                // handle json...
            }
        } catch let error {
            print(error.localizedDescription)
        }
    })
    task.resume()
}

6
मुझे आपके कोड के साथ निम्नलिखित त्रुटि मिलती है "डेटा को पढ़ा नहीं जा सकता क्योंकि यह सही प्रारूप में नहीं है।"
सेबक्रशर

मुझे लगता है कि आप स्ट्रिंग प्रारूप में प्रतिक्रिया प्राप्त कर रहे हैं क्या आप सत्यापित कर सकते हैं?
सुहित पाटिल

1
मुझे लगता है कि इस समाधान में समस्या यह है कि आप पैरामीटर को जौन सीरीज़िंग के रूप में पास करते हैं और वेब सेवा फॉर्मडाटा मापदंडों के रूप में ले रहे हैं
अमार एंग्री

हाँ, समाधान में parson json हैं, कृपया सर्वर से जाँच करें यदि इसमें फॉर्म डेटा की आवश्यकता है तो सामग्री प्रकार बदलें जैसे request.setValue ("application / x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
Suhit पाटिल

मल्टीपार्ट परमेट्स के लिए लेट बाउंड्रीऑनस्टैंट का उपयोग करें = "--V2ymHFg03ehbqgZCaKO6jy--"; request.addvalue ("मल्टीपार्ट / फॉर्म-डेटा सीमा = (बाउंड्रीऑनस्टैंट)", forHTTPHeaderField: "सामग्री-प्रकार")
सुहिल पाटिल

17

स्विफ्ट 5 में POST अनुरोध को एनकोड करने के लिए एक साफ तरीके की तलाश में किसी के लिए।

आपको मैन्युअल रूप से प्रतिशत एन्कोडिंग को जोड़ने की आवश्यकता नहीं है। URLComponentsGET अनुरोध URL बनाने के लिए उपयोग करें । फिर queryउस URL की प्रॉपर्टी का उपयोग ठीक से प्राप्त होने वाले क्वेरी स्ट्रिंग से प्रतिशत प्राप्त करने के लिए करें।

let url = URL(string: "https://example.com")!
var components = URLComponents(url: url, resolvingAgainstBaseURL: false)!

components.queryItems = [
    URLQueryItem(name: "key1", value: "NeedToEscape=And&"),
    URLQueryItem(name: "key2", value: "vålüé")
]

let query = components.url!.query

queryएक सही तरीके से छोड़े स्ट्रिंग हो जाएगा:

कुंजी 1 = NeedToEscape% 3DAnd% 26 और कुंजी 2 = v% C3% A5l% C3% ई.पू.% C3% A9

अब आप एक अनुरोध बना सकते हैं और HTTPBody के रूप में क्वेरी का उपयोग कर सकते हैं:

var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = Data(query.utf8)

अब आप रिक्वेस्ट भेज सकते हैं।


विभिन्न उदाहरणों के बाद, यह केवल स्विफ्ट 5 के लिए काम करता है
ओलेकेंडर

मैंने GET अनुरोध का उल्लेख किया लेकिन मुझे आश्चर्य है कि POST अनुरोध के बारे में कैसे? HttpBody में पैरामीटर कैसे पास करें या क्या मुझे इसकी आवश्यकता है?
मर्टालप तसडलेन

स्मार्ट समाधान! @Pointum साझा करने के लिए धन्यवाद। मुझे यकीन है कि Martalp को अब उत्तर की आवश्यकता नहीं है, लेकिन किसी और को पढ़ने के लिए, ऊपर एक पोस्ट अनुरोध करता है।
व्लाद

12

मैं अपनी लॉगिंग लाइब्रेरी में जिस विधि का उपयोग करता हूं, वह है: https://github.com/goktugyil/QorumLogs

यह तरीका Google फॉर्म के अंदर HTML फॉर्म भरता है।

    var url = NSURL(string: urlstring)

    var request = NSMutableURLRequest(URL: url!)
    request.HTTPMethod = "POST"
    request.setValue("application/x-www-form-urlencoded; charset=utf-8", forHTTPHeaderField: "Content-Type")
    request.HTTPBody = postData.dataUsingEncoding(NSUTF8StringEncoding)
    var connection = NSURLConnection(request: request, delegate: nil, startImmediately: true)

1
क्या है application/x-www-form-urlencodedआप क्या तय कर रहे हैं?
हनी

अनुरोध शरीर @Honey में डेटा पारित करने के लिए
अचराफ

4
let session = URLSession.shared
        let url = "http://...."
        let request = NSMutableURLRequest(url: NSURL(string: url)! as URL)
        request.httpMethod = "POST"
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        var params :[String: Any]?
        params = ["Some_ID" : "111", "REQUEST" : "SOME_API_NAME"]
        do{
            request.httpBody = try JSONSerialization.data(withJSONObject: params, options: JSONSerialization.WritingOptions())
            let task = session.dataTask(with: request as URLRequest as URLRequest, completionHandler: {(data, response, error) in
                if let response = response {
                    let nsHTTPResponse = response as! HTTPURLResponse
                    let statusCode = nsHTTPResponse.statusCode
                    print ("status code = \(statusCode)")
                }
                if let error = error {
                    print ("\(error)")
                }
                if let data = data {
                    do{
                        let jsonResponse = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions())
                        print ("data = \(jsonResponse)")
                    }catch _ {
                        print ("OOps not good JSON formatted response")
                    }
                }
            })
            task.resume()
        }catch _ {
            print ("Oops something happened buddy")
        }

3
@IBAction func btn_LogIn(sender: AnyObject) {

    let request = NSMutableURLRequest(URL: NSURL(string: "http://demo.hackerkernel.com/ios_api/login.php")!)
    request.HTTPMethod = "POST"
    let postString = "email: test@test.com & password: testtest"
    request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
    let task = NSURLSession.sharedSession().dataTaskWithRequest(request){data, response, error in
        guard error == nil && data != nil else{
            print("error")
            return
        }
        if let httpStatus = response as? NSHTTPURLResponse where httpStatus.statusCode != 200{
            print("statusCode should be 200, but is \(httpStatus.statusCode)")
            print("response = \(response)")
        }
        let responseString = String(data: data!, encoding: NSUTF8StringEncoding)
        print("responseString = \(responseString)")
    }
    task.resume()
}

1
URLRequest
Adam Ware

2

यहाँ सभी उत्तर JSON ऑब्जेक्ट्स का उपयोग करते हैं। इसने हमें $this->input->post() हमारे कोडिग्नेटर नियंत्रकों के तरीकों के साथ समस्याएं दीं । CI_ControllerJSON सीधे नहीं पढ़ सकते हैं। हमने इस विधि का उपयोग JSON के बिना करने के लिए किया

fun postRequest(){
//Create url object
guard let url = URL(string: yourURL) else {return}

//Create the session object
let session = URLSession.shared

//Create the URLRequest object using the url object
var request = URLRequest(url: url)

//Set the request method. Important Do not set any other headers, like Content-Type
request.httpMethod = "POST" //set http method as POST

//Set parameters here. Replace with your own.
let postData = "param1_id=param1_value&param2_id=param2_value".data(using: .utf8)
request.httpBody = postData
}

//Create a task using the session object, to run and return completion handler
let webTask = session.dataTask(with: request, completionHandler: {data, response, error in
guard error == nil else {
print(error?.localizedDescription ?? "Response Error")
return
}
guard let serverData = data else {
print("server data error")
return
}
do {
if let requestJson = try JSONSerialization.jsonObject(with: serverData, options: .mutableContainers) as? [String: Any]{
print("Response: \(requestJson)")
}
} catch let responseError {
print("Serialisation in error in creating response body: \(responseError.localizedDescription)")
let message = String(bytes: serverData, encoding: .ascii)
print(message as Any)
}
})
//Run the task
webTask.resume()

अब आपका CI_Controller प्राप्त करने param1और param2उपयोग करने में सक्षम हो जाएगा $this->input->post('param1')और$this->input->post('param2')

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.