How do I make an HTTP request in Swift?

前端 未结 20 1087
不知归路
不知归路 2020-11-22 05:10

I read The Programming Language Swift by Apple in iBooks, but cannot figure out how to make an HTTP request (something like cURL) in Swift. Do I need to import Obj-C classes

相关标签:
20条回答
  • 2020-11-22 05:39

    Check Below Codes :

    1. SynchonousRequest

    Swift 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)")
    

    Swift 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. AsynchonousRequest

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

    Swift 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. As usual URL connection

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

    Then

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

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

    Then

    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. Asynchonous POST Request

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

    Swift 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. Asynchonous GET Request

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

    Swift 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. Image(File) Upload

    Swift 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()
    
    0 讨论(0)
  • 2020-11-22 05:39

    Swift 3.0

    Through a small abstraction https://github.com/daltoniam/swiftHTTP

    Example

        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)")
        }
    
    0 讨论(0)
  • 2020-11-22 05:44
     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")
    }
    

    it will help you surely

    0 讨论(0)
  • 2020-11-22 05:47

    I am calling the json on login button click

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

    Here, I have made a seperate dictionary for the parameters.

    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.
    
    0 讨论(0)
  • 2020-11-22 05:48

    A simple Swift 2.0 approach to making a HTTP GET request

    The HTTP request is asynchronous so you need a way to get the returned value from the HTTP Request. This approach uses Notifiers and is spread over two classes.

    The example is to check the username and password for an identifier token using the website http://www.example.com/handler.php?do=CheckUserJson&json= That is the file is called handler.php and has a switch statement on the do parameter to get a RESTful approach.

    In the viewDidLoad we setup the NotifierObserver, set up the json and make the call to the getHTTPRequest function. It will return to the function checkedUsernameAndPassword with the returned parameter from the http request.

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

    There are two static functions in Utility.swift first to encode the json and then to do the HTTP call.

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

    and the Http request

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

    The sendNotification function completes the circle. Notice that in teh Observer there is a ":" at the end of the selector string. This allows the notification to carry a payload in userInfo. I give this a String and an Int.

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

    Note that using HTTP is oldFashioned, prefer HTTPS see How do I load an HTTP URL with App Transport Security enabled in iOS 9?

    0 讨论(0)
  • 2020-11-22 05:50

    Swift 4 and above : Data Request using 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()
    

    Swift 4 and above, Decodable and Result enum

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

    example:

    //if we want to fetch todo from placeholder API, then we define the ToDo struct and call dataRequest and pass "https://jsonplaceholder.typicode.com/todos/1" string 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)
        }
    }
    

    //this prints the result:

    ToDo(id: 1, userId: 1, title: "delectus aut autem", completed: false)
    
    0 讨论(0)
提交回复
热议问题