我在函数中使用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的私有功能中使用:
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
}
}
答案 0 :(得分:0)
您需要创建一个completionHandler
由于您的代码尚未收到服务器的响应,因此直到您的代码获得对User
对象的引用时,该代码仍为nil
。
public func login(username: String, password: String) -> User?
将其更改为:
public func login(username: String, password: String, completion: @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
}
}
}