Due to background processing, the order of operation of the functions below has changed and the return value of the functions is not expected.
let task=NSURLSession.sharedSession().dataTaskWithRequest......
This line and beyond are skipped and the function is terminated.
Could you tell me how to improve it?
This is the way to use Post.Alternatives are fine.
The code was too old, so I modified it to work properly except for the HTTP address.
In the following case, the print output order is "NG" ->HTML code.Correct HTML code ->"OK"
Thank you for your cooperation.
import UIKit
classViewController:UIViewController, NSURLSessionDelegate, NSURLSessionDataDelegate {
override func viewDidLoad(){
super.viewDidLoad()
// Do any additional setup after loading the view, typically from anib.
print(Test())
}
override funcdidReceiveMemoryWarning(){
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func Test() - > String {
let post="name=Masuda&addr=Tokyo"
let postdata=post.dataUsingEncoding (NSShiftJISStringEncoding)!
let url = NSURL (string: "http://moonmile.net/ios9/post.php")
let req = NSMutableURLRequest (URL: url!)
req.HTTPMethod="POST"
req.setValue("application/x-www-form-urlencoded", for HTTPHeaderField: "Content-Type")
let length = postdata.length
req.setValue("\(length)" for HTTPHeaderField: "Content-Length")
req.HTTPBody=postdata
var textBuf: String = "NG"
let task = NSURLSession.sharedSession().dataTaskWithRequest(req, completionHandler: {
(data, res, err) in
if data!=nil{
let text = NSSstring(data:data!, encoding:NSShiftJISStringEncoding)
print(NSString(data:data!, encoding:NSShiftJISStringEncoding))
dispatch_async(dispatch_get_main_queue(), {
textBuf="OK"
})
}
})
task.resume()
return textBuf
}
}
"Waiting for termination" is a wrong solution just because asynchronous processing results are not immediately available.While waiting in a simple loop for an exit is a no-brainer, if you continue to wait for an unspecified amount of time in the expected method called by the main thread, as in this example, the main thread will slow down and compromise usability.
When writing code that uses asynchronous processing, you should remember the following principles:
1. The method that invokes asynchronous processing cannot return the result of the processing
2. After starting asynchronous processing, do nothing in that method anymore
3. Asynchronous processing results must be handled in the completion handler
In the case of real apps, it is inconceivable to simply print the contents of the String, so if you want to make it a generic method, one way is to have your method have a completion handler that passes the result as an argument instead of returning it as a return value.
If you rewrite the original example you gave me, it looks like this
import UIKit
classViewController:UIViewController, NSURLSessionDelegate, NSURLSessionDataDelegate {
override func viewDidLoad(){
super.viewDidLoad()
// Do any additional setup after loading the view, typically from anib.
Test({(result:String)->Void in// Asynchronous processing results must be handled in the completion handler
print(result)
})
}
override funcdidReceiveMemoryWarning(){
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func Test(completionHandler:(String)->Void) {// Make your own method have a completion handler as well
let post="name=Masuda&addr=Tokyo"
let postdata=post.dataUsingEncoding (NSShiftJISStringEncoding)!
let url = NSURL (string: "http://moonmile.net/ios9/post.php")
let req = NSMutableURLRequest (URL: url!)
req.HTTPMethod="POST"
req.setValue("application/x-www-form-urlencoded", for HTTPHeaderField: "Content-Type")
// Content-Length is not required when HTTPBody is specified in NSData
req.HTTPBody=postdata
var textBuf: String = "NG"
let task = NSURLSession.sharedSession().dataTaskWithRequest(req, completionHandler: {
(data, res, err) in
if data!=nil{
let text = String (data:data!, encoding:NSShiftJISStringEncoding)
print(text)
dispatch_async(dispatch_get_main_queue(), {
textBuf="OK"
completionHandler(textBuf) // Call your own completion handler in the completion handler
})
}
})
task.resume()
// Do nothing in the method after starting asynchronous processing
}
}
I don't think I've ever seen (in iOS and other programs) a way of writing where you wait for a button to be pressed in a loop like while!isButtonPressed{/*...*/}
.(I used to do it normally when programming a one-board microcomputer a long time ago...) For asynchronous processing with communication, please learn a proper asynchronous processing pattern instead of waiting for it to be processed.
The following code is the resolved code.
import UIKit
classViewController:UIViewController, NSURLSessionDelegate, NSURLSessionDataDelegate {
var waiting = true // Add
override func viewDidLoad(){
super.viewDidLoad()
// Do any additional setup after loading the view, typically from anib.
print(Test())
}
override funcdidReceiveMemoryWarning(){
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func Test() - > String {
let post="name=Masuda&addr=Tokyo"
let postdata=post.dataUsingEncoding (NSShiftJISStringEncoding)!
let url = NSURL (string: "http://moonmile.net/ios9/post.php")
let req = NSMutableURLRequest (URL: url!)
req.HTTPMethod="POST"
req.setValue("application/x-www-form-urlencoded", for HTTPHeaderField: "Content-Type")
let length = postdata.length
req.setValue("\(length)" for HTTPHeaderField: "Content-Length")
req.HTTPBody=postdata
var textBuf: String = "NG"
let task = NSURLSession.sharedSession().dataTaskWithRequest(req, completionHandler: {
(data, res, err) in
if data!=nil{
let text = NSSstring(data:data!, encoding:NSShiftJISStringEncoding)
print(NSString(data:data!, encoding:NSShiftJISStringEncoding))
dispatch_async(dispatch_get_main_queue(), {
textBuf="OK"
waiting = false // Add
})
}
})
task.resume()
// Add
while (waiting) {
NSRunLoop.currentRunLoop().runMode(NSDefaultRunLoopMode, beforeDate:NSDate())
}
return textBuf
}
}
© 2024 OneMinuteCode. All rights reserved.