我尝试用swift 3创建我的第一个项目。
我尝试从我的API中获取数据。如果我手动启动这个函数,效果会很好。我需要同步异步请求。
我需要触发我的函数3次,然后等待其他函数完成。
makeGetCall(URLstring: "api1")等待完成
makeGetCall(URLstring: "api2")等待完成
makeGetCall(URLstring: "api3") 将其设置为background并每5秒触发一次。
func makeGetCall(URLstring: String, update: Bool) {
let completeURL = "http://myapi/" + URLstring
// Set up the URL request
guard let url = URL(string: completeURL) else {
print("Error: cannot create URL")
return
}
let urlRequest = URLRequest(url: url)
// set up the session
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
// make the request
let task = session.dataTask(with: urlRequest) {
(data, response, error) in
// check for any errors
guard error == nil else {
print("error calling GET on /todos/1")
print(error as Any)
return
}
// make sure we got data
guard let responseData = data else {
print("Error: did not receive data")
return
}
// parse the result as XML
if URLstring == "devicelist.cgi" {
self.readDevice(XMLData: responseData)
}
if URLstring == "statelist.cgi" {
self.readDeviceData(XMLData: responseData, update: update)
}
if URLstring == "functionlist.cgi" {
self.readGewerke(XMLData: responseData)
}
}
task.resume()
}有人能帮帮忙吗。
黑根
这是我在完成处理程序中尝试过的:
override func viewDidLoad() {
super.viewDidLoad()
makeGetCall(input: "statelist.cgi") {
(result: Bool) in
print("finished statelist")
}
makeGetCall(input: "devicelist.cgi") {
(result: Bool) in
print("finished devicelist")
}
makeGetCall(input: "functionlist.cgi") {
(result: Bool) in
print("finished functionlist")
}
}
func makeGetCall(input: String, completion: @escaping (_ result: Bool) -> Void) {
let completeURL = "http://192.168.0.25/addons/xmlapi/" + input
// Set up the URL request
guard let url = URL(string: completeURL) else {
print("Error: cannot create URL")
return
}
let urlRequest = URLRequest(url: url)
// set up the session
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
// make the request
let task = session.dataTask(with: urlRequest) {
(data, response, error) in
// check for any errors
guard error == nil else {
print("error calling GET on /todos/1")
print(error as Any)
return
}
// make sure we got data
guard data != nil else {
print("Error: did not receive data")
return
}
completion(true)
}
task.resume()
}如果我把这3个调用放在一起,它就会正常工作。我认为它也应该与GCD一起工作,但大多数例子都是针对swift 2的。
makeGetCall(input: "devicelist.cgi") {
(result: Bool) in
print("finished devicelist")
self.makeGetCall(input: "functionlist.cgi") {
(result: Bool) in
print("finished functionlist")
self.makeGetCall(input: "statelist.cgi") {
(result: Bool) in
print("finished statelist")
}
}
}也许现在有人能帮上忙了。
谢谢黑根
发布于 2017-02-14 03:45:20
当发生某些事情时,使用DispatchGroup来获得通知。
override func viewDidLoad() {
super.viewDidLoad()
let stateListGroup = DispatchGroup()
stateListGroup.enter()
makeGetCall(input: "statelist.cgi") {
(result: Bool) in
print("finished statelist")
stateListGroup.leave()
}
let deviceListGroup = DispatchGroup()
deviceListGroup.enter()
// the notify closure is called when the (stateList-) groups enter and leave counts are balanced.
stateListGroup.notify(queue: DispatchQueue.main) {
self.makeGetCall(input: "devicelist.cgi") {
(result: Bool) in
print("finished devicelist")
deviceListGroup.leave()
}
}
let functionListGroup = DispatchGroup()
functionListGroup.enter()
deviceListGroup.notify(queue: DispatchQueue.main) {
self.makeGetCall(input: "functionList") {
(result: Bool) in
print("finished functionlist")
functionListGroup.leave()
}
}
functionListGroup.notify(queue: DispatchQueue.main) {
print("update ui here")
}
}打印:
statelist.cgi
finished statelist
devicelist.cgi
finished devicelist
functionList
finished functionlist
update ui here还要记住,session.dataTask()的完成处理程序是在后台队列上调用的,因此我建议在主队列上调度completion(true),以避免意外行为:
DispatchQueue.main.async {
completion(true)
}https://stackoverflow.com/questions/42146274
复制相似问题