swift - SwiftUI:在执行以下代码之前等待 Alamofire 请求完成
问题描述
我在函数中使用 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
}
}
解决方案
你需要创建一个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
}
}
}
推荐阅读
- jsf - xhtml 文件不起作用,但 html 文件可以正常工作
- c# - 从 Crystal Report 查看器中的每个页面获取内容并将其导出为 pdf
- python - 如何在 Google Colab 中读取压缩文件?
- python - 简单地匹配值而不使用循环
- c++ - 使用 OpenCV [C++] 预测 2D 乒乓球的轨迹
- sql - 在包含 ca. 的小型数据库中搜索名称的最快方法是什么?1.000.000 个名字?
- regex - 正则表达式寻找一个基本词(snmp-server)然后它需要拥有所有三个(组视图和主机)
- git - `git reset --hard HEAD~1`中的`HEAD~1`是什么意思?
- laravel - 使用 nuxt auth 和 laravel 护照登录时出现错误 404
- c++ - 我需要使用 OpenGL 和 GLUT 绘制一个点,但我只是得到一个空白的黑屏