我使用Swift 2和Xcode 7.1。
我有一个连接我的用户的功能,但它会在我的数据库中使用HTTP连接。我使用Alamofire执行此请求。我想知道,如果用户已连接,则从视图控制器。
我的功能连接在一个类中。我在ViewController中测试连接。 像这样:
class user {
// ...
func connectUser(username: String, password: String){
let urlHost = "http://localhost:8888/project350705/web/app_dev.php/API/connect/"
let parametersSymfonyG = [
username, password
]
let url = UrlConstruct(urlHost: urlHost).setSymfonyParam(parametersSymfonyG).getUrl()
//var userArray = [String:AnyObject]()
Alamofire.request(.GET, url)
.responseString { response in
if let JSON = response.result.value {
var result = self.convertStringToDictionary(JSON)!
if result["status"] as! String == "success"{
let userArray = result["user"] as! [String:AnyObject]
userConnect = self.saveUser(userArray)
} else{
print("ERROR-CONNECTION :\n Status :\(result["status"]!)\n Code :\(result["code"]!)")
}
return ""
}
}
}
// ...
}
class MyViewController: UIViewController {
// ...
@IBAction func connect(sender: AnyObject?) {
// CONNECTION
User.connectUser(self.username.text!, password: self.password.text!)
// CHECK
if userConnect != nil {
print("connected")
}else{
print("NotConnected")
}
}
// ...
}
第一个解决方案:返回
这样做会要求我的函数返回一个布尔值。 只有我不能使用return。
Alamofire.request(.GET, url)
.responseString { response in
if let JSON = response.result.value {
var result = self.convertStringToDictionary(JSON)!
if result["status"] as! String == "success"{
let userArray = result["user"] as! [String:AnyObject]
userConnect = self.saveUser(userArray)
} else{
print("ERROR-CONNECTION :\n Status :\(result["status"]!)\n Code :\(result["code"]!)")
}
return "" // Unexpected non-void return value in void function
}
}
第二个解决方案:
我还可以测试用户是否已经登录,但在测试之前,我必须等待功能已经完成加载。
users.connectUser(self.username.text!, password: self.password.text!)
// after
if userConnect != nil {
print("connected")
}else{
print("NotConnected")
}
我更喜欢返回一个布尔值。它将促进处理。 你有解决方案吗?
答案 0 :(得分:11)
我建议您在connectUser
方法中使用完成处理程序:
func connectUser(username: String, password: String, completion:(Bool) -> ()) {
// build the URL
// now perform request
Alamofire.request(.GET, url)
.responseString { response in
if let JSON = response.result.value, let result = self.convertStringToDictionary(JSON) {
completion(result["status"] as? String == "success")
} else {
completion(false)
}
}
}
然后您可以使用以下方式调用它:
users.connectUser(username.text!, password: password.text!) { success in
if success {
print("successful")
} else {
print("not successful")
}
}
// But don't user `success` here yet, because the above runs asynchronously
顺便说一句,如果你的服务器真的在生成JSON,你可以使用responseJSON
而不是responseString
,进一步简化代码并消除对convertStringToDictionary
的需求:
func connectUser(username: String, password: String, completion:(Bool) -> ()) {
// build the URL
// now perform request
Alamofire.request(.GET, url)
.responseJSON { response in
if let JSON = response.result.value {
completion(JSON["status"] as? String == "success")
} else {
completion(false)
}
}
}
如果您已编写自己的服务器代码来对用户进行身份验证,请确保设置正确的标头(因为responseJSON
不仅要为您解析JSON,还要将其作为验证过程的一部分,它确保标题指定JSON正文;无论如何设置标题是一种好习惯。例如在PHP中,在echo
JSON之前,设置标题如下:
header("Content-Type: application/json");
答案 1 :(得分:2)
Alamofire.request
方法的完成处理程序是异步的,并且它的签名中没有指定返回类型。这就是为什么在完成处理程序闭包中提供return
语句时看到错误的原因。
您必须将请求和响应处理拆分为单独的方法,并调用响应处理方法而不是使用return
语句。
Alamofire.request(.GET, url).responseString { response in
if let JSON = response.result.value {
var result = self.convertStringToDictionary(JSON)!
if result["status"] as! String == "success"{
let userArray = result["user"] as! [String:AnyObject]
userConnect = self.saveUser(userArray)
processSuccessResponse() //Pass any parameter if needed
} else{
print("ERROR-CONNECTION :\n Status :\(result["status"]!)\n Code :\(result["code"]!)")
processFailureResponse() //Pass any parameter if needed
}
}
}
func processSuccessResponse() {
//Process code for success
}
func processFailureResponse() {
//Process code for failure
}
答案 2 :(得分:1)
我这样做的首选方法是在完成处理程序中调用一个函数。您还可以设置布尔标志,以检查用户是否在任何给定时间连接。
func connectUser(username: String, password: String, ref: MyClass) {
Alamofire.request(.GET, url)
.responseString { response in
var userIsConnected = false
if let JSON = response.result.value {
var result = self.convertStringToDictionary(JSON)!
if result["status"] as! String == "success"{
let userArray = result["user"] as! [String:AnyObject]
userConnect = self.saveUser(userArray)
userIsConnected = true
} else {
print("ERROR-CONNECTION :\n Status :\(result["status"]!)\n Code :\(result["code"]!)")
}
} else {
print("Response result nil")
}
ref.finishedConnecting(userIsConnected)
}
}
}
class MyClass {
var userIsConnected = false
func startConnecting() {
connectUser(username, password: password, ref: self)
}
func finishedConnecting(success: Bool) {
userIsConnected = success
... post-connection code here
}
}