我在函数中使用 Alamofire 请求从数据库中检索用户。问题是,请求所使用的函数取决于请求,因为我将结果作为 User 类的对象返回。
目前,它总是返回在我的函数顶部声明的默认 nil 值,因为请求下面的代码不会费心等待请求完成。 .success 或 .failure 部分中的基本打印语句证明了这一点(因为它不打印任何内容)。
我就是不知道怎么解决。我在网上查了一段时间,并且:
- 要么我在论坛上遇到有关使用哪些类的建议,甚至懒得解释如何使用它
- 或者我看到一个视频解释了完全不同的事情,例如处理多个请求
我可以向你们寻求帮助吗?我将在下面发布代码:
用户类别:
public class User
{
private var _name : String
public var Naam : String
{
get {return self._name}
set
{
/*
Just a function from a static class which trims a string. It's not really relevant to my problem …
*/
let name : String? = StringOps.trimString(string: newValue)
if name == nil
{
fatalError()
}
self._name = newValue
}
}
/*
* And some fields and properties for:
* - firstname
* - username
* - password
* - email
* They are basically equivalent to the one above
*/
// And a constructor
init(id : Int)
{
self._id = id
self._name = ""
self._firstname = ""
self._username = ""
self._email = ""
self._password = ""
}
}
LoginViewController 中的登录函数内的请求:
public func login(username: String, password: String)
-> User?
var user : User? = nil
/* Some code that is trimming and checking the input.
The username parameter gets put into a let parameter userName and the same goes for the password parameter. It's Ommitted here.
*/
let parameters : Parameters = [
"userName" : userName!,
"passWord" : passWord!
]
// _loginUrl is a private let String parameter
Alamofire.request(_loginUrl, method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: nil)
.responseJSON
{
(response : DataResponse<Any>) in
switch (response.result)
{
case .success(_):
let data: NSDictionary = (response.value as! NSArray)[0] as! NSDictionary
/* The part commented out isn't working anyways,
and before I started changing the return type of my
function (was a Bool at first),
it worked well enough without it */
/*
if response.result.value != nil
{
/* Convert the JSON to a User object */
let data = (response.value as! NSArray)[0] as! NSDictionary
user = User(id: data["id"] as! Int)
user!.Email = data["e_mail"] as! String
user!.Username = data["username"] as! String
user!.Name = data["name"] as! String
user!.Firstname = data["firstname"] as! String
user!.Password = data["password"] as! String
}
*/
user = User(id: data["id"] as! Int)
user!.Email = data["e_mail"] as! String
user!.Username = data["username"] as! String
user!.Name = data["name"] as! String
user!.Firstname = data["firstname"] as! String
user!.Password = data["password"] as! String
break
case .failure(_):
print(response.result.error as Any)
// _error is also a private var member of LoginViewController
self._error = "Something's wrong with your login credentials!"
user = nil
break
}
}
return user
}
此函数在我的 LoginView 中的私有(private)函数中使用:
struct LoginView
: View
{
// Some unimportant bits
private func logIn()
{
// username and password are @State private vars which are bound to their corresponding Text()
let user : User? = self.controller.login(username: self.username, wachtwoord: self.password)
// other code
}
}
最佳答案
您需要创建一个completionHandler
当您的代码获取对 User
对象的引用时,仍然是 nil
,因为服务器的响应尚未到来。
public func login(用户名:字符串,密码:字符串) -> 用户?
将其更改为:
public func login(用户名:字符串,密码:字符串,完成:@escaping (User?) -> Void)
然后你可以这样做:
private func logIn() {
self.controller.login(username: self.username, wachtwoord: self.password) { user in
guard let user = user else {
print("Error while retrieving user")
return
}
/// Access your user here
}
}
}
关于SwiftUI:在执行下面的代码之前等待 Alamofire 请求完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59920354/