iOS 登录接口封装实践
登录。。。基本所有APP都少不了,开始写APP,可能首先就是从登录开始
我也一样,我手上有一个封装了所有账户体系相关接口的SDK,运行良好但也遇到少量烦心事,就拿登录来说说吧。
首先有如下相关封装,很常见,也无需太多解释:
import Foundationpublic typealias Response = (_ json: String?, _ error: Error?) -> Void// 账户体系管理器public class AccountMgr: NSObject { private override init() {} public static let shared = AccountMgr()}public extension AccountMgr { /// 登录 /// - Parameters: /// - accountType: 账户类型 see `AccountType` /// - password: 密码 /// - res: 请求结果 func login(by accountType: AccountType, password: String, res: Response?) { var params = [String: Any]() switch accountType { case let .email(email): params["type"] = "email" params["email"] = email case let .mobile(mobile, mobileArea): params["type"] = "mobile" params["mobile"] = mobile params["mobileArea"] = mobileArea } params["password"] = password //网络请求,并回调 //request(type: .post, api: .login, params: params, res: res) }}/// 账号类型 public enum AccountType { /// 手机号 /// - mobile: 手机号 /// - mobileArea: 国家区号(中国 86) case mobile(_ phoneNumber: String, mobileArea: String = "86") /// 邮箱 case email(_ email: String)}
使用也很方便:
// 分开使用AccountMgr.shared.login(by: .email(""), password: "", res: nil)AccountMgr.shared.login(by: .mobile("", mobileArea: ""), password: "", res: nil)// 合并使用var loginType: AccountTypeif inputEmail { loginType = .email("test@weixian.com")} else { loginType = .mobile("18000000000", mobileArea: "86")}AccountMgr.shared.login(by: loginType, password: "xxxxx", res: nil)
无论是邮箱,手机号登录分开逻辑登录,还是统一的登录管理器登录都能胜任,并且只有两种登录,分开写也不会多很多代码。
有一天,这个SDK需要在OC项目中使用
感觉没爱了,懒得想太多,直接废弃了Swift 枚举的便利性,写成了两个方法:
public class AccountMgr: NSObject { private override init() {} @objc(shareInstance) public static let shared = AccountMgr()}@objc func loginBy(email: String, password: String, res: Response?)@objc func loginBy(mobile: String, mobilArea: String, password: String, res: Response?)
之所以写成loginBy(email:)
而不是login(by email:)
,主要是为了swift 转 OC 后使用的时候能直接看懂,也不需要去查看定义,看如下截图就能明白了:
login
第一个方法不看定义,应该没办法理解参数应该填什么了。
就这样,我的SDK又运行了一段时间,看起来也没什么大问题,无非是手机登录和邮箱登录肯定要分开调用罢了
又有一天,这个登录方法要添加客户账号登录
依样画葫芦,我又添加了一个接口~~~,只是这样,那故事就结束了。
可惜,我还有第三方绑定接口,即微信登录后绑定手机,邮箱,或者账号、、、、这里又三个接口,还有查询账号信息又三个,还有。。。又三个。。。,还有。。。又三个。。。
这个时候我又开始怀念第一版的接口了,其实这很容易处理,只需一个整型枚举,而后把多出来的参数设置为可选,尽管使用的时候会有点奇怪,但是很好的处理了问题。并且最终我也是这么做的,可我还是想在Swift中能够更好的使用Swfit特性,写出更简洁的代码。。所以我写了两套接口。。。。,一套OC使用,一套Swfit使用,由于我总觉得在不久的将来,我就不需要支持OC了:
首先添加了一个OC的类型枚举:
@objc public enum AccountType_OC: Int { case mobile case email case userId}
而后添加了一个只有OC可用的方法:
@available(swift 10.0)@objc func loginBy(accountType: AccountType_OC, account: String, password: String, mobileArea: String?, res: Response?) { let type = getSwiftAccountType(accountType: accountType, account: account, mobileArea: mobileArea) login(by: type, password: password, res: res)} private func getSwiftAccountType(accountType: AccountType_OC, account: String, mobileArea: String?) -> AccountType { var type: AccountType switch accountType { case .mobile: guard let mobileArea = mobileArea else { fatalError("need mobile area") } type = .mobile(account, mobileArea: mobileArea) case .email: type = .email(account) case .userId: type = .userId(account) } return type}
OC中没办法给参数赋默认值,即相似mobileArea: String = "86"
这种,完全没有用。。。
私有类型转换的方法的封装,使得所有其余方法可以快速转换,关于@available(swift 10.0)
意思就是说只有Swift 版本10.0只后才可以使用。。即变相达到了,在Swift 代码中不会出现这个方法,只有下面方法可以使用:
func login(by accountType: AccountType, password: String, res: Response?)
基本就是这样了,看起来很麻烦,也的确挺麻烦,其实完全可以只保留OC使用的方法,这完全归于我的代码洁癖,以及我自己在使用Swift和对于日后去掉OC支持时我可以快乐的删代码的白日幻想。
当然,假如你只是在自己的混编APP内部封装少量接口,那一套接口应该是比较好的,假如你的是SDK,同时你也不是很怕麻烦,像我这样写也许会有少量意外的收获。
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » iOS 登录接口封装实践