URLSession dataTask doesn't work - ios

im new at swift and im trying to get response from a soap services, but the dataTask in my session never get in, always skip it. I already test te urls and the soap message but i don't have any lucky. Here is my code
func servisRun(){
let soapMessage = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:tem=\"http://tempuri.org/\"><soapenv:Header/><soapenv:Body><tem:LogIn><tem:user>00002403</tem:user><tem:password>123456</tem:password></tem:LogIn></soapenv:Body></soapenv:Envelope>"
let msgLength = String(describing: soapMessage.characters.count)
let url = URL(string: "http://192.168.1.171/WcfSif.Services.Login.Login.svc")
var request = URLRequest(url: url!)
request.addValue("text/xml; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.addValue(msgLength, forHTTPHeaderField: "Content-Length")
request.httpMethod = "POST"
request.httpBody = soapMessage.data(using: String.Encoding.utf8, allowLossyConversion: false)
URLSession.shared.dataTask(with: request) { (data, resp, error) in
guard error == nil && data != nil else{
print("connection error or data is nill")
return
}
if resp != nil {
self.mutableData?.length = 0;
}
let mutableData : Void = NSMutableData.initialize()
print(mutableData)
let dataString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
self.mutableData?.append(data!)
print(dataString!)
}
.resume()
let nsData = mutableData?.copy() as! NSData
let xmlParser = XMLParser(data: nsData as Data)
xmlParser.delegate = self
xmlParser.parse()
xmlParser.shouldResolveExternalEntities = true
}

Related

HTTP Post request with body receiving null values to server

I am using trying to post some data to server using Swift URLRequest with using following code.
var request = URLRequest(url: URL(string: Global.ip)!)
request.httpMethod = "POST"
request.addValue("application/x-www-form-urlencoded; charset=UTF-8", forHTTPHeaderField: "Content-Type")
let postString = "cmd=getFavorites" + "&ab={\"userId\":\"\(userId)\",\"favId\":\"\(favoriteId)\",\"favoriData\":\(panelData)}&token=\(token)"
let newPostString = postString.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)
request.httpBody = newPostString?.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else {
print("error=\(String(describing: error))")
completion(false)
return;
}
let json = JSON(data)
completion(true)
}
task.resume()

How can I convert a synchronous post request to an asynchronous post request?

As it's widely known that an asynchronous post request is better since the user won't get a perception that the app has "crashed" while it's loading the long process.
However, I'm not sure where to start to convert a synchronous post request to an asynchronous post request for a Swift code.
I have this code currently:
func checkLogin () {
let username:NSString = txtUsername.text! as NSString
let password:NSString = txtPassword.text! as NSString
do {
let post:NSString = "username=\(username)&password=\(password)" as NSString
NSLog("PostData: %#",post);
let url:URL = URL(string:"https://example.com/login.php")!
let postData:Data = post.data(using: String.Encoding.ascii.rawValue)!
let postLength:NSString = String( postData.count ) as NSString
let request:NSMutableURLRequest = NSMutableURLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = postData
request.setValue(postLength as String, forHTTPHeaderField: "Content-Length")
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
var reponseError: NSError?
var response: URLResponse?
var urlData: Data?
do {
urlData = try NSURLConnection.sendSynchronousRequest(request as URLRequest, returning:&response)
} catch let error as NSError {
reponseError = error
urlData = nil
}
if ( urlData != nil ) {
let res = response as! HTTPURLResponse!;
NSLog("Response code: %ld", res?.statusCode);
if ((res?.statusCode)! >= 200 && (res?.statusCode)! < 300) {
let responseData:NSString = NSString(data:urlData!, encoding:String.Encoding.utf8.rawValue)!
NSLog("Response ==> %#", responseData);
let jsonData:NSDictionary = try JSONSerialization.jsonObject(with: urlData!, options:JSONSerialization.ReadingOptions.mutableContainers ) as! NSDictionary
let success:NSInteger = jsonData.value(forKey: "success") as! NSInteger
NSLog("Success: %ld", success);
if(success == 1)
{
// do something, code removed
} else {
var error_msg:NSString
if jsonData["error_message"] as? NSString != nil {
error_msg = jsonData["error_message"] as! NSString
} else {
error_msg = "Unknown Error"
}
// show alert
}
}
}
}
}
First of all don't use NSURLConnection as it's deprecated now. Instead use NSURLSession.
You can simply use like this:
let task = URLSession.shared().dataTask(with: request) {
data, response, error in
if (data) {
} else {
print("error=\(error!.localizedDescription)")
}
}
task.resume()
You need to really make a lot of changes. Use swift type, instead of NSMutableURLRequest use URLRequest use String instead of NSString instead of NSDictionary & NSArray use Swift Dictionary and Array
func checkLogin () {
let username = txtUsername.text!
let password = txtPassword.text!
let post = "username=\(username)&password=\(password)"
NSLog("PostData: %#",post);
let url:URL = URL(string:"https://example.com/login.php")!
let postData = post.data(using: .utf8)!
let postLength = String( postData.count )
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = postData
request.setValue(postLength as String, forHTTPHeaderField: "Content-Length")
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
if error != nil {
return
}
if let jsonData = (try? JSONSerialization.jsonObject(with: data!, options: [])) as? [String:Any] {
let success = jsonData["success"] as! Int
if success == 1 {
//do something,
}
else {
//show alert
}
}
})
task.resume()
}

HTTP response is blank

I want to send dictionary data to server but server's POST response is showing blank.
func HitApi(callback: (NSDictionary) -> Void){
let mapDict = [ "1":"First", "2":"Second"]
let json = [ "title":"ABC" , "dict": mapDict ]
let jsonData:NSData?
do {
jsonData = try NSJSONSerialization.dataWithJSONObject(json, options: .PrettyPrinted)
}catch{
jsonData = nil
}
// create post request
let url = NSURL(string: "http://myserver.com")!
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
request.setValue("application/x-www-form-urlencoded; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.setValue("application/x-www-form-urlencoded; charset=utf-8", forHTTPHeaderField: "Accept")
request.HTTPBody = jsonData
var dict = ["output":""]
let task = NSURLSession.sharedSession().dataTaskWithRequest(request){ data,response,error in
if error != nil{
dict["output"] = "An error"
callback(dict)
}
do {
let data = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.AllowFragments) as? NSDictionary
dict["output"] = NSString(data: data!, encoding: NSUTF8StringEncoding)
callback(dict)
}catch{
dict["output"] = "error"
callback(dict)
}
}
task.resume()
}
If I use this code, then everything is going fine:
func HitApi(callback: (NSDictionary) -> Void){
let dataToSend:String = "1=First&2=Second"
let jsonData:NSData?
// create post request
let url = NSURL(string: "http://myserver.com")!
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
request.setValue("application/x-www-form-urlencoded; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.setValue("application/x-www-form-urlencoded; charset=utf-8", forHTTPHeaderField: "Accept")
request.HTTPBody = dataToSend.dataUsingEncoding(NSUTF8StringEncoding)
var dict = ["output":""]
let task = NSURLSession.sharedSession().dataTaskWithRequest(request){ data,response,error in
if error != nil{
dict["output"] = "An error"
callback(dict)
}
do {
let data = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.AllowFragments) as? NSDictionary
dict["output"] = NSString(data: data!, encoding: NSUTF8StringEncoding)
callback(dict)
}catch{
dict["output"] = "error"
callback(dict)
}
}
task.resume()
}
Now server is responding fine. But if i have big nested dictionary data then this method will be fail. What is problem in my first code?

sendSynchronousRequest is deprecated in ios 9 [duplicate]

This question already has an answer here:
Fixing NSURLConnection Deprecation from Swift 1.2 to 2.0
(1 answer)
Closed 7 years ago.
Xcode says that sendSynchronousRequest is now deprecated.
How should I replace it?
let postData:NSData = post.dataUsingEncoding(NSASCIIStringEncoding)!
let postLength:NSString = String( postData.length )
let request:NSMutableURLRequest = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
request.HTTPBody = postData
request.setValue(postLength as String, forHTTPHeaderField: "Content-Length")
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
var response: NSURLResponse?
var urlData: NSData?
do {
urlData = try NSURLConnection.sendSynchronousRequest(request, returningResponse:&response)
} catch _ as NSError {
urlData = nil
} catch {
fatalError()
}
This is a working example,
You should use NSURLSession, with Request.
func testPost(sender: UIButton) {
let session = NSURLSession.sharedSession()
let request = NSMutableURLRequest(URL: NSURL(string: "http://localhost:8080/iOSServer/ios/helloworld/swiftCalculator")!)
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.HTTPMethod = "POST"
let d = "4"
let data = "x=4&y=\(d)"
request.HTTPBody = data.dataUsingEncoding(NSASCIIStringEncoding)
let task = session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
if let error = error {
print(error)
}
if let data = data{
print("data =\(data)")
}
if let response = response {
print("url = \(response.URL!)")
print("response = \(response)")
let httpResponse = response as! NSHTTPURLResponse
print("response code = \(httpResponse.statusCode)")
//if you response is json do the following
do{
let resultJSON = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions())
let arrayJSON = resultJSON as! NSArray
for value in arrayJSON{
let dicValue = value as! NSDictionary
for (key, value) in dicValue {
print("key = \(key)")
print("value = \(value)")
}
}
}catch _{
print("Received not-well-formatted JSON")
}
}
})
task.resume()
}
Notice it is not necessary to use the request. you can have a data task with URL, but I added the request because in your code, you have set some headers in the request.
Notice using the completionHandler which will be called when your server responses by http response.

session.dataTaskWithURL is not executing in proper sequence

I am calling Web service.
In that method session.dataTaskWithURL is calling after some time.I think it is not giving in proper thread?
my code below
——--------------
func callService(usr: String, pwdCode: String) ->Bool
{
var resultPage=false
let url = NSURL(string: "demourl")
var xmlParse:NSString = ""
var data : NSData!
println("Before request *****************")
let config = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession(configuration: config)
session.dataTaskWithURL(url!,
completionHandler: {(data, response, error) in
let request = NSMutableURLRequest(URL: url!)
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.HTTPMethod = "POST"
let dictionary = ["email": usr, "userPwd": pwdCode] as NSDictionary
var error: NSError?
if let body = NSJSONSerialization.dataWithJSONObject(dictionary, options: nil, error: &error) {
request.HTTPBody = body
}
else
{
println("JSON error: \(error)")
}
let xmlParse=NSString(data: data, encoding: NSUTF8StringEncoding)!
if data == nil {
println("dataTaskWithRequest error: \(error)")
return
}
let parser = NSXMLParser(data: data)
parser.delegate = self
resultPage=parser.parse()
println("******** boolVal \(resultPage)")
}).resume()
println("After request *****************")
println("resultPage Final \(resultPage)")
return resultPage;
}
Can you please help me if we can execute my method "session.dataTaskWithURL(url!,
completionHandler: {(data, response, error) in " in a proper sequence???
Thanks in advance.
var resultPage=false
let url = NSURL(string: "URL")
var xmlParse:NSString = ""
var data : NSData!
let request = NSMutableURLRequest(URL: url!)
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.HTTPMethod = "POST"
let dictionary = ["email": base64String, "userPwd": base64StringPwd] as NSDictionary
var error: NSError?
if let body = NSJSONSerialization.dataWithJSONObject(dictionary, options: nil, error: &error) {
request.HTTPBody = body
} else {
println("JSON error: \(error)")
}
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
(data, response, error) in
println(NSString(data: data, encoding: NSUTF8StringEncoding))
let xmlParse=NSString(data: data, encoding: NSUTF8StringEncoding)!
if data == nil {
println("dataTaskWithRequest error: \(error)")
return
}
let parser = NSXMLParser(data: data)
println("parser \(parser)")
parser.delegate = self
resultPage=parser.parse()
if self.success==false
{
println("success \(self.success)")
self.lblMessage.hidden=false
}
}
task.resume()

Resources