基本上我有一个用于将简单数据发布到服务器的代码,如果post请求成功,它将返回一个布尔值success
但似乎是在处理数据之前返回了布尔值,我做错了什么?
public func postRequest(rawText: String) -> Bool {
var success = true
let destUrl = "http://api.getquesto.com:8080/upload/"
var request = URLRequest(url: URL(string: destUrl)!)
request.httpMethod = "POST"
let postString = rawText
request.setValue("text/plain", forHTTPHeaderField: "Content-Type")
// request.setValue("compute", forHTTPHeaderField: "Questo-Query")
// request.setValue("Fuck you", forHTTPHeaderField: "quizTitle")
request.httpBody = postString.data(using: .utf8)
print(request.httpBody!)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else { // check for fundamental networking error
print("error=\(error)")
success = false
print(success)
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { // check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(response)")
}
let responseString = String(data: data, encoding: .utf8)
do {
if let json = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions(rawValue: UInt(0))) as? [String: Any] {
print("json \(json)")
} else {
print("can not cast data")
success = false
}
} catch let error {
print("cant parse json \(error)")
success = false
print(success)
}
print("responseString = \(responseString)")
let dataString = NSString(data: data, encoding: String.Encoding.utf8.rawValue)
//print(dataString)
//print("responseString = \(responseString)")
constantVariables.rawQuestionData = dataString as! String
let processedResults = dataString?.replacingOccurrences(of: "\\n", with: " ")
print("processed results = " + (processedResults! as String))
let newArray = processedResults!.components(separatedBy: ", \"")
//print(newArray)
for index in 0...(newArray.count - 1) {
if index%2 == 0 {
constantVariables.questions.insert(newArray[index].replacingOccurrences(of: "\"", with: "").replacingOccurrences(of: "]", with: "").replacingOccurrences(of: "[", with: ""), at: index/2)
// ConstantsArray.questionArray.append(newArray[index])
// print("question array: " + ConstantsArray.answerArray[index/2])
}else{
constantVariables.answers.insert(newArray[index].replacingOccurrences(of: "\"", with: "").replacingOccurrences(of: "]", with: "").replacingOccurrences(of: "[", with: ""), at: (index-1)/2)
// ConstantsArray.questionArray.append(newArray[index])
print("answer array: " + constantVariables.answers[(index-1)/2])
}
}
}
task.resume()
print(success)
return success
}
答案 0 :(得分:4)
这种情况正在发生,因为函数直接返回success
的值,dataTask
异步,因此,函数不应该等到dataTask
完成解析以编辑success
的值,即return success
在dataTask
编辑success
的值之前执行。
我建议让该函数处理 completion
闭包,而不是直接返回Bool
。
您的功能应类似于:
public func postRequest(rawText: String, completion: @escaping (_ success: Bool) -> ()) {
var success = true
let destUrl = "http://api.getquesto.com:8080/upload/"
var request = URLRequest(url: URL(string: destUrl)!)
request.httpMethod = "POST"
let postString = rawText
request.setValue("text/plain", forHTTPHeaderField: "Content-Type")
// request.setValue("compute", forHTTPHeaderField: "Questo-Query")
// request.setValue("Fuck you", forHTTPHeaderField: "quizTitle")
request.httpBody = postString.data(using: .utf8)
print(request.httpBody!)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else { // check for fundamental networking error
print("error=\(error)")
success = false
print(success)
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { // check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(response)")
}
let responseString = String(data: data, encoding: .utf8)
do {
if let json = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions(rawValue: UInt(0))) as? [String: Any] {
print("json \(json)")
} else {
print("can not cast data")
success = false
}
} catch let error {
print("cant parse json \(error)")
success = false
print(success)
}
print("responseString = \(responseString)")
let dataString = NSString(data: data, encoding: String.Encoding.utf8.rawValue)
//print(dataString)
//print("responseString = \(responseString)")
constantVariables.rawQuestionData = dataString as! String
let processedResults = dataString?.replacingOccurrences(of: "\\n", with: " ")
print("processed results = " + (processedResults! as String))
let newArray = processedResults!.components(separatedBy: ", \"")
//print(newArray)
for index in 0...(newArray.count - 1) {
if index%2 == 0 {
constantVariables.questions.insert(newArray[index].replacingOccurrences(of: "\"", with: "").replacingOccurrences(of: "]", with: "").replacingOccurrences(of: "[", with: ""), at: index/2)
// ConstantsArray.questionArray.append(newArray[index])
// print("question array: " + ConstantsArray.answerArray[index/2])
}else{
constantVariables.answers.insert(newArray[index].replacingOccurrences(of: "\"", with: "").replacingOccurrences(of: "]", with: "").replacingOccurrences(of: "[", with: ""), at: (index-1)/2)
// ConstantsArray.questionArray.append(newArray[index])
print("answer array: " + constantVariables.answers[(index-1)/2])
}
}
completion(success)
}
task.resume()
print(success)
}
在Swift 3中,您应该使用@escaping
,有关详细信息,您可能需要查看this answer。
通话:
postRequest(rawText: "rawText", completion: { success in
print(success)
})
现在,它应该等到dataTask
完成它的解析,然后,completion
中的代码将被调用。
希望它有所帮助。