This question already has answers here:
How can I get the Data from NSURLSession.sharedSession().dataTaskWithRequest
(2 answers)
Closed 6 years ago.
I'm trying to post from swift to php and then return json encoded data back to swift.
However, print(task.response) is nil. My link does what it is supposed to but my app still responds with nil. Any idea why?
let request = NSMutableURLRequest(URL: NSURL(string: "https://www.flashkase.com/API/createAccount.php")!)
request.HTTPMethod = "POST"
let postString = "username=frogg222"
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in
guard error == nil && data != nil else { // check for fundamental networking error
print("error=\(error)")
return
}
if let httpStatus = response as? NSHTTPURLResponse where httpStatus.statusCode != 200 { // check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(response)")
}
let responseString = String(data: data!, encoding: NSUTF8StringEncoding)
print("responseString = \(responseString)")
}
task.resume()
print(task.response)
And my PHP file
<?php
include($_SERVER["DOCUMENT_ROOT"] . "/inc/database.php");
$arr = [];
$arr[] = 'Reporting for duty';
if($_SERVER['REQUEST_METHOD'] == 'POST'){
$arr[] = 'Post received';
$arr[] = $_POST['username'];
}
echo json_encode($arr);
?>
Update: How can I check for data after completion? If I uncomment sleep(3) it will display results...but that's obviously not ideal.
func postToServer(postURL: String, postString: String) {
let request = NSMutableURLRequest(URL: NSURL(string: postURL)!)
request.HTTPMethod = "POST"
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request){
data, response, error in
print("\(data), \(response), \(error)")
}
task.resume()
//sleep(3)
}
let sendURL: String = "https://www.flashkase.com/API/createAccount.php"
let sendData: String = "username=frogg222&email=fake123#gmail.com&password=fake1234"
postToServer(sendURL,postString: sendData)
dataTaskWithRequest is an asynchronous operation. Printing the response code immediately after the task starts will obviously print nil, as it hasn't had time to get a value. The completion handler already has a response object you can use, so inside your completion handler, call print(response) to see the properties and try to get a response code.
Related
I use this code and work perfect. I use swift. PHP is work fine.
I also try some other examples at this
I have 2 problems
first my responseString values turns in Optional("Success"). Why?
second is How can assign it on my button?
func makePostCall() {
var request = URLRequest(url: URL(string: "MyURL/page.php")!)
request.httpMethod = "POST"
let postString = "id=login"
request.httpBody = postString.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
print("error=\(error)")
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { // check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(response)")
}
let responseString = String(data: data, encoding: .utf8)
print("responseString = \(responseString)")
self.lbl.text = responseString
}
task.resume()
//return responseString
}
You need to use DispatchQueue.main.async to work with UI from URLRequests. Also you need to use [weak self] to prevent reference cycle problem. At last, btn.setTitle(responseString, for: .normal) to set title for button state .normal. Here is correct answer!
func makePostCall() {
var request = URLRequest(url: URL(string: "MyURL/page.php")!)
request.httpMethod = "POST"
let postString = "id=login"
request.httpBody = postString.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request) {[weak self] data, response, error in
guard let data = data, error == nil else { // check for fundamental networking error
print("error=\(error)")
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { // check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(response)")
}
guard let responseString = String(data: data, encoding: .utf8) else {
return
}
print("responseString = \(responseString)")
DispatchQueue.main.async {
self?.lbl.text = responseString
self?.btn.setTitle(responseString, for: .normal) // your button
}
}
task.resume()
//return responseString
}
With my program I try to login and scrape the home page, however after I log in with a post request (in which the response says successful), when I try to get the home page it says my session has timed out.
I've tried using different types of session, modifying minor parts of the code, and Alamofire with no success
import Foundation
let session: URLSession = {
let configuration = URLSessionConfiguration.default
configuration.timeoutIntervalForRequest = 30 // seconds
configuration.timeoutIntervalForResource = 30 // seconds
return URLSession(configuration: .default)
}()
let url = URL(string: "examplesite.com")!
var request = URLRequest(url: url)
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField:
"Content-Type")
request.httpMethod = "POST"
let postString = "Email=exampleemail&Password=examplepass"
request.httpBody = postString.data(using: .utf8)
//log in
session.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else {
// check for fundamental networking error
print("\(error)")
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode
!= 200 { // check for http errors
print("\(httpStatus.statusCode)")
print("\(response)")
}
let responseString = String(data: data, encoding: .utf8)
print("\(responseString)")
let urlnext = URL(string: "example.com/HomePage")!
//get page after loggin in
session.dataTask(with: urlnext) { datanext, responsenext, errornext in
guard let datanext = datanext, errornext == nil else {
print("\(errornext)")
return
}
let stringnext = String(data: datanext, encoding: .utf8)
//get page html
print("\(stringnext)")
}.resume()
}.resume()
// Infinitely run the main loop to wait for our request.
// Only necessary if you are testing in the command line.
RunLoop.main.run()
the results are a successful login {\"msg\":\"\",\"valid\":\"1\"}, and the html code of a time out page instead of the home page
My question is i want to hit the url and when i hit the url on server side the php return the results just echo in php and i have to save that result in variable in swift 3, i tried the below code:
let URLstr = URL(string: strURL)
let request = URLRequest(url: URLstr!)
request.httpMethod = "POST"
print (request)
I didn't get the content of URL in swift which is much easier in objective C.
Use the string initializer with the url.
do {
let contents = try String(contentsOf: URLstr, encoding: .ascii)
} catch {
// handle error
}
Or you can use URLSession.
let task = URLSession.shared.dataTask(with: URLStr) { data, response, error in
guard data != nil else { // no data }
let contents = String(data: data!, encoding: .ascii)
}
task.resume()
I adjusted the code provided above. To fetch HTML code use URLSession.
Swift 5
let session = URLSession.shared
let url = URL(string: "https://yourwebsiteaddress.com/")!
let task = session.dataTask(with: url) { data, response, error in
// Check whether data is not nil
guard let loadedData = data else { return }
// Load HTML code as string
let contents = String(data: loadedData, encoding: .utf8)
print(contents)
}
task.resume()
strong text this is my code to pass two parameters(jsonData and device_Secret) to httpBody for that i should get following son in response
{"success":false,"msg":"Key not created plz try again."}
but i m getting this
responseString = Optional({"success":false,"msg":"Invalid Method"})
there is a problem in parameters format, what i am doing wrong?
my code is following /////////////
let JsonData = ["method":"device_token","params":["key":"1234jhg","device_id":"eb7e630a9637b0b83557e5a62121be8cb9210afb9aa5b878f819b775cb7d42a6"]]
let device_secret = ["params":["token":"-1","device_id":"9de47fb53c67eca4","key":"-1"]]
let params = ["data":JsonData, "device_secret":device_secret] as Dictionary<String, AnyObject>
let request = NSMutableURLRequest(URL: NSURL(string: "http://dev.jobsmarket.pk/api/v1")!)
print(request)
request.HTTPMethod = "POST"
let data : NSData = NSKeyedArchiver.archivedDataWithRootObject(params)
print("NSdata of params is")
print(data)
NSJSONSerialization.isValidJSONObject(params)
print( NSJSONSerialization.isValidJSONObject(params))
// request.HTTPBody = params
request.HTTPBody = NSKeyedArchiver.archivedDataWithRootObject(params)
print("httpBody is ")
print(request.HTTPBody)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in
guard error == nil && data != nil else { // check for fundamental networking error
print("error=\(error)")
return
}
if let httpStatus = response as? NSHTTPURLResponse where httpStatus.statusCode != 200 { // check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(response)")
}
let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("responseString = \(responseString)")
}
task.resume()
/////////////////////////
I have been following this tutorial to learn Swift and I have a few questions on the way they do things.
Specifically here:
let paramString = "data=Hello"
request.HTTPBody = paramString.dataUsingEncoding(NSUTF8StringEncoding)
let task = session.dataTaskWithRequest(request) {
(data, response, error) in
guard let _:NSData = data, let _:NSURLResponse = response where error == nil else {
print("Error")
return
}
let dataString = NSString(data: data!, encoding: NSUTF8StringEncoding)
print(dataString)
}
Why is (data, response, error) in always used in NSURLSessions? What does this line of code mean? Also, why does he have a guard statement underneath?
The whole section of code is here:
func dataRequest() {
let urlToRequest: String = " http://www.kaleidosblog.com/tutorial/nsurlsession_tutorial.php"
let url: NSURL = NSURL(string: urlToRequest)!
let session = NSURLSession.sharedSession()
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringCacheData
let paramString = "data=Hello"
request.HTTPBody = paramString.dataUsingEncoding(NSUTF8StringEncoding)
let task = session.dataTaskWithRequest(request) {
(data, response, error) in
guard let _:NSData = data, let _:NSURLResponse = response where error == nil else {
print("Error")
return
}
let dataString = NSString(data: data!, encoding: NSUTF8StringEncoding)
print(dataString)
}
task.resume()
}
With NSURLSession you make asynchronous calls, meaning that you make / start a network request and your program continues running - it doesn't stop waiting for response. Then, when your response is ready a completion block gets called / executed. So you need a way to access the data that's coming to you with this response. This data is accessible to you with (data, response, error) properties. This are just the names of those properties, so that you know how to use them. You could have different names, but it would be confusing to anyone else.
You use the guard statement because you can't be sure that you actually have the data or the response. It could be nil if an error occurred (timeout, ...). In such case (if there's an error) you just print "Error" to the console and call return, which makes you leave the completion block without executing the lines let dataString = NSString(data: data!, encoding: NSUTF8StringEncoding) and print(dataString). Of course, if you have the data and the response and error == nil you skip the else block of the guard statement and you just execute you last two lines of code in the block.