I'm writing a program that retrieves values from a database and displays it on the UI. The retrieval step executes asynchronously and as a result the result box gets updated before the db results come back. Right now I can get it to work by using a NSThread.sleepForTimeInterval(time) above the "ResultBox.text = globaldbresults" but I know that is a bad way to do it since the retrieval time will vary depending on the size of the retrieval etc. I much prefer to ensure a block (the UI textfield update) only runs after the retrieve has completed.
I've tried using dispatch_group_wait but I think I'm using it wrong.
[In AppDelegate.swift]
var globaldbresults
@UIApplicationMain
[END In Appdelegate.swift]
import UIKit
import Dispatch
class ViewController: UIViewController {
dbGetqueue = dispatch_group_create()
@IBAction func goClicked(sender: AnyObject) {
dispatch_group_enter(dbGetqueue)
mysqlget(Room1num, num2: Room2num)
dispatch_group_leave(dbGetqueue)
dispatch_group_wait(dbGetqueue, 5)
ResultBox.text = globaldbresults
}
func mysqlget(num1 :Int, num2 :Int) {
let myUrl = NSURL(string: "http://localhost/iOS_PHP_MySQL.php")
let myGetTask = NSURLSession.sharedSession().dataTaskWithRequest(myRequest, completionHandler: {(reqData, reqResponse, reqError) -> Void in
dbresults = (NSString(data: reqData, encoding: NSUTF8StringEncoding)!)
globaldbresults = String(dbresults)
})
myGetTask.resume()
}
}
I've just put the relevant lines of code. The globaldbresults which is bad way to deal with one of my problem solves the scope issue which occurs if I try to directly reference dbresults from my goClicked Action.
I would it should be:
dispatch_group(dbGetqueue) {
block to execute
}
[Some other code not dependent on block above]
dispatch_group_wait(dbGetqueue) {
code that doesn't start till dbGetqueue finished
}
but that is obviously not the case.
If you have only one request to get desired data this could be solved by a simple callback closure.
But if you want to do it with dispatch_group_ way here it could be done:
class ViewController: UIViewController {
dbGetqueue = dispatch_group_create()
@IBAction func goClicked(sender: AnyObject) {
mysqlget(Room1num, num2: Room2num)
dispatch_group_notify(dbGetqueue,dispatch_get_main_queue(),{
self.ResultBox.text = globaldbresults
})
}
func mysqlget(num1 :Int, num2 :Int) {
dispatch_group_enter(dbGetqueue) //Enter group here
let myUrl = NSURL(string: "http://localhost/iOS_PHP_MySQL.php")
let myGetTask = NSURLSession.sharedSession().dataTaskWithRequest(myRequest, completionHandler: {(reqData, reqResponse, reqError) -> Void in
dbresults = (NSString(data: reqData, encoding: NSUTF8StringEncoding)!)
globaldbresults = String(dbresults)
dispatch_group_leave(self.dbGetqueue) //Leave group when you are done getting results.
})
myGetTask.resume()
}
Another way of doing without dispatch_group_ is
class ViewController: UIViewController {
dbGetqueue = dispatch_group_create()
@IBAction func goClicked(sender: AnyObject) {
mysqlget(Room1num, num2: Room2num)
}
func mysqlget(num1 :Int, num2 :Int) {
let myUrl = NSURL(string: "http://localhost/iOS_PHP_MySQL.php")
let myGetTask = NSURLSession.sharedSession().dataTaskWithRequest(myRequest, completionHandler: {(reqData, reqResponse, reqError) -> Void in
dbresults = (NSString(data: reqData, encoding: NSUTF8StringEncoding)!)
globaldbresults = String(dbresults)
dispatch_async(dispatch_get_main_queue(), {
self.self.ResultBox.text = globaldbresults
})
})
myGetTask.resume()
}
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.