【发布时间】:2016-06-17 18:19:14
【问题描述】:
我正在使用以下函数通过 RESTEngine.sharedEngine.registerUser 函数从我的服务器获取一些数据。 “userCreationCall”进行 API 调用,解析它返回的 JSON,创建一个用户,然后将该用户传递到其完成块中。
“makeUser”然后通过将其中的用户传递给另一个函数来处理该完成块,该函数返回用户对象供我在我的应用程序的其他地方使用。
func userCreationCall(first: String, last: String, email: String, completionHandler: (User?, ErrorType?) -> ()) {
RESTEngine.sharedEngine.registerUser(email, firstName: first, lastName: last, age: 12, success: { response in
if let response = response, result = response["resource"], id = result[0]["_id"] {
let params: JSON =
["name": "\(first) \(last)",
"id": id as! String,
"email": email,
"rating": 0.0,
"nuMatches": 0,
"nuItemsSold": 0,
"nuItemsBought": 0]
let user = User(json: params)
completionHandler(user, nil)
}
}, failure: { error in
completionHandler(nil, error)
})
}
func makeUser(first: String, last: String, email: String) {
userCreationCall(first, last: last, email: email) { user, error in
guard error == nil else {
print("Error creating a user! : \(error)")
return
}
returnUser(user!)
}
}
func returnUser(user: User) -> User {
return user
}
出于测试目的,我在 viewDidLoad 中进行了以下调用,旨在为“testUser”分配在“makeUser”的完成块中传递的用户对象:
override func viewDidLoad() {
super.viewDidLoad()
let testUser = makeUser("John", last: "Doe", email: "johnDoe@gmail.com")
print("\(testUser)")
}
但是,当我打印 testUser 时,它仍然是空白的(这意味着它永远不会在“makeUser”的完成块中分配给用户对象)。有没有人知道我的逻辑/实现哪里出错了?提前致谢!
【问题讨论】:
-
您也应该在
makeUser中使用完成处理程序来处理您想要的输出,而不是返回。 -
您从that other answer 中获取了
makeUser,但似乎没有理解基本点,即您不能从异步方法返回值(并且getUser现在是异步方法) .调用异步方法时,不要尝试返回结果,而是始终遵循异步编程模式,例如完成处理程序模式。 -
您说“它永远不会在“makeUser”的完成块中分配用户对象”。不,它确实得到了一个值,但稍后,在
viewDidLoad已经完成之后。您只能在完成块中使用该值,而不能在viewDidLoad中使用。 -
所以由于我无法从异步方法返回值,看来我唯一剩下的选择是在异步调用之前声明一个“空”用户对象,我将用数据填充我从回应中得到。我的想法在这里正确吗?
-
是的,就是这样做的。如果可以,请保存上次的内容,以便在使用更新的数据进行刷新时显示一些内容。或者在执行异步请求时显示活动指示器视图。
标签: ios swift asynchronous closures