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:
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 withrun(mode:before:)
until the network request finishes, as advised in therun
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)
}In standard macOS apps, you have to enable outgoing (client) connections in the “App Sandbox” capabilities.
If playground, you have to set
needsIndefiniteExecution
.By default, macOS and iOS apps disable
http
requests unless you enable "Allow Arbitrary Loads” in yourInfo.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?
ok approach you're answer with this solution
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
Add Animations to Foreach Loop Elements (Swiftui)
Alamofire: Send JSON with Array of Dictionaries
Swift 4.2 Setter Getter, All Paths Through This Function Will Call Itself
Mutable Binding in Swiftui Live Preview
Parameters After Opening Bracket
Call Completion Block When Two Other Completion Blocks Have Been Called
Uiscrollview with Embedded Uiimageview; How to Get the Image to Fill the Screen
Swiftui: How to Present View When Clicking on a Button
How Does Dictionary Use the Equatable Protocol in Swift
Swift: Corelocation Handling Nserror in Didfailwitherror
Get Image from Calayer or Nsview (Swift 3)
In Swift, What Does It Mean for Protocol to Inherit from Class Keyword
Can an Enum Contain Another Enum Values in Swift
Spacer Not Working with Form Inside a VStack
Make Int Round Off to Nearest Value
How to Display Realm Results in Swiftui List
How to Copy a Struct and Modify One of Its Properties at the Same Time