我仍然是iOS开发的新手,我正在尝试从MVVM开始,在Swift中教自己良好的编码实践和设计模式。我需要将数据从ServiceCall类中的完成句柄传递给我的ViewModel。我希望能够帮助理解如何做到这一点,并在我的代码中使用MVVM的最佳实践指导。
这是我到目前为止所做的:
模型
struct Login {
var appVersion: String ?
var deviceID : String ?
var deviceOS : String ?
var password : String ?
var username : String ?
}
服务电话/ API客户端
class LoginServiceCall : NSObject, URLSessionDelegate {
let viewResponse = ThrowResponse()
func requestLogin(request: URLRequest, requestObject: Login, completion: @escaping ([NSDictionary] ? ) -> Void) {
let searchParams = Login.init(appVersion: requestObject.appVersion, deviceID: requestObject.deviceID, deviceOS: requestObject.deviceOS, password: requestObject.password, username: requestObject.username)
var request = request
request.httpMethod = "POST"
do {
request.httpBody = try JSONSerialization.data(withJSONObject: searchParams, options: .prettyPrinted)
} catch let error {
print(error.localizedDescription)
}
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
let session = URLSession.shared
let task = session.dataTask(with: request, completionHandler: {
data, response, error -> Void in
do {
let json = try JSONSerialization.jsonObject(with: data!) as ? Dictionary<String, Any>
//completion(json!)
// This is where i would like to pass the dictionary data
} catch {
DispatchQueue.main.async {
self.viewResponse.dismissLoader()
self.viewResponse.showFailureAlert(title: "Failure", message: "")
completion(nil)
}
}
})
task.resume()
}
}
查看控制器
class LoginViewController: UIViewController, UITextFieldDelegate {
@IBOutlet var loginButton: UIButton!
@IBOutlet var usernameOrEmailTextField: UITextField ?
@IBOutlet var passwordTextField : UITextField ?
var serviceBalance = 0.0
let defaults = UserDefaults.standard
var Reach : Reachability ? = Reachability()
var viewModel : LoginViewModel ?
override func viewDidLoad() {
super.viewDidLoad()
usernameOrEmailTextField?.delegate = self
passwordTextField?.delegate = self
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
usernameOrEmailTextField?.resignFirstResponder()
passwordTextField?.resignFirstResponder()
return (true)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
@IBAction func loginButton(_ sender: Any) {
viewModel?.setLoginObject(withUsername: usernameOrEmailTextField?.text, withPassword : passwordTextField?.text)
}
@IBAction func forgotPasswordButton(_ sender: Any) {
self.performSegue(withIdentifier: "forgotPasswordSegue", sender: nil)
}
@IBAction func registerButton(_ sender: Any) {
self.performSegue(withIdentifier: "registerUserSegue", sender: nil)
}
}
视图模型
class LoginViewModel: NSObject {
var Reach: Reachability? = Reachability()
var login: Login?
var homeViewDictionary: [NSDictionary]?
var APIClient: LoginServiceCall!
var request = URLRequest(url: URL(string: "http://myapiuser/login")!)
func setLoginObject(withUsername username: String?, withPassword password: String?){
login?.username = username
login?.password = password
login?.appVersion = self.getAppVersion()
login?.deviceID = self.getDeviceID()
login?.deviceOS = self.getDeviceOs()
APIClient.requestLogin(request: request, requestObject: login! { (AppDictionary) in
DispatchQueue.main.async {
self.homeViewDictionary = AppDictionary
}
}, completion: ())
}
func getAppVersion() -> String { return "0.2" }
func getDeviceID() -> String {
if let deviceid = UIDevice.current.identifierForVendor?.uuidString { return deviceid }
}
func getDeviceOs() -> String {
let systemVersion = UIDevice.current.systemVersion
let model = UIDevice.current.model
return systemVersion+" "+model
}
}