我正在构建一个iOS应用程序,我刚刚完成了我的登录/注册部分(请求sails.js休息Api) 目前我有2个具有重复代码的视图控制器,因为我在每个类的注册/登录按钮事件监听器上发出其余的调用,并且有很多类似的代码我可以重构。
我想要做的是创建一个名为ApiManager的单例,它将包含我需要的所有调用。 (还有未来的)
问题是,对于异步调用,我无法创建一个函数func login(用户名,密码),它将返回数据,以便我可以存储它们并准备好。
正确实现这一目标的简单/正确方法是什么?这意味着调用ApiManager.myFunction并在任何需要的地方使用结果(填充数据的tableview,启动segue进行登录或注册成功)并使该函数在另一个视图控制器中可重用,即使它是用于其他用途。我正在使用swift。
编辑:我是这样做的,所以我希望它能帮助你
执行休息呼叫的功能:
func login(#username: String, password: String, resultCallback: (finalresult: UserModel!,finalerror:String!) -> Void) {
Alamofire.request(.POST, AppConfiguration.ApiConfiguration.apiDomain+"/login", parameters: ["username": username,"password": password], encoding: .JSON)
.responseJSON { request, response, data, error in
if let anError = error
{
resultCallback(finalresult: nil,finalerror:anError.localizedDescription)
}else if(response!.statusCode == 200){
var user:UserModel = self.unserializeAuth(data!)//just processing the json using SwiftyJSON to get a easy to use object.
resultCallback(finalresult: user,finalerror:nil)
}else{
resultCallback(finalresult: nil,finalerror:"Username/Password incorrect!")
}
}.responseString{ (request, response, stringResponse, error) in
// print response as string for debugging, testing, etc.
println(stringResponse)
}
}
这就是我从ViewController调用此函数的方法:
@IBAction func onLoginTapped(sender: AnyObject) {//When my user tap the login button
let username = loginInput.text;//taking the content of inputs
let password = passwordInput.text;
ApiManager.sharedInstance.login(username:username,password:password){
[unowned self] finalresult,finalerror in
if(finalresult !== nil){//if result is not null login is successful and we can now store the user in the singleton
ApiManager.sharedInstance.current_user=finalresult
self.performSegueWithIdentifier("showAfterLogin", sender: nil)//enter the actual app and leave the login process
}else{
self.displayAlert("Error!", message: finalerror)//it is basically launching a popup to the user telling him why it didnt work
}
}
}
答案 0 :(得分:2)
我的几乎所有应用程序都以Server
类结束,这是唯一知道如何与服务器通信的类。它进行调用,将结果解析为Swift结构并返回它。我的大多数服务器返回json所以我使用SwiftyJSON,但你可以做任何你想做的事。
关键是,因为这是唯一了解服务器通信的类,如果我需要更改用于进行通信的库(AFNetworking 1 vs 2 vs Parse,vs之等),这是我唯一的类需要触摸。
class Server {
static let instance = Server()
func loginWithUsername(username: String, password: String, resultCallback: (result: Either<User, NSError>) -> Void) {
// if login is successful call
resultCallback(result: .Left(self.user!))
// otherwise call
resultCallback(result: .Right(error))
}
}
使用示例:
let server = Server.instance
SVProgressHUD.showWithStatus("Loggin In...")
server.loginWithUsername(username, password: password) { [unowned self] result in
SVProgressHUD.dismiss()
switch result {
case .Left(let user):
self.presentUserType(user.userType)
case .Right(let error):
self.warnUserWithMessage("An error occured. \(error.localizedDescription)")
}
}
如果所有后续调用都需要用户名/密码,则服务器对象将保留它们的副本。如果登录返回令牌,则服务器会保留该令牌的副本。 QED。
答案 1 :(得分:0)
我通常在我的视图控制器共享的基类中使用实用程序函数,并使用NSNotificationCenter对请求的结果作出反应。它也可以通过授权(协议和代表。
)轻松实现这主要是关于感知,但我发现你可以更容易想象,例如,你可以在一个控制器上启动一个动作并对另一个控制器作出反应,因为这个调用需要很长时间而且你没有阻止你应用中的导航。 / p>