Swfit-实现登录和列表网络请求MVP结构(最新2020.7)

16 篇文章 0 订阅

此篇文章阐述如何Swfit实现登录功能界面,利用项目MVP结构,分层逻辑化清晰地实现需求:

功能特点:

  • Alamofire获取请求服务器JSON进行登录
  • 一个输入Name,一个输入Pwd,一个登录按钮,一个注册按钮
  • 输入账户密码,点击登录正确,方可跳转到Home界面
  • 点击注册按钮进行跳转到注册界面
  • UI框架用的最流行的SnapKit框架设计

一:项目结构如下:

  1. LoginView(登录的view样式)
  2. LoginPresenter(登录的接口请求)
  3. LoginModel(接口的返回参数JSON)
  4. LoginViewController(登录的控制器界面实现)

在这里插入图片描述

二:项目区块功能分析如下:

  • LoginView的界面实现,样式,代理Protocol,继承类Baseview
import UIKit

protocol  LoginViewProtocol:NSObjectProtocol{
    
    func onLoginClick()//登录的按钮代理
    
    func onReginClick()//注册的按钮代理
    
}

class LoginView: BaseView {
    
    weak var delegate:LoginViewProtocol?
    
    //用户名
    var aUserNmaeLb:UILabel?
    
    var aUserNameTf:UITextField?
    
    var aUserNameImage:UIImageView?
    
    //密码
    var aUserPsdLb:UILabel?
    
    var aUserPsdTf:UITextField?
    
    var aUserPsdImage:UIImageView?
    
    //确认按钮
    var aUserLoginBtn:UIButton?
    
    //注册按钮
    var aUserReginBtn:UIButton?
    
    override func initView() {
        
        let mainView = UIView()
        if let image = UIImage(named: "login_bg"){
             mainView.backgroundColor = UIColor(patternImage: image)
        }
        mainView.alpha = 0.95
        addSubview(mainView)
        
        mainView.snp.makeConstraints{(make)->Void in
            make.top.equalTo(self).offset(0)
            make.left.equalTo(self).offset(0)
            make.right.equalTo(self).offset(0)
            make.bottom.equalTo(self).offset(0)
        }
        
        let aimages = UIImageView()
        aimages.image = UIImage(named: "hy_login")
        mainView.addSubview(aimages)
        
         aimages.snp.makeConstraints{(make)->Void in
               make.top.equalTo(90)
               make.height.equalTo(80)
               make.width.equalTo(80)
               make.centerX.equalTo(self)
        }
        
        //用户名
        let aUserView = UIView()
        aUserView.layer.cornerRadius = 8
        aUserView.layer.borderColor = UIColor.white.cgColor
        aUserView.layer.borderWidth = 1
        mainView.addSubview(aUserView)
        
        aUserView.snp.makeConstraints{(make)->Void in
            make.left.equalTo(mainView).offset(10)
            make.right.equalTo(mainView).offset(-10)
            make.top.equalTo(mainView).offset(200)
            make.height.equalTo(50)
        }
        
        aUserNameImage = UIImageView()
        aUserNameImage?.image = UIImage(named: "user")
        aUserView.addSubview(aUserNameImage!)
        
        aUserNameImage?.snp.makeConstraints{(make)->Void in
            make.left.equalTo(aUserView).offset(10)
            make.width.equalTo(25)
            make.top.equalTo(aUserView).offset(15)
            make.height.equalTo(25)
        }
        
        aUserNameTf = UITextField()
        aUserNameTf?.placeholder = "Please input account/email."
        aUserNameTf?.text="hy"
        aUserNameTf?.textColor = UIColor.white
        aUserView.addSubview(aUserNameTf!)
       
        aUserNameTf?.snp.makeConstraints{(make)->Void in
           make.left.equalTo(aUserNameImage!).offset(35)
           make.width.equalTo(220)
           make.top.equalTo(aUserView).offset(0)
           make.height.equalTo(50)
        }
        
        //密码
        let aUserPsdView = UIView()
        aUserPsdView.layer.cornerRadius = 8
        aUserPsdView.layer.borderColor = UIColor.white.cgColor
        aUserPsdView.layer.borderWidth = 1
        mainView.addSubview(aUserPsdView)
        
        aUserPsdView.snp.makeConstraints{(make)->Void in
            make.left.equalTo(mainView).offset(10)
            make.right.equalTo(mainView).offset(-10)
            make.top.equalTo(mainView).offset(270)
            make.height.equalTo(50)
        }
        
         aUserPsdImage = UIImageView()
         aUserPsdImage?.image = UIImage(named: "pwdx")
         aUserPsdView.addSubview(aUserPsdImage!)
         
         aUserPsdImage?.snp.makeConstraints{(make)->Void in
             make.left.equalTo(aUserPsdView).offset(10)
             make.width.equalTo(25)
             make.top.equalTo(aUserPsdView).offset(15)
             make.height.equalTo(25)
         }
         
         aUserPsdTf = UITextField()
         aUserPsdTf?.placeholder = "Please input account/email."
         aUserPsdTf?.text="888@eiou"
         aUserPsdTf?.textColor = UIColor.white
         aUserPsdView.addSubview(aUserPsdTf!)
        
         aUserPsdTf?.snp.makeConstraints{(make)->Void in
            make.left.equalTo(aUserPsdImage!).offset(35)
            make.width.equalTo(220)
            make.top.equalTo(aUserPsdView).offset(0)
            make.height.equalTo(50)
         }
        
        //登录
        aUserLoginBtn = UIButton()
        aUserLoginBtn?.setTitle("登录", for: .normal)
        aUserLoginBtn?.layer.cornerRadius = 15
        aUserLoginBtn?.backgroundColor = UIColor(hexString: "#03a9f4", transparency: 1.0)
        mainView.addSubview(aUserLoginBtn!)
        
        aUserLoginBtn?.snp.makeConstraints{(make)->Void in
           make.top.equalTo(aUserPsdView).offset(80)
           make.left.equalTo(mainView).offset(30)
           make.right.equalTo(mainView).offset(-30)
           make.height.equalTo(50)
       }
        
        aUserLoginBtn?.addTarget(self, action: #selector(onLoginClick), for: .touchUpInside)
        
        //注册
    }
    
    @objc func onLoginClick(){
        if delegate != nil {
            delegate!.onLoginClick()
        }
    }
    
}

  • LoginPresenter接口文件的实现:
  • 主要描写了网球请求的方法,利用Alamofire框架,通过代理传递返回正确的JSON数据,控制器界面 接收model;
import UIKit
import Alamofire

protocol LoginProtocol:NSObjectProtocol {
    func getLoginSuccess(result:LoginModel)
    func getLoginFail(result:String)
}

struct LoginPresenter<T> where T:LoginProtocol {
    var view: T?
    weak var delegate:LoginProtocol?
    
    mutating func initial(_ view: T){
        self.view = view
    }
    
    func loginUserJson(user:String,pwd:String){
       let url = BASE_URL.appending("user/getUser")
               
       let params:[String:Any] = [
           "username":user,
           "password":pwd
       ]
       
       let headers: HTTPHeaders = [
           "Content-Type":"application/json"
       ]
        
        ApiUtils.shared.netWork(url: url, method: .post, params: params, headers: headers, success: { result in
            if let model = LoginModel.deserialize(from: result){
                 if model.code == "200"{
                    self.view?.getLoginSuccess(result: model)
                }else{
                    self.view?.getLoginFail(result: "Account or Password Yes!")
                }
            }else{
                self.view?.getLoginFail(result: "Account or Password Error!")
            }
            
        }, error: { error in
            self.view?.getLoginFail(result: error)
        })
    }
}
  • LoginModel主要描述的是JSON数据的model,我这json请求成功返回:如:{code = 200 ,message = “成功登录”,data:[{name:22,age:33},{name:33,age:66}]}

import UIKit
import HandyJSON

class LoginModel: HandyJSON {
    
    var code:String?
    var message:String?
    var data:Array<User>?
    
    required init() {}
}


class User: HandyJSON {
    
    var pushId:Bool?
    var name:String?
    var userName:String?
    
    required init() {}
}

  • LoginViewController控制器界面的功能实现
  • 把需要的代理都写入LoginViewController:BaseViewController,LoginProtocol,LoginViewProtocol,UITextFieldDelegate
import UIKit
import WHToast
import MBProgressHUD

class LoginViewController:BaseViewController,LoginProtocol,LoginViewProtocol,UITextFieldDelegate{
    
    private var loginView = LoginView()
    private var loginPresenter = LoginPresenter<LoginViewController>()
    
    private var uid:String?
    
    private var name:String?
    
    private var pwd:String?
    
    var hud:MBProgressHUD?
    
    private var cmUtil = CommonUtil()
    
    override func viewDidLoad() {
           super.viewDidLoad()
       }
    
    override func initView() {
        loginView.frame = view.bounds
        self.view.addSubview(loginView)
    }
    
    override func initData() {
        loginView.delegate = self
        loginView.aUserNameTf?.delegate = self
        loginView.aUserPsdTf?.delegate = self
        self.loginPresenter.initial(self)
    }
    
    
    func onLoginClick() {
        let name:String = loginView.aUserNameTf?.text ?? ""
        let pwd:String = loginView.aUserPsdTf?.text ?? ""
        
        if !cmUtil.isEmpty(name) && !cmUtil.isEmpty(pwd){
            loginPresenter.loginUserJson(user: name, pwd: pwd)
            showHud()
        }else{
            WHToast.showMessage("Input is not empty!", originY: 500, duration: 2, finishHandler: {
            })
        }
        print("登录")
    }
    
    /*
        show loading...
     */
    func showHud() {
        hud = MBProgressHUD.showAdded(to: view, animated: true)
        hud?.bezelView.style = .solidColor
        hud?.bezelView.color = UIColor.black.withAlphaComponent(0.7)
        hud?.label.text = NSLocalizedString("Loading...", comment: "HUD loading title")
        hud?.contentColor = UIColor.white
        //正常情况下是10秒后消失
        hud?.hide(animated: true, afterDelay: 8.0)
    }
    
    func hidHud(){
        hud?.hide(animated: true, afterDelay: 0.5)
    }
    
    func onReginClick() {
        print("注册")
    }
    
    func getLoginSuccess(result: LoginModel) {
        print("成功");
        hidHud()
        let reg = HomeViewController()
        let navCtrl = UINavigationController(rootViewController: reg)
        present(navCtrl, animated: true)
    }
    
    func getLoginFail(result: String) {
        hidHud()
        WHToast.showMessage(result, originY: 500, duration: 2, finishHandler: {
        })
        print("失败");
    }
    
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        loginView.aUserNameTf?.resignFirstResponder()
        loginView.aUserPsdTf?.resignFirstResponder()
        return true
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        loginView.aUserNameTf?.resignFirstResponder()
        loginView.aUserPsdTf?.resignFirstResponder()
    }
}

三:Podfile配置文件调用第三方

target 'HY_SYSTEM_APP_SWFIT' do
  use_frameworks!
  pod 'Alamofire'
  pod 'SnapKit', '~> 5.0.0'
  pod 'HandyJSON', '~> 5.0.0'
  pod 'WMPageController', '~> 2.4.0'
  pod 'WHToast','~>0.0.3'
  pod 'MBProgressHUD', '~> 1.2.0'
  pod 'MJRefresh'

end

四:调取的服务器路径为自己的:
在这里插入图片描述

五:效果如图下:
在这里插入图片描述

以上此篇Swfit编写登录界面的功能需求实现到此为止,如果对你有所满意,感谢您的阅读与支持,如果有写的不好之处,欢迎指点迷津。相互进步学习… 可关注后续更多的IOS移动端文章!~Aftrey

六:Demo点击这:

Swfit-实现登录和列表网络请求MVP结构(最新2020.7)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值