Swift Http Request Use Urlsession

How to make HTTP request in Swift?

You can use URL, URLRequest and URLSession or NSURLConnection as you'd normally do in Objective-C. Note that for iOS 7.0 and later, URLSession is preferred.

Using URLSession

Initialize a URL object and a URLSessionDataTask from URLSession. Then run the task with 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()

Using NSURLConnection

First, initialize a URL and a URLRequest:

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

Then, you can load the request asynchronously with:

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

Or you can initialize an NSURLConnection:

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

Just make sure to set your delegate to something other than nil and use the delegate methods to work with the response and data received.

For more detail, check the documentation for the NSURLConnectionDataDelegate protocol

Testing on an Xcode playground

If you want to try this code on a Xcode playground, add import PlaygroundSupport to your playground, as well as the following call:

PlaygroundPage.current.needsIndefiniteExecution = true

This will allow you to use asynchronous code in playgrounds.

Making HTTP GET request with Swift 5

Right now, if there is an error, you are going to silently fail. So add some error logging, e.g.,

func httpRequest() {
let url = URL(string: "https://www.stackoverflow.com")! // note, https, not http

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

print(string)
}
task.resume()
}

That should at least give you some indication of the problem.

A few other considerations:

  1. If command line app, you have to recognize that the app may quit before this asynchronous network request finishes. One would generally start up a RunLoop, looping with run(mode:before:) until the network request finishes, as advised in the run documentation.

    For example, you might give that routine a completion handler that will be called on the main thread when it is done. Then you can use that:

    func httpRequest(completion: @escaping () -> Void) {
    let url = URL(string: "https://www.stackoverflow.com")! // note, https, not http

    let task = URLSession.shared.dataTask(with: url) { data, response, error in
    defer {
    DispatchQueue.main.async {
    completion()
    }
    }

    guard
    error == nil,
    let data = data,
    let string = String(data: data, encoding: .utf8)
    else {
    print(error ?? "Unknown error")
    return
    }

    print(string)
    }
    task.resume()
    }

    var finished = false

    httpRequest {
    finished = true
    }

    while !finished {
    RunLoop.current.run(mode: .default, before: .distantFuture)
    }
  2. In standard macOS apps, you have to enable outgoing (client) connections in the “App Sandbox” capabilities.

  3. If playground, you have to set needsIndefiniteExecution.

  4. By default, macOS and iOS apps disable http requests unless you enable "Allow Arbitrary Loads” in your Info.plist. That is not applicable to command line apps, but you should be aware of that should you try to do this in standard macOS/iOS apps.

    In this case, you should just use https and avoid that consideration altogether.

Using Swift with URLSession works with GET and PUT, but it gives error 405 Method Not Allowed when I use POST

I find out the fix for my problem.

I was using "http://MY_ENDPOINT/validaResenha" in my constants file instead of using "https://MY_ENDPOINT/validaResenha".

After add the "s" to "http" letter (it becomes "https") everything starts to work for me.

The strange part is that GET and PUT methods works fine because of the redirect from HTTP to HTTPS, but in the case of POST calls, I got this error.

It's fixed now.

How to pass data into header while using URLSession in Swift?

Sample Image

ok approach you're answer with this solution

Sample Image

Swift 5, make http post request

Below is the code for Post Method,using URLSession

let Url = String(format: "http://10.10.10.53:8080/sahambl/rest/sahamblsrv/userlogin")
guard let serviceUrl = URL(string: Url) else { return }
let parameters: [String: Any] = [
"request": [
"xusercode" : "YOUR USERCODE HERE",
"xpassword": "YOUR PASSWORD HERE"
]
]
var request = URLRequest(url: serviceUrl)
request.httpMethod = "POST"
request.setValue("Application/json", forHTTPHeaderField: "Content-Type")
guard let httpBody = try? JSONSerialization.data(withJSONObject: parameters, options: []) else {
return
}
request.httpBody = httpBody
request.timeoutInterval = 20
let session = URLSession.shared
session.dataTask(with: request) { (data, response, error) in
if let response = response {
print(response)
}
if let data = data {
do {
let json = try JSONSerialization.jsonObject(with: data, options: [])
print(json)
} catch {
print(error)
}
}
}.resume()
}


Related Topics



Leave a reply



Submit