programing

POST 메서드를 사용한Swift에서의 HTTP 요구

cafebook 2023. 4. 19. 00:20
반응형

POST 메서드를 사용한Swift에서의 HTTP 요구

Swift에서 HTTP Request를 실행하여 URL에 POST 2 파라미터를 설정하려고 합니다.

예:

링크:www.thisismylink.com/postName.php

파라미터:

id = 13
name = Jack

그것을 하는 가장 간단한 방법은 무엇입니까?

나는 심지어 반응도 읽고 싶지 않아.PHP 파일을 통해 데이터베이스에 변경을 가하기 위해 전송하고 싶습니다.

중요한 것은 다음과 같습니다.

  • 을 설정하다httpMethod로.POST;
  • 필요에 따라서,Content-Typeheader: 서버가 다른 유형의 요구를 받아들일 수 있는 경우에 대비하여 요청 본문의 부호화 방법을 지정합니다.
  • 필요에 따라서,Accept서버가 다른 유형의 응답을 생성할 수 있는 경우에 대비하여 응답 본문의 부호화 방법을 요구합니다.
  • 을 설정하다httpBody특정에 맞게 올바르게 부호화되다Content-Type; 예:application/x-www-form-urlencoded요청, 요청 본문을 백분율로 수정해야 합니다.

예: Swift 3 이상에서는 다음을 수행할 수 있습니다.

let url = URL(string: "https://httpbin.org/post")!
var request = URLRequest(url: url)
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
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 ?? URLError(.badServerResponse))
        return
    }
    
    guard (200 ... 299) ~= response.statusCode else {                    // check for http errors
        print("statusCode should be 2xx, but is \(response.statusCode)")
        print("response = \(response)")
        return
    }
    
    // do whatever you want with the `data`, e.g.:
    
    do {
        let responseObject = try JSONDecoder().decode(ResponseObject<Foo>.self, from: data)
        print(responseObject)
    } catch {
        print(error) // parsing error
        
        if let responseString = String(data: data, encoding: .utf8) {
            print("responseString = \(responseString)")
        } else {
            print("unable to parse response as string")
        }
    }
}

task.resume()

여기서 다음 확장은 Swift를 변환하는 퍼센트 부호화 요구 본문을 촉진합니다.Dictionary에 대해서application/x-www-form-urlencoded포맷했다Data:

extension Dictionary {
    func percentEncoded() -> Data? {
        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
    }()
}

그리고 다음과 같습니다.Decodable모델 오브젝트는 의 해석을 용이하게 합니다.application/json응답, 사용JSONDecoder:

// sample Decodable objects for https://httpbin.org

struct ResponseObject<T: Decodable>: Decodable {
    let form: T    // often the top level key is `data`, but in the case of https://httpbin.org, it echos the submission under the key `form`
}

struct Foo: Decodable {
    let id: String
    let name: String
}

이것에 의해, 기본적인 네트워크 에러와 높은 레벨의 HTTP 에러가 모두 체크됩니다.이 비율도 쿼리의 파라미터를 적절히 회피합니다.

주의: 저는nameJack & Jill적절한 예를 들어x-www-form-urlencoded의 결과name=Jack%20%26%20Jill('퍼센트 부호화'(즉, 공백은 다음과 같이 치환됨)%20및 그&값이 로 대체되다%26).


Swift 2의 표현에 대해서는 이 답변의 이전 개정판을 참조하십시오.

Swift 4 이상

func postRequest() {
  
  // declare the parameter as a dictionary that contains string as key and value combination. considering inputs are valid
  
  let parameters: [String: Any] = ["id": 13, "name": "jack"]
  
  // create the url with URL
  let url = URL(string: "www.thisismylink.com/postName.php")! // change server url accordingly
  
  // 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
  
  // add headers for the request
  request.addValue("application/json", forHTTPHeaderField: "Content-Type") // change as per server requirements
  request.addValue("application/json", forHTTPHeaderField: "Accept")
  
  do {
    // convert parameters to Data and assign dictionary to httpBody of request
    request.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted)
  } catch let error {
    print(error.localizedDescription)
    return
  }
  
  // create dataTask using the session object to send data to the server
  let task = session.dataTask(with: request) { data, response, error in
    
    if let error = error {
      print("Post Request Error: \(error.localizedDescription)")
      return
    }
    
    // ensure there is valid response code returned from this HTTP response
    guard let httpResponse = response as? HTTPURLResponse,
          (200...299).contains(httpResponse.statusCode)
    else {
      print("Invalid Response received from the server")
      return
    }
    
    // ensure there is data returned
    guard let responseData = data else {
      print("nil Data received from the server")
      return
    }
    
    do {
      // create json object from data or use JSONDecoder to convert to Model stuct
      if let jsonResponse = try JSONSerialization.jsonObject(with: responseData, options: .mutableContainers) as? [String: Any] {
        print(jsonResponse)
        // handle json response
      } else {
        print("data maybe corrupted or in wrong format")
        throw URLError(.badServerResponse)
      }
    } catch let error {
      print(error.localizedDescription)
    }
  }
  // perform the task
  task.resume()
}

Swift 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적절한 이스케이프 문자열이 됩니다.

key1=NeedToEscape%3DAnd%26&key2=v%C3%A5l%C3%BC%C3%A9

이제 요청을 만들고 쿼리를 HTTPBody로 사용할 수 있습니다.

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

이제 요청을 보낼 수 있습니다.

로그 라이브러리에서 사용한 방법은 다음과 같습니다.https://github.com/goktugyil/QorumLogs

이 메서드는 Google Forms 내의 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)
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")
        }

이 답변은 모두 JSON 개체를 사용합니다.이 때문에, 델은,$this->input->post()코드 시그니터 컨트롤러의 방법.CI_ControllerJSON을 사용합니다.을 사용하여 WITHIN JSON 없이 JSON을 .

func 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')

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

언급URL : https://stackoverflow.com/questions/26364914/http-request-in-swift-with-post-method

반응형