Swift에서 HTTP 요청을 어떻게합니까?


371

iBooks에서 Apple 의 Programming Language Swift 를 읽었 지만 Swift 에서 HTTP 요청 (cURL과 같은 것)을 만드는 방법을 알 수 없습니다. Obj-C 클래스를 가져와야합니까 아니면 기본 라이브러리 만 가져와야합니까? 아니면 네이티브 스위프트 코드를 기반으로 HTTP 요청을 할 수 없습니까?


2
사용 URLSession (GET, POST, DELETE 방법) : stackoverflow.com/a/48306950/6898523
마 히펄 싱

답변:


550

당신은 사용할 수 있습니다 URL, URLRequest그리고 URLSession또는 NSURLConnection당신이 일반적으로 오브젝티브 C에 할 거라고한다. iOS 7.0 이상에서는 URLSession선호됩니다.

사용 URLSession

URL객체와 URLSessionDataTaskfrom을 초기화하십시오 URLSession. 그런 다음로 작업을 실행하십시오 resume().

let url = URL(string: "http://www.stackoverflow.com")!

let task = URLSession.shared.dataTask(with: url) {(data, response, error) in
    guard let data = data else { return }
    print(String(data: data, encoding: .utf8)!)
}

task.resume()

사용 NSURLConnection

먼저 a URL와 a를 초기화 하십시오 URLRequest.

let url = URL(string: "http://www.stackoverflow.com")!
var request = URLRequest(url: url)
request.httpMethod = "POST" 

그런 다음 다음을 사용하여 요청을 비동기 적으로로드 할 수 있습니다.

NSURLConnection.sendAsynchronousRequest(request, queue: OperationQueue.main) {(response, data, error) in
    guard let data = data else { return }
    print(String(data: data, encoding: .utf8)!)
}

또는 다음을 초기화 할 수 있습니다 NSURLConnection.

let connection = NSURLConnection(request: request, delegate:nil, startImmediately: true)

델리게이트를 다른 것으로 설정 nil하고 델리게이트 메소드를 사용하여 수신 된 응답 및 데이터로 작업하십시오.

자세한 내용 프로토콜 설명서를 확인하십시오.NSURLConnectionDataDelegate

Xcode 놀이터에서 테스트

Xcode 놀이터에서이 코드를 사용 import PlaygroundSupport하려면 놀이터와 다음 호출을 추가하십시오.

PlaygroundPage.current.needsIndefiniteExecution = true

이를 통해 놀이터에서 비동기 코드를 사용할 수 있습니다.


2
XCPlayground가 지원되지 않으므로 놀이터에서 iOS 8 베타 2를 사용하는 데 시간을 낭비하지 마십시오. 해킹을 시도하려는 경우 영리하고 추악한 방법이 있습니다 : stackoverflow.com/a/24058337/700206
whitneyland

7
NSURLSession을 사용하여 POST 데이터를 어떻게 보내나요?
Fernando Santiago

2
이 예는 6.1에서 실패합니다. test.swift : 5 : 57 : 오류 : 선택적 유형 'NSURL?' 래핑되지 않은; ‘!’을 (를) 사용 하시겠습니까? 또는 '?'? 하자 작업 = NSURLSession.sharedSession (). dataTaskWithURL (url) {(data, response, error) in
mcuadros

2
느낌표 수정의 @mcuadros '오류 메시지 추가 ... .dataTaskWithURL (URL!)
숀 맥클로리

3
코드 스 니펫을 수정할 수 있습니까? 다음은 Swift 4print(String(data: data!, encoding: String.Encoding.utf8))
Nate

101

아래 코드 확인 :

1. SynchonousRequest

스위프트 1.2

    let urlPath: String = "YOUR_URL_HERE"
    var url: NSURL = NSURL(string: urlPath)!
    var request1: NSURLRequest = NSURLRequest(URL: url)
    var response: AutoreleasingUnsafeMutablePointer<NSURLResponse?>=nil
    var dataVal: NSData =  NSURLConnection.sendSynchronousRequest(request1, returningResponse: response, error:nil)!
    var err: NSError
    println(response)
    var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(dataVal, options: NSJSONReadingOptions.MutableContainers, error: &err) as? NSDictionary
    println("Synchronous\(jsonResult)")

스위프트 2.0 +

let urlPath: String = "YOUR_URL_HERE"
    let url: NSURL = NSURL(string: urlPath)!
    let request1: NSURLRequest = NSURLRequest(URL: url)
    let response: AutoreleasingUnsafeMutablePointer<NSURLResponse?>=nil


    do{

        let dataVal = try NSURLConnection.sendSynchronousRequest(request1, returningResponse: response)

            print(response)
            do {
                if let jsonResult = try NSJSONSerialization.JSONObjectWithData(dataVal, options: []) as? NSDictionary {
                    print("Synchronous\(jsonResult)")
                }
            } catch let error as NSError {
                print(error.localizedDescription)
            }



    }catch let error as NSError
    {
         print(error.localizedDescription)
    }

2. 비동기 요청

스위프트 1.2

let urlPath: String = "YOUR_URL_HERE"
    var url: NSURL = NSURL(string: urlPath)!
    var request1: NSURLRequest = NSURLRequest(URL: url)
    let queue:NSOperationQueue = NSOperationQueue()
    NSURLConnection.sendAsynchronousRequest(request1, queue: queue, completionHandler:{ (response: NSURLResponse!, data: NSData!, error: NSError!) -> Void in
        var err: NSError
        var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
        println("Asynchronous\(jsonResult)")
       })

스위프트 2.0 +

let urlPath: String = "YOUR_URL_HERE"
    let url: NSURL = NSURL(string: urlPath)!
    let request1: NSURLRequest = NSURLRequest(URL: url)
    let queue:NSOperationQueue = NSOperationQueue()

    NSURLConnection.sendAsynchronousRequest(request1, queue: queue, completionHandler:{ (response: NSURLResponse?, data: NSData?, error: NSError?) -> Void in

        do {
            if let jsonResult = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? NSDictionary {
                print("ASynchronous\(jsonResult)")
            }
        } catch let error as NSError {
            print(error.localizedDescription)
        }


    })

3. 평소와 같이 URL 연결

스위프트 1.2

    var dataVal = NSMutableData()
    let urlPath: String = "YOUR URL HERE"
    var url: NSURL = NSURL(string: urlPath)!
    var request: NSURLRequest = NSURLRequest(URL: url)
    var connection: NSURLConnection = NSURLConnection(request: request, delegate: self, startImmediately: true)!
    connection.start()

그때

 func connection(connection: NSURLConnection!, didReceiveData data: NSData!){
    self.dataVal?.appendData(data)
}


func connectionDidFinishLoading(connection: NSURLConnection!)
{
    var error: NSErrorPointer=nil

    var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(dataVal!, options: NSJSONReadingOptions.MutableContainers, error: error) as NSDictionary

    println(jsonResult)



}

스위프트 2.0 +

   var dataVal = NSMutableData()
    let urlPath: String = "YOUR URL HERE"
    var url: NSURL = NSURL(string: urlPath)!
    var request: NSURLRequest = NSURLRequest(URL: url)
    var connection: NSURLConnection = NSURLConnection(request: request, delegate: self, startImmediately: true)!
    connection.start()

그때

func connection(connection: NSURLConnection!, didReceiveData data: NSData!){
    dataVal.appendData(data)
}


func connectionDidFinishLoading(connection: NSURLConnection!)
{

    do {
        if let jsonResult = try NSJSONSerialization.JSONObjectWithData(dataVal, options: []) as? NSDictionary {
            print(jsonResult)
        }
    } catch let error as NSError {
        print(error.localizedDescription)
    }

}

4. 비동기 POST 요청

스위프트 1.2

    let urlPath: String = "YOUR URL HERE"
    var url: NSURL = NSURL(string: urlPath)!
    var request1: NSMutableURLRequest = NSMutableURLRequest(URL: url)

    request1.HTTPMethod = "POST"
     var stringPost="deviceToken=123456" // Key and Value

    let data = stringPost.dataUsingEncoding(NSUTF8StringEncoding)

    request1.timeoutInterval = 60
    request1.HTTPBody=data
    request1.HTTPShouldHandleCookies=false

    let queue:NSOperationQueue = NSOperationQueue()

     NSURLConnection.sendAsynchronousRequest(request1, queue: queue, completionHandler:{ (response: NSURLResponse!, data: NSData!, error: NSError!) -> Void in


        var err: NSError

        var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
        println("AsSynchronous\(jsonResult)")


        })

스위프트 2.0 +

let urlPath: String = "YOUR URL HERE"
    let url: NSURL = NSURL(string: urlPath)!
    let request1: NSMutableURLRequest = NSMutableURLRequest(URL: url)

    request1.HTTPMethod = "POST"
    let stringPost="deviceToken=123456" // Key and Value

    let data = stringPost.dataUsingEncoding(NSUTF8StringEncoding)

    request1.timeoutInterval = 60
    request1.HTTPBody=data
    request1.HTTPShouldHandleCookies=false

    let queue:NSOperationQueue = NSOperationQueue()

    NSURLConnection.sendAsynchronousRequest(request1, queue: queue, completionHandler:{ (response: NSURLResponse?, data: NSData?, error: NSError?) -> Void in

        do {
            if let jsonResult = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? NSDictionary {
                print("ASynchronous\(jsonResult)")
            }
        } catch let error as NSError {
            print(error.localizedDescription)
        }


    })

5. 비동기식 GET 요청

스위프트 1.2

    let urlPath: String = "YOUR URL HERE"
    var url: NSURL = NSURL(string: urlPath)!
    var request1: NSMutableURLRequest = NSMutableURLRequest(URL: url)

    request1.HTTPMethod = "GET"
    request1.timeoutInterval = 60
    let queue:NSOperationQueue = NSOperationQueue()

     NSURLConnection.sendAsynchronousRequest(request1, queue: queue, completionHandler:{ (response: NSURLResponse!, data: NSData!, error: NSError!) -> Void in


        var err: NSError

        var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
        println("AsSynchronous\(jsonResult)")


        })

스위프트 2.0 +

let urlPath: String = "YOUR URL HERE"
    let url: NSURL = NSURL(string: urlPath)!
    let request1: NSMutableURLRequest = NSMutableURLRequest(URL: url)

    request1.HTTPMethod = "GET"
    let queue:NSOperationQueue = NSOperationQueue()

    NSURLConnection.sendAsynchronousRequest(request1, queue: queue, completionHandler:{ (response: NSURLResponse?, data: NSData?, error: NSError?) -> Void in

        do {
            if let jsonResult = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? NSDictionary {
                print("ASynchronous\(jsonResult)")
            }
        } catch let error as NSError {
            print(error.localizedDescription)
        }


    })

6. 이미지 (파일) 업로드

스위프트 2.0 +

  let mainURL = "YOUR_URL_HERE"

    let url = NSURL(string: mainURL)
    let request = NSMutableURLRequest(URL: url!)
    let boundary = "78876565564454554547676"
    request.addValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")


    request.HTTPMethod = "POST" // POST OR PUT What you want
    let session = NSURLSession(configuration:NSURLSessionConfiguration.defaultSessionConfiguration(), delegate: nil, delegateQueue: nil)

    let imageData = UIImageJPEGRepresentation(UIImage(named: "Test.jpeg")!, 1)





    var body = NSMutableData()

    body.appendData("--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)

    // Append your parameters

    body.appendData("Content-Disposition: form-data; name=\"name\"\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
    body.appendData("PREMKUMAR\r\n".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)!)
    body.appendData("--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)

    body.appendData("Content-Disposition: form-data; name=\"description\"\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
    body.appendData("IOS_DEVELOPER\r\n".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)!)
    body.appendData("--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)


    // Append your Image/File Data

    var imageNameval = "HELLO.jpg"

    body.appendData("--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
    body.appendData("Content-Disposition: form-data; name=\"profile_photo\"; filename=\"\(imageNameval)\"\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
    body.appendData("Content-Type: image/jpeg\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
    body.appendData(imageData!)
    body.appendData("\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)

    body.appendData("--\(boundary)--\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)

    request.HTTPBody = body




    let dataTask = session.dataTaskWithRequest(request) { (data, response, error) -> Void in

        if error != nil {

            //handle error


        }
        else {




            let outputString : NSString = NSString(data:data!, encoding:NSUTF8StringEncoding)!
            print("Response:\(outputString)")


        }
    }
    dataTask.resume()

93

또 다른 옵션 은 Chainable Request / Response 방법을 제공 하는 Alamofire 라이브러리입니다.

https://github.com/Alamofire/Alamofire

요청하다

import Alamofire

Alamofire.request(.GET, "http://httpbin.org/get")

응답 처리

Alamofire.request(.GET, "http://httpbin.org/get", parameters: ["foo": "bar"])
         .response { request, response, data, error in
              print(request)
              print(response)
              print(error)
          }

125
프레임 워크에서 제공하는 기능은 외부 라이브러리를 제안하여 회신하는 것이 올바른 방법이 아니라고 생각합니다.
turkishweb

9
@turkishweb이 맞습니다. Cezar의 답변은보다 완전하며 외부 라이브러리를 사용하지 않습니다. 그 대답이 받아 들여 져야합니다.
FredMaggiowski

11
Cezar의 답변은 구식이며 (Swift 3부터) Alamofire의 인터페이스는 인터페이스 및 컨소 시트 보다 훨씬 우수합니다 URLSession. 또한 수용은 추상적 인 선의 척도 (모두 혼자서는 안됩니다!;)의 척도가 아니라 OP를 가장 많이 도왔던 것입니다. ( "순수한"솔루션에는 SO 문서가 있습니다!) 이것이 정답이라면 완벽합니다. 첫 번째 원칙을 사용하지는 않지만 항상 "올바른"솔루션은 아닙니다. 그렇지 않습니까?
Raphael

9
SO 지침에 따라 특별히 요구되지 않는 한 타사 라이브러리를 제공하지 마십시오
Alec O

1
Alamofire 최고
tania_S

36

Swift 4 이상 : URLSession API를 사용한 데이터 요청

   //create the url with NSURL
   let url = URL(string: "https://jsonplaceholder.typicode.com/todos/1")! //change the url

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

   //now create the URLRequest object using the url object
   let request = URLRequest(url: url)

   //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)
         }
      } catch let error {
        print(error.localizedDescription)
      }
   })

   task.resume()

스위프트 4 이상, 디코딩 가능 및 결과 열거 형

//APPError enum which shows all possible errors
enum APPError: Error {
    case networkError(Error)
    case dataNotFound
    case jsonParsingError(Error)
    case invalidStatusCode(Int)
}

//Result enum to show success or failure
enum Result<T> {
    case success(T)
    case failure(APPError)
}

//dataRequest which sends request to given URL and convert to Decodable Object
func dataRequest<T: Decodable>(with url: String, objectType: T.Type, completion: @escaping (Result<T>) -> Void) {

    //create the url with NSURL
    let dataURL = URL(string: url)! //change the url

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

    //now create the URLRequest object using the url object
    let request = URLRequest(url: dataURL, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 60)

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

        guard error == nil else {
            completion(Result.failure(AppError.networkError(error!)))
            return
        }

        guard let data = data else {
            completion(Result.failure(APPError.dataNotFound))
            return
        }

        do {
            //create decodable object from data
            let decodedObject = try JSONDecoder().decode(objectType.self, from: data)
            completion(Result.success(decodedObject))
        } catch let error {
            completion(Result.failure(APPError.jsonParsingError(error as! DecodingError)))
        }
    })

    task.resume()
}

예:

// 자리 표시 자 API에서 할 일을 가져 오려면 ToDo 구조체를 정의하고 dataRequest를 호출하고 " https://jsonplaceholder.typicode.com/todos/1 "문자열 url을 전달 합니다.

struct ToDo: Decodable {
    let id: Int
    let userId: Int
    let title: String
    let completed: Bool

}

dataRequest(with: "https://jsonplaceholder.typicode.com/todos/1", objectType: ToDo.self) { (result: Result) in
    switch result {
    case .success(let object):
        print(object)
    case .failure(let error):
        print(error)
    }
}

// 결과가 출력됩니다.

ToDo(id: 1, userId: 1, title: "delectus aut autem", completed: false)

21

기본 스위프트 3+ 솔루션

guard let url = URL(string: "http://www.stackoverflow.com") else { return }

let task = URLSession.shared.dataTask(with: url) { data, response, error in

  guard let data = data, error == nil else { return }

  print(NSString(data: data, encoding: String.Encoding.utf8.rawValue))
}

task.resume()

3
귀하의 예는 Swift 3을 위한 것이므로, URL(string: "http://www.stackoverflow.com")대신 대신 사용해야 합니다NSURL
FelixSFD

URL에 URL에서 캐스팅하는 것은 이해되지 않는다URLSession.shared.dataTask(with: url!)
레오 버스들이시길

이 오류가 발생합니다 :App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file.

이 게시물에 따라 @YumYumYum 유무하면 구성 응용 프로그램 전송 보안 stackoverflow.com/questions/30731785/...
벤 설리반

Leo Dabus 변수 URL은 URL 유형입니까?
Tom Schulz

14

나는 지금까지 https://github.com/daltoniam/swiftHTTP 좋은 결과와 함께이 남자의 래퍼를 사용하고 있습니다 . 큰 누출 추상화가 없음지금까지 가 없습니다.

    do {
        let opt = try HTTP.GET("https://google.com")
        opt.start { response in
            if let err = response.error {
                print("error: \(err.localizedDescription)")
                return //also notify app of failure as needed
            }
            print("opt finished: \(response.description)")
            //print("data is: \(response.data)") access the response of the data with response.data
        }
    } catch let error {
        print("got an error creating the request: \(error)")
    }

3
보기를 표시하기 전에 요청이 완료 될 때까지 기다리는 방법을 찾으셨습니까? @AlexanderN
Reshad

9

세부

  • Xcode 9.2, 스위프트 4
  • Xcode 10.2.1 (10E1001), 스위프트 5

Info.plist

NSAppTransportSecurity

정보 plist에 추가하십시오.

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

알라모 파이어 샘플

알라모 파이어

import Alamofire

class AlamofireDataManager {
    fileprivate let queue: DispatchQueue
    init(queue: DispatchQueue) { self.queue = queue }

    private func createError(message: String, code: Int) -> Error {
        return NSError(domain: "dataManager", code: code, userInfo: ["message": message ])
    }

    private func make(session: URLSession = URLSession.shared, request: URLRequest, closure: ((Result<[String: Any]>) -> Void)?) {
        Alamofire.request(request).responseJSON { response in
            let complete: (Result<[String: Any]>) ->() = { result in DispatchQueue.main.async { closure?(result) } }
            switch response.result {
                case .success(let value): complete(.success(value as! [String: Any]))
                case .failure(let error): complete(.failure(error))
            }
        }
    }

    func searchRequest(term: String, closure: ((Result<[String: Any]>) -> Void)?) {
        guard let url = URL(string: "https://itunes.apple.com/search?term=\(term.replacingOccurrences(of: " ", with: "+"))") else { return }
        let request = URLRequest(url: url)
        make(request: request) { response in closure?(response) }
    }
}

Alamofire 샘플의 사용법

private lazy var alamofireDataManager = AlamofireDataManager(queue: DispatchQueue(label: "DataManager.queue", qos: .utility))
//.........

alamofireDataManager.searchRequest(term: "jack johnson") { result in
      print(result.value ?? "no data")
      print(result.error ?? "no error")
}

URL 세션 샘플

import Foundation

class DataManager {

    fileprivate let queue: DispatchQueue
        init(queue: DispatchQueue) { self.queue = queue }

    private func createError(message: String, code: Int) -> Error {
        return NSError(domain: "dataManager", code: code, userInfo: ["message": message ])
    }

    private func make(session: URLSession = URLSession.shared, request: URLRequest, closure: ((_ json: [String: Any]?, _ error: Error?)->Void)?) {
        let task = session.dataTask(with: request) { [weak self] data, response, error in
            self?.queue.async {
                let complete: (_ json: [String: Any]?, _ error: Error?) ->() = { json, error in DispatchQueue.main.async { closure?(json, error) } }

                guard let self = self, error == nil else { complete(nil, error); return }
                guard let data = data else { complete(nil, self.createError(message: "No data", code: 999)); return }

                do {
                    if let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any] {
                        complete(json, nil)
                    }
                } catch let error { complete(nil, error); return }
            }
        }

        task.resume()
    }

    func searchRequest(term: String, closure: ((_ json: [String: Any]?, _ error: Error?)->Void)?) {
        let url = URL(string: "https://itunes.apple.com/search?term=\(term.replacingOccurrences(of: " ", with: "+"))")
        let request = URLRequest(url: url!)
        make(request: request) { json, error in closure?(json, error) }
    }
}

URLSession 샘플의 사용법

private lazy var dataManager = DataManager(queue: DispatchQueue(label: "DataManager.queue", qos: .utility))
// .......
dataManager.searchRequest(term: "jack johnson") { json, error  in
      print(error ?? "nil")
      print(json ?? "nil")
      print("Update views")
}

결과

여기에 이미지 설명을 입력하십시오


searchRequest? 기간? 그들은 어디에서 왔니?
El Tomato

요청의 전체 샘플입니다. class func searchRequest(term: String, ...itunes.apple.com의 다운로드 데이터 샘플입니다. 이 샘플은 검색하므로 searchRequest함수 이름을 선택 / 발명했습니다 . term" itunes.apple.com/search ?"의 일부입니다. 의뢰. 논리 모델을 설명 할 함수 이름을 선택할 수 있습니다.
Vasily Bodnarchuk

좋은 해결책. closure케이스 success와 함께 열거 형을 반환하도록 을 변경했습니다 error.
neoneye

7

이 방법 으로 JSON 구문 분석을 사용 하여 GETPOST 메소드 모두 HTTP 요청 을 수행했습니다 .

()의 viewDidLoad :

override func viewDidLoad() {
super.viewDidLoad()

    makeGetRequest()
    makePostRequest()

}

func makePostRequest(){

    let urlPath: String = "http://www.swiftdeveloperblog.com/http-post-example-script/"
    var url: NSURL = NSURL(string: urlPath)!
    var request: NSMutableURLRequest = NSMutableURLRequest(URL: url)

    request.HTTPMethod = "POST"
    var stringPost="firstName=James&lastName=Bond" // Key and Value

    let data = stringPost.dataUsingEncoding(NSUTF8StringEncoding)

    request.timeoutInterval = 60
    request.HTTPBody=data
    request.HTTPShouldHandleCookies=false

    let queue:NSOperationQueue = NSOperationQueue()

    NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue(), completionHandler:{ (response:NSURLResponse!, data: NSData!, error: NSError!) -> Void in
        var error: AutoreleasingUnsafeMutablePointer<NSError?> = nil
        let jsonResult: NSDictionary! = NSJSONSerialization.JSONObjectWithData(data, options:NSJSONReadingOptions.MutableContainers, error: error) as? NSDictionary

         if (jsonResult != nil) {
            // Success
           println(jsonResult)

           let message = jsonResult["Message"] as! NSString

           println(message)
         }else {
            // Failed
            println("Failed")
        }

    })

}

func makeGetRequest(){
    var url : String = "http://api.androidhive.info/contacts/"
    var request : NSMutableURLRequest = NSMutableURLRequest()
    request.URL = NSURL(string: url)
    request.HTTPMethod = "GET"
    request.timeoutInterval = 60

    NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue(), completionHandler:{ (response:NSURLResponse!, data: NSData!, error: NSError!) -> Void in
        var error: AutoreleasingUnsafeMutablePointer<NSError?> = nil
        let jsonResult: NSDictionary! = NSJSONSerialization.JSONObjectWithData(data, options:NSJSONReadingOptions.MutableContainers, error: error) as? NSDictionary

        if (jsonResult != nil) {
            // Success
            println(jsonResult)

            let dataArray = jsonResult["contacts"] as! NSArray;

            for item in dataArray { // loop through data items

                let obj = item as! NSDictionary

                for (key, value) in obj {

                    println("Key: \(key) - Value: \(value)")

                    let phone = obj["phone"] as! NSDictionary;

                    let mobile = phone["mobile"] as! NSString
                    println(mobile)
                    let home = phone["home"] as! NSString
                    println(home)
                    let office = phone["office"] as! NSString
                    println(office)
                }
            }

        } else {
            // Failed
            println("Failed")
        }

    })
}

끝난


'(NSMutableURLRequest, 대기열 : NSOperationQueue, completionHandler : (NSURLResponse !, NSData !, NSError!)-> Void)'유형의 인수 목록으로 'sendAsynchronousRequest'를 호출 할 수 없습니다.
bMalum

4

URLSession + Swift 5 사용

cezar 's answer에 추가하기 만하면 Apple의 URLSession 클래스를 사용하여 웹 요청을하려면 여러 가지 방법으로 작업을 수행 할 수 있습니다

  1. URL을 포함한 간단한 GET 요청
  2. URL 및 매개 변수가있는 간단한 GET 요청
  3. 오류 처리가 포함 된 URL이 포함 된 간단한 GET 요청
  4. URL을 사용한 간단한 POST 요청, 오류 처리 기능이있는 매개 변수

1. URL을 이용한 간단한 GET 요청

func simpleGetUrlRequest()
    {
        let url = URL(string: "https://httpbin.org/get")!

        let task = URLSession.shared.dataTask(with: url) {(data, response, error) in
            guard let data = data else { return }
            print("The response is : ",String(data: data, encoding: .utf8)!)
            //print(NSString(data: data, encoding: String.Encoding.utf8.rawValue) as Any)
        }
        task.resume()
    }

참고 : http 요청을 위해 pList에 "NSAppTransportSecurity"키를 추가해야 합니다.

<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>

2. URL과 매개 변수를 포함한 간단한 GET 요청

func simpleGetUrlWithParamRequest()
    {
        let url = URL(string: "https://www.google.com/search?q=peace")!

        let task = URLSession.shared.dataTask(with: url) {(data, response, error) in

            if error != nil || data == nil {
                print("Client error!")
                return
            }
            guard let response = response as? HTTPURLResponse, (200...299).contains(response.statusCode) else {
                print("Server error!")
                return
            }
            print("The Response is : ",response)
        }
        task.resume()
    }

3. 오류 처리가 포함 된 URL을 사용한 간단한 GET 요청

func simpleGetUrlRequestWithErrorHandling()
    {
        let session = URLSession.shared
        let url = URL(string: "https://httpbin.org/get")!

        let task = session.dataTask(with: url) { data, response, error in

            if error != nil || data == nil {
                print("Client error!")
                return
            }

            guard let response = response as? HTTPURLResponse, (200...299).contains(response.statusCode) else {
                print("Server error!")
                return
            }

            guard let mime = response.mimeType, mime == "application/json" else {
                print("Wrong MIME type!")
                return
            }

            do {
                let json = try JSONSerialization.jsonObject(with: data!, options: [])
                print("The Response is : ",json)
            } catch {
                print("JSON error: \(error.localizedDescription)")
            }

        }
        task.resume()
    }

4. URL이있는 간단한 POST 요청, 오류 처리가있는 매개 변수.

func simplePostRequestWithParamsAndErrorHandling(){
        var session = URLSession.shared
        let configuration = URLSessionConfiguration.default
        configuration.timeoutIntervalForRequest = 30
        configuration.timeoutIntervalForResource = 30
        session = URLSession(configuration: configuration)

        let url = URL(string: "https://httpbin.org/post")!

        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        request.addValue("application/json", forHTTPHeaderField: "Accept")

        let parameters = ["username": "foo", "password": "123456"]

        do {
            request.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted)
        } catch let error {
            print(error.localizedDescription)
        }

        let task = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in

            if error != nil || data == nil {
                print("Client error!")
                return
            }

            guard let response = response as? HTTPURLResponse, (200...299).contains(response.statusCode) else {
                print("Oops!! there is server error!")
                return
            }

            guard let mime = response.mimeType, mime == "application/json" else {
                print("response is not json")
                return
            }

            do {
                let json = try JSONSerialization.jsonObject(with: data!, options: [])
                print("The Response is : ",json)
            } catch {
                print("JSON error: \(error.localizedDescription)")
            }

        })

        task.resume()
    }

당신의 제안에 감사드립니다 !!


var session = URLSession.shared변수를 사용하지 않고 변수를 덮어 쓸 때 왜 사용 합니까? 필요합니까?
vrwim

3

로그인 버튼 클릭시 json을 호출합니다.

@IBAction func loginClicked(sender : AnyObject) {

    var request = NSMutableURLRequest(URL: NSURL(string: kLoginURL)) // Here, kLogin contains the Login API.

    var session = NSURLSession.sharedSession()

    request.HTTPMethod = "POST"

    var err: NSError?
    request.HTTPBody = NSJSONSerialization.dataWithJSONObject(self.criteriaDic(), options: nil, error: &err) // This Line fills the web service with required parameters.
    request.addValue("application/json", forHTTPHeaderField: "Content-Type")
    request.addValue("application/json", forHTTPHeaderField: "Accept")

    var task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
        var strData = NSString(data: data, encoding: NSUTF8StringEncoding)
        var err1: NSError?
        var json2 = NSJSONSerialization.JSONObjectWithData(strData.dataUsingEncoding(NSUTF8StringEncoding), options: .MutableLeaves, error:&err1 ) as NSDictionary

        println("json2 :\(json2)")

        if(err) {
            println(err!.localizedDescription)
        }
        else {
            var success = json2["success"] as? Int
            println("Success: \(success)")
        }
    })

    task.resume()
}

여기서는 매개 변수에 대한 별도의 사전을 만들었습니다.

var params = ["format":"json", "MobileType":"IOS","MIN":"f8d16d98ad12acdbbe1de647414495ec","UserName":emailTxtField.text,"PWD":passwordTxtField.text,"SigninVia":"SH"]as NSDictionary
    return params
}

// You can add your own sets of parameter here.

2

당신은 사용할 수 있습니다 하는 python-requests스타일의 HTTP 라이브러리를.

Just로 HTTP 요청을 보내는 몇 가지 예 :

// synchronous GET request with URL query a=1
let r = Just.get("https://httpbin.org/get", params:["a":1])

// asynchronous POST request with form value and file uploads
Just.post(
    "http://justiceleauge.org/member/register",
    data: ["username": "barryallen", "password":"ReverseF1ashSucks"],
    files: ["profile_photo": .URL(fileURLWithPath:"flash.jpeg", nil)]
) { (r)
    if (r.ok) { /* success! */ }
}

두 경우 모두 다음 r과 유사한 방식으로 요청 결과에 액세스 할 수 있습니다 python-request.

r.ok            // is the response successful?
r.statusCode    // status code of response
r.content       // response body as NSData?
r.text          // response body as text?
r.json          // response body parsed by NSJSONSerielization

운동장 에서 더 많은 예를 찾을 수 있습니다

놀이터에서이 라이브러리를 동기 모드로 사용하는 것은 Swift에서 얻을 수있는 가장 가까운 URL입니다.


이 링크가 질문에 대한 답변을 제공 할 수 있지만 여기에 답변의 필수 부분을 포함시키고 참조 용 링크를 제공하는 것이 좋습니다. 링크 된 페이지가 변경되면 링크 전용 답변이 유효하지 않을 수 있습니다.
dimo414

이 라이브러리는 더 이상 사용되지 않는 것 같습니다. Swift 4를 지원하지 않으며 공개 된 문제에 아무도 응답하지 않습니다.
Heinrisch

2

Swift 4.1 및 Xcode 9.4.1에서.

JSON POST 접근법 예제. 인터넷 연결을 확인하려면 https://developer.apple.com/library/archive/samplecode/Reachability/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007324-Intro-DontLinkElementID_2 에서 Reachability.h 및 .m 파일을 추가 하십시오.

func yourFunctionName {
    //Check internet connection
    let networkReachability = Reachability.forInternetConnection()
    let networkStatus:Int = (networkReachability?.currentReachabilityStatus())!.rawValue
    print(networkStatus)
    if networkStatus == NotReachable.rawValue {
        let msg = SharedClass.sharedInstance.noNetMsg//Message
        //Call alert from shared class
        SharedClass.sharedInstance.alert(view: self, title: "", message: msg)
    } else {
        //Call spinner from shared class
        SharedClass.sharedInstance.activityIndicator(view: self.view)//Play spinner

        let parameters = "Your parameters here"
        var request = URLRequest(url: URL(string: url)!)

        request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
        request.httpMethod = "POST"

        print("URL : \(request)")

        request.httpBody = parameters.data(using: .utf8)

        let task = URLSession.shared.dataTask(with: request) { data, response, error in guard let data = data, error == nil else { // check for fundamental networking error
            //Stop spinner
            SharedClass.sharedInstance.stopActivityIndicator() //Stop spinner
            //Print error in alert
            SharedClass.sharedInstance.alert(view: self, title: "", message: "\(String(describing: error!.localizedDescription))")
            return
            }

            SharedClass.sharedInstance.stopActivityIndicator() //Stop spinner

            if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { // check for http errors
                print("statusCode should be 200, but is \(httpStatus.statusCode)")
                print("response = \(String(describing: response))")
            }

            do {
                let response = try JSONSerialization.jsonObject(with: data, options: []) as? [String: AnyObject]
                print(response!)
                //Your code here                    
            } catch let error as NSError {
                print(error)
            }
        }

        task.resume()

    }

}

SharedClass 에서이 함수를 사용하려는 경우

//My shared class
import UIKit
class SharedClass: NSObject {

static let sharedInstance = SharedClass()

func postRequestFunction(apiName: String , parameters: String, onCompletion: @escaping (_ success: Bool, _ error: Error?, _ result: [String: Any]?)->()) {

    var URL =  "your URL here/index.php/***?"

    URL = URL.replacingOccurrences(of: "***", with: apiName)

    var request = URLRequest(url: URL(string: URL)!)
    request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
    request.httpMethod = "POST"
    print("shared URL : \(request)")
    request.httpBody = parameters.data(using: .utf8)

    var returnRes:[String:Any] = [:]
    let task = URLSession.shared.dataTask(with: request) { data, response, error in

        if let error = error {
            onCompletion(false, error, nil)
        } else {
            guard let data = data else {
                onCompletion(false, error, nil)
                return
            }

            if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode == 200 {
                do {
                   returnRes = try JSONSerialization.jsonObject(with: data, options: []) as! [String : Any]
                    onCompletion(true, nil, returnRes)

                } catch let error as NSError {
                   onCompletion(false, error, nil)
                }
            } else {
                onCompletion(false, error, nil)
            }
        }
    }
    task.resume()
}


private override init() {

}

마지막으로이 함수를 이렇게 호출하십시오 ....

SharedClass.sharedInstance.postRequestFunction(apiName: "Your API name", parameters: parameters) { (success, error, result) in
    print(result!)
    if success {
        //Your code here
    } else {
        print(error?.localizedDescription ?? "")
    }
}

1

HTTP GET 요청을하는 간단한 Swift 2.0 접근 방식

HTTP 요청은 비동기 적이므로 HTTP 요청에서 반환 된 값을 가져 오는 방법이 필요합니다. 이 접근 방식은 알리미를 사용하며 두 클래스에 걸쳐 있습니다.

예는 웹 사이트 http://www.example.com/handler.php?do=CheckUserJson&json=를 사용하여 식별자 토큰의 사용자 이름과 비밀번호를 확인하는 것입니다.이 파일은 handler.php라고하며 RESTful 접근 방식을 얻으려면 매개 변수를 수행하십시오.

viewDidLoad에서 NotifierObserver를 설정하고 json을 설정 한 후 getHTTPRequest 함수를 호출합니다. http 요청에서 리턴 된 매개 변수와 함께 checkedUsernameAndPassword 함수로 리턴됩니다.

override func viewDidLoad() {
    super.viewDidLoad()
    // setup the Notification observer to catch the result of check username and password
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "checkedUsernameAndPassword:", name: CHECK_USERNAME_AND_PASSWORD, object: nil)        
    let username = GlobalVariables.USER_NAME
    let password = GlobalVariables.PASSWORD
    // check username and password
    if let jsonString = Utility.checkUsernameAndPasswordJson(username, password:password){
        print("json string returned = \(jsonString)")
        let url = CHECKUSERJSON+jsonString
        // CHECKUSERJSON = http://www.example.com/handler.php?do=CheckUserJson&json=
        // jsonString = {\"username\":\"demo\",\"password\":\"demo\"}"
        // the php script handles a json request and returns a string identifier           
        Utility.getHTTPRequest(url,notifierId: CHECK_USERNAME_AND_PASSWORD)
        // the returned identifier is sent to the checkedUsernaeAndPassword function when it becomes availabel.
    }
}

Utility.swift에는 먼저 json을 인코딩 한 다음 HTTP 호출을 수행하는 두 가지 정적 함수가 있습니다.

    static func checkUsernameAndPasswordJson(username: String, password: String) -> String?{
    let para:NSMutableDictionary = NSMutableDictionary()
        para.setValue("demo", forKey: "username")
        para.setValue("demo", forKey: "password")
    let jsonData: NSData
    do{
        jsonData = try NSJSONSerialization.dataWithJSONObject(para, options: NSJSONWritingOptions())
        let jsonString = NSString(data: jsonData, encoding: NSUTF8StringEncoding) as! String
        return jsonString
    } catch _ {
        print ("UH OOO")
        return nil
    }
}

그리고 HTTP 요청

    static func getHTTPRequest (url:String , notifierId: String) -> Void{
    let urlString = url
    let config = NSURLSessionConfiguration.defaultSessionConfiguration()
    let session = NSURLSession(configuration: config, delegate: nil, delegateQueue: nil)
    let safeURL = urlString.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())!
    if let url = NSURL(string: safeURL){
        let request  = NSMutableURLRequest(URL: url)
        request.HTTPMethod = "GET"
        request.timeoutInterval = 60
        let taskData = session.dataTaskWithRequest(request, completionHandler: {
            (data:NSData?, response:NSURLResponse?, error:NSError?) -> Void in
            if (data != nil) {
                let result = NSString(data: data! , encoding: NSUTF8StringEncoding)
                sendNotification (notifierId, message: String(result), num: 0)
            }else{
                  sendNotification (notifierId, message: String(UTF8String: nil), num: -1)                    }
        })
    taskData.resume()
    }else{
        print("bad urlString = \(urlString)")
    }
}

sendNotification 함수는 원을 완성합니다. 관찰자에서 선택기 문자열의 끝에 ":"가 있습니다. 이를 통해 알림이 userInfo에 페이로드를 전달할 수 있습니다. 나는 이것을 String과 Int로 준다.

    static func sendNotification (key: String, message:String?, num: Int?){
    NSNotificationCenter.defaultCenter().postNotificationName(
        key,
        object: nil,
        userInfo:   (["message": message!,
                      "num": "\(num!)"])
    )
}

HTTP 사용은 oldFashioned이며 HTTPS를 선호합니다 . iOS 9에서 App Transport Security를 ​​사용하여 HTTP URL을로드하는 방법을 참조하십시오 .


0
 var post:NSString = "api=myposts&userid=\(uid)&page_no=0&limit_no=10"

    NSLog("PostData: %@",post);

    var url1:NSURL = NSURL(string: url)!

    var postData:NSData = post.dataUsingEncoding(NSASCIIStringEncoding)!

    var postLength:NSString = String( postData.length )

    var request:NSMutableURLRequest = NSMutableURLRequest(URL: url1)
    request.HTTPMethod = "POST"
    request.HTTPBody = postData
    request.setValue(postLength, forHTTPHeaderField: "Content-Length")
    request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
    request.setValue("application/json", forHTTPHeaderField: "Accept")

    var reponseError: NSError?
    var response: NSURLResponse?

    var urlData: NSData? = NSURLConnection.sendSynchronousRequest(request, returningResponse:&response, error:&reponseError)

    if ( urlData != nil ) {
        let res = response as NSHTTPURLResponse!;

        NSLog("Response code: %ld", res.statusCode);

        if (res.statusCode >= 200 && res.statusCode < 300)
        {
            var responseData:NSString  = NSString(data:urlData!, encoding:NSUTF8StringEncoding)!

            NSLog("Response ==> %@", responseData);

            var error: NSError?

            let jsonData:NSDictionary = NSJSONSerialization.JSONObjectWithData(urlData!, options:NSJSONReadingOptions.MutableContainers , error: &error) as NSDictionary

            let success:NSInteger = jsonData.valueForKey("error") as NSInteger

            //[jsonData[@"success"] integerValue];

            NSLog("Success: %ld", success);

            if(success == 0)
            {
                NSLog("Login SUCCESS");

                self.dataArr = jsonData.valueForKey("data") as NSMutableArray
                self.table.reloadData()

            } else {

                NSLog("Login failed1");
                ZAActivityBar.showErrorWithStatus("error", forAction: "Action2")
            }

        } else {

            NSLog("Login failed2");
            ZAActivityBar.showErrorWithStatus("error", forAction: "Action2")

        }
    } else {

        NSLog("Login failed3");
        ZAActivityBar.showErrorWithStatus("error", forAction: "Action2")
}

그것은 확실히 당신을 도울 것입니다


0

// 다음은 나를 위해 일한 예입니다.

// 키 값으로 서버에 요청을 게시하는 스위프트 함수

func insertRecords()
{



    let usrID = txtID.text
    let checkin = lblInOut.text
    let comment = txtComment.text



    // The address of the web service
    let urlString = "http://your_url/checkInOut_post.php"

    // These are the keys that your are sending as part of the post request
    let keyValues = "id=\(usrID)&inout=\(checkin)&comment=\(comment)"




    // 1 - Create the session by getting the configuration and then
    //     creating the session

    let config = NSURLSessionConfiguration.defaultSessionConfiguration()
    let session = NSURLSession(configuration: config, delegate: nil, delegateQueue: nil)


    // 2 - Create the URL Object

    if let url = NSURL(string: urlString){


        // 3 - Create the Request Object

        var request  = NSMutableURLRequest(URL: url)
        request.HTTPMethod = "POST"

        // set the key values
        request.HTTPBody = keyValues.dataUsingEncoding(NSUTF8StringEncoding);


        // 4 - execute the request

        let taskData = session.dataTaskWithRequest(request, completionHandler: {

            (data:NSData!, response:NSURLResponse!, error:NSError!) -> Void in

            println("\(data)")

            // 5 - Do something with the Data back

            if (data != nil) {

                // we got some data back
                println("\(data)")

                let result = NSString(data: data , encoding: NSUTF8StringEncoding)
                println("\(result)")

                if result == "OK" {

                    let a = UIAlertView(title: "OK", message: "Attendece has been recorded", delegate: nil, cancelButtonTitle: "OK")

                    println("\(result)")

                    dispatch_async(dispatch_get_main_queue()) {


                    a.show()


                    }


                } else {
                  // display error and do something else

                }


            } else

            {   // we got an error
                println("Error getting stores :\(error.localizedDescription)")

            }


        })

        taskData.resume()



    }


}

핵심 가치를 얻는 PHP 코드

$ empID = $ _POST [ 'id'];

$ inOut = $ _POST [ 'inout'];

$ comment = $ _POST [ 'comment'];


0

놀이터에서 매우 간단한 Swift 4 예제는 다음과 같습니다 .

import UIKit
// run asynchronously in a playground
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true

// create a url
let url = URL(string: "http://www.stackoverflow.com")

// create a data task
let task = URLSession.shared.dataTask(with: url!) { (data, response, error) in
    if error != nil {
        print("there's a problem")
    }
    print(String(data: data!, encoding: String.Encoding.utf8) ?? "")
}

//running the task w/ resume
task.resume()

0

비동기 요청이 완료되기 전에 XCUITest에서 테스트 완료를 중지하려면 다음을 사용하십시오 (100 시간 초과를 줄일 수 있음).

func test_api() {
    let url = URL(string: "https://jsonplaceholder.typicode.com/posts/42")!
    let exp = expectation(description: "Waiting for data")
    let task = URLSession.shared.dataTask(with: url) {(data, response, error) in
        guard let data = data else { return }
        print(String(data: data, encoding: .utf8)!)
        exp.fulfill()
    }
    task.resume()
    XCTWaiter.wait(for: [exp], timeout: 100)
}

0

키스 답변 :

URLSession.shared.dataTask(with: URL(string: "https://google.com")!) {(data, response, error) in
    print(String(data: data!, encoding: .utf8))
}.resume()

-2

샘플 "GET"요청의 예는 다음과 같습니다.

let urlString = "YOUR_GET_URL"
let yourURL = URL(string: urlstring)
let dataTask = URLSession.shared.dataTask(with: yourURL) { (data, response, error) in
do {
    let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers)
    print("json --- \(json)")
    }catch let err {
    print("err---\(err.localizedDescription)")
    }
   }
dataTask.resume()
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.