如何在Swift中发出HTTP请求? [ios]


Answers

您可以像Objective-C一样使用URLURLRequestURLSessionNSURLConnection 。 请注意,对于iOS 7.0及更高版本,首选URLSession

使用URLSession

URLSession初始化URL对象和URLSession 。 然后用resume()运行任务。

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

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

task.resume()

使用NSURLConnection

首先,初始化URLURLRequest

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

然后,您可以异步加载请求:

NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) {(response, data, error) in
    print(NSString(data: data!, encoding: NSUTF8StringEncoding))
}

或者您可以初始化NSURLConnection

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

只需确保将您的代理设置为不是nil并使用委托方法来处理收到的响应和数据。

有关更多详细信息,请查看NSURLConnectionDataDelegate协议文档

在Xcode操场上进行测试

如果您想在Xcode操场上尝试此代码,请将import XCPlayground添加到操场,以及以下调用:

XCPSetExecutionShouldContinueIndefinitely()

这将允许您在操场中使用异步代码。

Question

我在iBooks中阅读了Apple的“Programming Language Swift”,但无法弄清楚如何在Swift中进行http请求(如CURL)。 我需要导入Obj-C类,还是只需要导入默认库? 还是不可能根据本机swift代码发出HTTP请求?




我正在使用这个家伙的包装器,迄今为止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)")
    }



使用URLSession API的Swift 3数据请求

   //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()



您可以使用Just ,一个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! */ }
}

在这两种情况下,可以以与python-request相似的方式访问请求r的结果:

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最接近的cURL。




一个简单的Swift 2.0方法来制作HTTP GET请求

HTTP请求是异步的,因此您需要一种从HTTP请求获取返回值的方法。 这种方法使用通配符并分布在两个类上。

示例是使用网站http://www.example.com/handler.php?do=CheckUserJson&json=来检查标识符令牌的用户名和密码这就是文件叫做handler.php,并且有一个switch语句做参数以获得RESTful方法。

在viewDidLoad中,我们设置NotifierObserver,设置json并调用getHTTPRequest函数。 它将返回函数checkedUsernameAndPassword与http请求中返回的参数。

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中启用应用程序传输安全性加载HTTP URL?




//这是一个为我工作的例子

//将Swift函数发送给具有键值的服务器

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'];