2016-11-27 5 views
1

В принципе, у меня есть код для отправки простых данных на сервер и будет возвращать логическое значение 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 
    } 
+2

'URLSessionDataTask' является асинхронным, когда вы вызываете' resume() 'ваш код будет продолжен, а задача запускается в двух параллельных потоках. Если вы хотите, чтобы он был синхронным, сделайте расширение с кодом, подобным этому: http://stackoverflow.com/a/34308158/2122979 – Ossir

+0

Другие похожие вопросы с ответами: http://stackoverflow.com/questions/40810108/swift -http-request-use-urlsession, http://stackoverflow.com/questions/40811500/ios-swift-value-of-an-integer-is-not-being-saved, http://stackoverflow.com/questions/40756123/swift-обеспечить-urlsession-datatask-is-completed-in-my-function-before-pass-res, http://stackoverflow.com/questions/40491502/swift-3-send-make-synchronous-http -request, ... –

ответ

2

Это происходит потому, что функция непосредственно возвращает значение 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 будет называться.

Надеюсь, это помогло.

+0

Спасибо вам большое! Это сработало хорошо! –