ios - Swift 函数在完成处理之前返回值

标签 ios swift function swift3 nsurlsession

<分区>

基本上我有一个用于将简单数据发布到服务器的代码,如果发布请求成功,它将返回一个 bool 值 success 但它似乎是在数据之前返回 bool 值已处理,我做错了什么吗?

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
    }

最佳答案

发生这种情况是因为函数直接返回success 的值,dataTask 工作异步,所以函数不应该等到dataTask完成解析编辑success的值,即:return successdataTask编辑值之前执行成功

我建议让函数处理一个完成闭包,而不是直接返回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 中的代码。

关于ios - Swift 函数在完成处理之前返回值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40829647/

相关文章:

c++ - 在函数调用中使用构造函数?

c - 这是什么c函数?

ios - swift 从 UInt8 转换为 String

ios - CGlayer 绘图性能低下

ios - UITextField TapGesture 在 iOS 7.1 上没有响应

function - 函数的 Kotlin 类型不匹配返回字符串

ios - UITextView 结合了文本和图像

swift - makeFirstResponder : does not always take cursor

ios - 如何使用firebase实时数据库ios增加特定节点中的值

ios - UITableViewCell 之间的随机空间?可以看穿分隔符