How to stop task or section from NSURLSession - ios

I am Using NSURLSession for call an post API, but when i turn of the wifi and then hit the web service and again turn on the wifi NSURLSession is calling that previously call web service, i want to stop this process. i read on some of documents that NSURLSession store the section of every service call when connection break in any situation , and again hit that service when connection established again. So now i am not getting any solution to stop that service call after connection reconnect to my device.
Any one please help me. Thanks in advance.
Below is my code i used.
let token: NSString!
let urlPath: NSURL!
if provider .isEqualToString("No"){
urlPath = NSURL(string: kAPI_SERVERBASEURL + (url as String))
}
else{
urlPath = NSURL(string: kAPI_SERVERBASEURLSEARCHPROVIDER + (url as String))
}
var postJsonData = NSData()
var jsonString = NSString()
do {
postJsonData = try NSJSONSerialization.dataWithJSONObject(dictRequest, options:[])
jsonString = NSString(data: postJsonData, encoding: NSUTF8StringEncoding)!
NSLog("request - %#", jsonString);
// do other stuff on success
} catch {
print("JSON serialization failed: \(error)")
}
let request = NSMutableURLRequest(URL: urlPath);
request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalCacheData
request.HTTPShouldHandleCookies = false
request.timeoutInterval = 120 ;
request.HTTPMethod = "POST";
if NSUserDefaults.standardUserDefaults().valueForKey(kAccessToken) != nil{
token = NSUserDefaults.standardUserDefaults().valueForKey(kAccessToken) as! NSString
//token = "tk_1vNoEoZRxJwY"
request.setValue("\(token)", forHTTPHeaderField: "access_token")
}
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.HTTPBody = postJsonData
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(request) { (data:NSData?, response:NSURLResponse?, error:NSError?) -> Void in
`

It may help you.
1.Declare one variable about the NSURLSessionTask like
var task: NSURLSessionTask? = nil
2.When ever you need to call dataTaskWithRequest assign the object to declared object like
task = NSURLSession.sharedSession().dataTaskWithURL(NSURL(fileURLWithPath: ""))
3.when you want to cancel the request just do the below.
if nil != task {
task!.cancel()
task = nil
}
Suppose you want cancel the request before calling another one combine both 2 and 3 steps like
if nil != task {
task!.cancel()
task = nil
}
task = NSURLSession.sharedSession().dataTaskWithURL(NSURL(fileURLWithPath: ""))

Related

Swift : HttpRequest works on Simulator but not on Device (iPhone 11)

I have an Authentication Manager that send SignIn and SignUp request. Code works good on simulator and fetch data from database but not working on device. On device It gives http 500 error. I check the textfields before sending the request and they seem fine.
Any suggestions to solve this issue ?
func performSignIn(email: String, password: String){
//1. Create URL
if let url = URL(string: Constants.signInURL){
var request = URLRequest(url: url)
//Request Body
var body = [String : Any]()
body["user"] = ["email": email,
"password": password]
do {
request.httpBody = try JSONSerialization.data(withJSONObject: body, options: [])
} catch {
print("JSON serialization failed: \(error)")
}
// Change the URLRequest to a POST request
request.httpMethod = "POST"
//Need to tell that request has json in body.
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
//2. Create URLSession
let session = URLSession(configuration: .default)
//3. Give Session a task
let task = session.dataTask(with: request) { (data, response, error) in
if error != nil{
DispatchQueue.main.async {
delegate?.failedWithError(error: error!)
return
}
}
if let safeData = data{
if let signInResponse = parseJSON(safeData){
//Who has the delegate run signInSuccess method
delegate?.signInSuccess(signInResponse)
}
}
}
//4. Start Task
task.resume()
}
}

Where do I specify ReloadIgnoringLocalCacheData for NSURLSession in Swift 2

I have an app that makes an API call every 5 seconds using NSURLSession and p2-oauth2. I'm running into an issue of it returning cached data instead of the updated information from the API. I read this post by Matt Thompson where he describes the different cache policies, the one I think I need to use is ReloadIgnoringLocalCacheData. I think it's suppose to be put in the AppDelegate DidFinishLaunchingWithOptions functions. But, the problem I'm having is I don't know where or how to specify it. I haven't found any Swift solutions. Can anyone tell me what my function should say?
If it's helpful, here is my API request:
let urlPath = "https://sandbox-api.uber.com/v1/requests/\(uberRequestId)"
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
guard let endpoint = NSURL(string: urlPath) else { print("Error creating endpoint");return }
let request = appDelegate.oauth.request(forURL: NSURL(string:urlPath)!)
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.HTTPMethod = "GET"
//get response from Uber and iterate through to find Uber Product ID.
NSURLSession.sharedSession().dataTaskWithRequest(request) { (data, response, error) -> Void in
do {
guard let dat = data else { throw JSONError.NoData }
let result = try NSJSONSerialization.JSONObjectWithData(dat, options: NSJSONReadingOptions.MutableContainers)
print(result)
//set status
status = result["status"] as! String
print("found status...returning it back -> \(status)")
completion(status: "\(status)")
} catch let error as JSONError {
print(error.rawValue)
print("ERROR NEEDS TO BE HANDLED.")
} catch {
print(error)
print("ERROR NEEDS TO BE HANDLED.")
}
}.resume()
Here is the final request that properly sets the cache policy. I added one line with ReloadIgnoringLocalCacheData.
let urlPath = "https://sandbox-api.uber.com/v1/requests/\(uberRequestId)"
let url:NSURL = NSURL(string: urlPath)!
let session = NSURLSession.sharedSession()
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let request = appDelegate.oauth.request(forURL: NSURL(string:urlPath)!)
request.HTTPMethod = "GET"
//added this line to set cache policy
request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalCacheData
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
let task = session.dataTaskWithRequest(request) {
(
let data, let response, let 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()
Assuming the OAuth API returns a mutable request, you can set its cachePolicy property to NSURLRequestCachePolicy.ReloadIgnoringCacheData.

HTTP POST function

I'm trying to use a POST function to take text from a label and send it as an email. The problem is, whenever I try and use the text from the label, the only data in the email is []
Any ideas as to what might be wrong?
Code:
func postToServerFunction() {
var userText : String = labelText.text!
var url: NSURL = NSURL(string: "http://www.webaddress.com/email_test.php")!
var request:NSMutableURLRequest = NSMutableURLRequest(URL:url)
var bodyData = userText
request.HTTPMethod = "POST"
request.HTTPBody = bodyData.dataUsingEncoding(NSUTF8StringEncoding);
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue())
{
(response, data, error) in
println(response)
}
}
Edit:
With this code I now get {""} in the email:
func postToServerFunction() {
var emailText = labelText
var url: NSURL = NSURL(string: "http:www.webaddress.com/email_test.php")!
var request:NSMutableURLRequest = NSMutableURLRequest(URL:url)
var bodyData = "\(emailText)"
request.HTTPMethod = "POST"
request.HTTPBody = bodyData.dataUsingEncoding(NSUTF8StringEncoding);
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue())
{
(response, data, error) in
println(response)
}
}
This API is deprecated in iOS9. Probably the easiest way to do this is by using Alamofire (https://github.com/Alamofire/Alamofire)
If you still wanted to use this API, then you should use the 'data' object.
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue())
{
(response, data, error) in
let strData = String(data, NSUTF8StringEncoding)
print(strData)
}
so this way you are initiating string instance from the NSData returned.
Please don't use NSURLConnection, as noted by other it's deprecated. If you don't want to depend on external libraries (Alamofire) use NSURLSession instead.
guard let url = NSURL(string: "http://www.webaddress.com/email_test.php") else {
print("bad url")
return
}
let session = NSURLSession(configuration: NSURLSessionConfiguration.ephemeralSessionConfiguration())
let request = NSMutableURLRequest(URL:url)
request.HTTPMethod = "POST"
request.HTTPBody = "Some Text".dataUsingEncoding(NSUTF8StringEncoding);
let post = session.dataTaskWithRequest(request) { data, response, error in
guard let data = data, let response = response where error == nil else {
print("Connection error")
return
}
let strData = String(data, NSUTF8StringEncoding)
print(strData)
}
post.resume()

How to securely pass variables to PHP script from Swift application, or make this code more secure

I am using NSURL to call a PHP script that interacts with with a MySQL database. I am passing the variables through the URL, which can be intercepted and hacked. Is there any way to pass form data with Swift, or securely pass variables to a URL using a similar structure that I have now? I have completed the application only to realize this vulnerability. If there is no way to alter this code, I guess I will have to rewrite a bunch... Here is the structure code I have:
let username = "bob"
let myUrl = NSURL(string: "http://127.0.0.1/phpscript.php?username=\(username)")
let request = NSMutableURLRequest(URL: myUrl!)
request.HTTPMethod = "POST"
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
data, response, error in
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)) {
let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
if error != nil {
print("Error: \(error)")
}
dispatch_async(dispatch_get_main_queue()) {
self.testLabel.text = "\(responseString!)"
}
}
}
task.resume()
As you can see, it would be simple to gather the username just by seeing the URL. Do you know of a way to pass variables other than through the URL, without having to rewrite all of this code?Thank you very much
You could pass username through post by adding between ..."POST" and let task... this code:
let postString = "username=\(username)"
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
end result:
let username = "bob"
let myUrl = NSURL(string: "http://127.0.0.1/phpscript.php")
let request = NSMutableURLRequest(URL: myUrl!)
request.HTTPMethod = "POST"
let postString = "username=\(username)"
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
data, response, error in
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)) {
let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
if error != nil {
print("Error: \(error)")
}
dispatch_async(dispatch_get_main_queue()) {
self.testLabel.text = "\(responseString!)"
}
}
}
task.resume()

How can i force method to wait until a callback finishes on swift?

I'm trying to make an http post request,
but the method returns before the dictionary get's filled.
How can i force the method to wait for the callback?
func makeRequest()-> [String :AnyObject]{
var ans : [String :AnyObject] = ["response" : "", "data" : "", "error" : ""]
var request = NSMutableURLRequest(URL: NSURL(string: self.url)!, cachePolicy: NSURLRequestCachePolicy.ReloadIgnoringLocalCacheData, timeoutInterval: 5)
if self.jsonIcluded {
var err: NSError?
let req = NSJSONSerialization.dataWithJSONObject(self.data!, options: NSJSONWritingOptions.PrettyPrinted, error: &err)
request.HTTPBody = req
}
request.HTTPMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
data, response, error in
if error != nil
{
println("error=\(error)")
return
}
ans["response"] = response
ans["data"] = data
ans["error"] = error
}
task.resume()
return ans
}
NSURLSession is used to make asynchronous requests. If you want to send synchronous requests then use the NSURLConnection -sendSynchronousRequest: method.
let reply = NSURLConnection.sendSynchronousRequest(request, returningResponse:&response, error:&error)
return reply

Resources