I created a code that request information to webservice, the user typing the word and the app request the information, the webservice return a json. The code worked ok. But I use search bar and a schedule time, when the user stoped to type, the information is requested.
The problem is, if the app request information and the user start typing again the app finish the first request and after request the second information. I need that, when the user request again, the app kill the first request and start second request. Is it possible?
this is the example:
var lastScheduledSearch: NSTimer?
@IBOutlet weak var searchBar: UISearchBar!
..
func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {
lastScheduledSearch?.invalidate() /
lastScheduledSearch = NSTimer.scheduledTimerWithTimeInterval(1.5, target: self, selector: "startSearching:", userInfo: searchText, repeats: false)
}
func startSearching(timer: NSTimer) {
let searchText = timer.userInfo as! String
search(searchText)
}
func search(searchText: String) {
let operation = NSBlockOperation()
operation.addExecutionBlock {
self.dataController.find(searchText){jsonData, error in
if let json: AnyObject! = jsonData {
self.data = json as! NSArray
dispatch_async(dispatch_get_main_queue()) {
self.tableView.reloadData()
}
}
}
}
currentOperation = operation
operationQueue.addOperation(currentOperation!)
}
//class that request json to webservice
func find(search: String,completion: (jsonData: NSArray?, error: NSError?)->Void){
var jsonData:NSArray = []
let post:NSString = "data=\(search)"
let url:NSURL = NSURL(string: links_web.find() as String)!
let postData:NSData = post.dataUsingEncoding(NSUTF8StringEncoding)!
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")
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(request) {urlData, response, reponseError in
if let receivedData = urlData {
let res = response as! NSHTTPURLResponse!;
NSLog("Response code: %ld", res.statusCode);
if 200..<300 ~= res.statusCode {
do {
jsonData = try NSJSONSerialization.JSONObjectWithData(receivedData, options: []) as! NSArray
/
completion(jsonData: jsonData, error: nil)
} catch let error as NSError {
completion(jsonData: nil, error: returnedError)
}
} else {
completion(jsonData: nil, error: returnedError)
}
} else {
var userInfo: [NSObject: AnyObject] = [
"title": "Error!",
"message": "Conection fail"
]
if let error = reponseError {
userInfo["message"] = error.localizedDescription
userInfo["cause"] = error
}
let returnedError = NSError(domain: ".", code: 2, userInfo: userInfo)
/
completion(jsonData: nil, error: returnedError)
}
}
task.resume()
}
You need to call
cancel()
on your NSURLSessionDataTask object, that is, the thing you got back from
dataTaskWithRequest(xxx)
. Right now you can’t do that because you’re storing your only reference to that object in
task
, which is a local variable. junkpile is recommending that you put it into a property (perhaps
currentTask
) at which point you can call
cancel
on it before starting a new task.
IMPORTANT A cancelled task still completes, just with an error. You should check for that error. Also, you’ll want some sort of serialisation to ensure that you don’t commit results from a cancelled task. Given that your results will eventually be committed to the UI (which is main thread only) your commit serialisation could be as simple as bouncing over to the main thread.
Also, I’m going to point you to a technote I wrote about this, Technote 2109 Simple and Reliable Threading with NSOperation and its associated ListAdder sample code. While it’s cast in terms of NSOperation, many of the same problems, and solutions, apply when you use NSURLSession like this.
Share and Enjoy
—
Quinn "The Eskimo!"
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
let myEmail = "eskimo" + "1" + "@apple.com"