我正在尝试构建用户注册表单,该表单应检查用户是否已存在。所以我发送一个php请求到我的mysql服务器。如果返回值为空,则用户尚不存在。
Unfortunatley我真的很难等待这个检查完成。我尝试了几种解决方案,我发现googleing但没有一个有效。我当前的代码使用信号量并且会因为"致命错误而崩溃:在解开一个Optional值"时意外地发现nil,所以信号量不会等到任务完成之后就像我期望的那样。
任何提示,将不胜感激。谢谢你们。
private func isUniqueEmail(email: String) -> Bool {
var result: Bool?
let semaphore = DispatchSemaphore(value: 1)
let requestURL = URL(string: "http://localhost/firstpostget/functions/get.php")
var request = URLRequest(url: requestURL!)
request.httpMethod = "POST"
let postParameters = "email=" + email
request.httpBody = postParameters.data(using: .utf8)
let configuration = URLSessionConfiguration.default
let session = URLSession(configuration: configuration, delegate: nil, delegateQueue: OperationQueue.main)
let task = session.dataTask(with: request) {(data, response, error) in
var myJson: AnyObject
do{
myJson = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) as AnyObject
if myJson.count == 0{
result = true
semaphore.signal()
} else{
result = false
semaphore.signal()
}
} catch{
//TODO
print(error)
}
}
task.resume()
semaphore.wait(timeout: .distantFuture)
return result!
}
答案 0 :(得分:1)
你的任务是异步的,你强行解开零值,这就是它崩溃的原因。
您必须将您的函数实现更改为异步,例如使用闭包:
private func isUniqueEmail(email: String, completion: ((Bool) -> (Void))?) {
let requestURL = URL(string: "http://localhost/firstpostget/functions/get.php")
var request = URLRequest(url: requestURL!)
request.httpMethod = "POST"
let postParameters = "email=" + email
request.httpBody = postParameters.data(using: .utf8)
let configuration = URLSessionConfiguration.default
let session = URLSession(configuration: configuration, delegate: nil, delegateQueue: OperationQueue.main)
let task = session.dataTask(with: request) {(data, response, error) in
var myJson: AnyObject
do{
myJson = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) as AnyObject
if myJson.count == 0 {
completion?(true)
} else{
completion?(false)
}
} catch{
//TODO
print(error)
}
}
task.resume()
}
现在您可以这样使用此功能:
isUniqueEmail(email: "aaa@bbbb.com") { result in
if result {
print("email unique")
} else {
print("email not unique")
}
}
答案 1 :(得分:1)
我认为您应该重新考虑用于从请求中获取数据的模式,您应该考虑使用自定义处理程序/回调方法,并将其与您尝试检查的电子邮件一起传递。请参阅下面的示例:
hot.addHook('afterGetColHeader', RemoveUnWantedHeader);
function RemoveUnWantedHeader(col, th) {
if (th.textContent == "A" || th.textContent == "B" || th.textContent == "C"
|| th.textContent == "D" || th.textContent == "E"
|| th.textContent == "F" || th.textContent == "G" || th.textContent ==
"H"
|| th.textContent == "I" || th.textContent == "J"
|| th.textContent == "K" || th.textContent == "L" || th.textContent ==
"M"
|| th.textContent == "N" || th.textContent == "O"
|| th.textContent == "P" || th.textContent == "Q" || th.textContent ==
"R"
|| th.textContent == "S" || th.textContent == "T"
|| th.textContent == "U" || th.textContent == "V" || th.textContent ==
"W"
|| th.textContent == "X" || th.textContent == "Y" || th.textContent ==
"Z"
|| th.textContent == "AQ" || th.textContent == "AR" || th.textContent ==
"AS"
|| th.textContent == "AT" || th.textContent == "AU" || th.textContent ==
"AV" || th.textContent == "AW") {
th.style.display = 'none';
}
}
生成强>
private func isUniqueEmail(email: String, handler: ((_ result: Bool) -> Void)?) -> Void {
let requestURL = URL(string: "http://localhost/firstpostget/functions/get.php")
var request = URLRequest(url: requestURL!)
request.httpMethod = "POST"
let postParameters = "email=" + email
request.httpBody = postParameters.data(using: .utf8)
let configuration = URLSessionConfiguration.default
let session = URLSession(configuration: configuration, delegate: nil, delegateQueue: OperationQueue.main)
let task = session.dataTask(with: request) {(data, response, error) in
var myJson: AnyObject
var result: Bool = false
do{
myJson = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) as AnyObject
if myJson.count == 0 {
result = true
}
guard handler != nil else {
return
}
handler!(result)
} catch{
//TODO
print(error)
}
}
task.resume()
}
如果你真的想沿着“等待”路线走下去,那就去isUniqueEmail(email: "test@test.com", handler: { result in
print(result) // true || false
})
的
https://developer.apple.com/documentation/dispatch/dispatchgroup
答案 2 :(得分:0)
您可以使用URlSession,如:
func isUniqueEmail(email: String,completion: @escaping (Bool) -> ()) {
var request = URLRequest(url: URL(string: "http://localhost/firstpostget/functions/get.php")!)
request.httpMethod = "POST"
let postString = "email=\(email)"
request.httpBody = postString.data(using: .utf8)
// loading to wait request
UIApplication.shared.isNetworkActivityIndicatorVisible = true
let task = URLSession.shared.dataTask(with: request) { data, response, error in
// we get request request
UIApplication.shared.isNetworkActivityIndicatorVisible = false
guard let data = data, error == nil else { // check for fundamental networking error
print("error=\(String(describing: error))")
completion(false)
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 = \(String(describing: response))")
completion(false)
}else{
completion(true)
}
let responseString = String(data: data, encoding: .utf8)
print("responseString = \(String(describing: responseString))")
}
task.resume()
}
并在代码中使用
self.isUniqueEmail(email: "your Email") { (isExit) in
if isExit {
}else{
}
}
答案 3 :(得分:0)
尝试使用:
<强> ApihelperClass 强>
static let sharedInstance = ApihelperClass()
typealias CompletionHandler = (_ success:Bool, _ error:Bool, _ result:NSDictionary) -> Void
typealias ErrorHandler = (_ success: Bool, _ error:Bool) -> Void
func callPostRequest(_ urlPath: String, params:[String: AnyObject], completionHandler: @escaping CompletionHandler, errorHandler:@escaping ErrorHandler ){
print("urlPath:==> \(urlPath) ")
let session = Foundation.URLSession.shared
let url = URL(string: urlPath)
var request = URLRequest(url : url!)
request.httpMethod = "POST"
do {
let jsonData = try JSONSerialization.data(withJSONObject: params, options: .prettyPrinted)
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.httpBody = jsonData
session.dataTask(with: request, completionHandler: { data, response, error in
OperationQueue.main.addOperation {
guard error == nil && data != nil else { // check for fundamental networking error
print("error=\(error)")
errorHandler(false, true)
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: String.Encoding.utf8)
print("responseString = \(responseString!)")
if let responsedata = responseString!.data(using: String.Encoding.utf8)! as? Data{
do {
let jsonResult:NSDictionary = try JSONSerialization.jsonObject(with: responsedata, options: []) as! NSDictionary
print("Get The Result \(jsonResult)")
//parse your jsonResult as per your requirements
if error != nil {
print("error=\(error)")
completionHandler(false, true, jsonResult)//
}
if let str = jsonResult["success"] as? NSNull {
print("error=\(str)")
completionHandler(false, true, jsonResult)
}
else {
let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
// print("Response string : \(responseString)")
completionHandler(true, false, jsonResult)
}
} catch let error as NSError {
print(error.localizedDescription)
}
}
}
}) .resume()
}catch {
print("Error ->Catch")
}
}
添加到您的viewcontroller
func isUniqueEmail(email: String){
ApihelperClass.sharedInstance.callPostRequest("http://localhost/firstpostget/functions/get.php", params: ["email":email as AnyObject], completionHandler: { (success, error, result) in
//success 200
}) { (success, error) in
//error
}
}
答案 4 :(得分:0)
好的,我刚刚找到了解决方案。我的信号量方法实际上和调度组一样有效。任务只需要URLSession.shared.dataTask
仍然感谢所有答案。