在我们日常使用的APP中,登录功能可谓是最基本的必备功能。对于一个功能完善的APP来说,会有相应的机制来维护用户的个人昵称,头像,以及登录的令牌token等一系列隐私的个人信息,在我们的后台维护用户信息的同时,我们也需要对用户的个人信息进行相应的本地化。
用户的个人信息会在APP的使用过程中区分用户所享有的不同的权限,比如:当用户试图点击进入一个“收藏”界面功能的时候,这个时候就需要对用户的登录状态进行判断,如果用户处于登录状态,那么可以直接进入收藏界面。如果用户处于游客状态(也就是未登录状态),那么我们不能让用户直接进入到收藏界面,那么这个时候,我们可以通过跳转到登录界面,引导用户登录,或者弹窗友好提示用户未登录。
类似登录的情况还会有:当用户更改了头像之后或昵称之后,当修改成功之后,会在后台的数据库中对用户的头像或昵称进行更新。此时,在本地,我们也是需要对用户的信息进行更新的,避免在某个地方使用用户的信息的时候,出现与最新数据不匹配的问题。那么问题来了,对于APP中频繁使用的和更新的用户信息,我们需要创建一个单独的公共类来统一管理这些用户信息,对用户信息的添加,更新和删除都通过这个个人信息管理工具类来处理,那么对用户信息的处理就会变得简洁,更容易维护和使用。
上图素材取自互联网,如有侵权,请私信联系删除
好了,话不多说,直接开撸。先让我们创建一个简单的工具类:UserInfoManager
1.UserInfo工具类的属性就是用户的各项信息,包括最常用的几个属性,如:userID和昵称以及头像等,具体还要根据自己的项目的业务需要来确定。
2.通过单例模式来实现全局共享这个用户信息类
3.(1)当我们登录成功或者调用获取用户信息的接口成功之后,服务器会给我们返回用户的相关信息。(此处因为没有可以展示的接口,我们就自己模拟构造一下相关的数据信息)
NSDictionary *infoDic = @{@"userName":@"猫蛋",@"userID":@"akjhfakhewawehfakehffcnak",@"nickName":@"笑傲江湖",@"headPic":@"http://www.baidu.com/pic",@"phone":@"18837879087",@"exclusiveCode":@"EGD56",@"birthday":@"1992-11-21",@"email":@"wangyitdp@163.com",@"sex":@1};
进行到这一步,我们可以将拿到的用户信息直接传递给UserInfoManager工具类,它会帮你把这些信息配置到用户属性列表中。key为属性名,value为属性的值。
[UserInfoManager configInfo:infoDic];
(2)该方法将字典中的所有key值都取出,根据这些key值构造不同属性的setter方法,并调用构造好的setter方法。
问题:调用属性的setter方法,是如何将属性的值存储到用户偏好设置列表中的呢???!
(3) 其实解决这个问题是使用了runtime中的一些功能方法,真不愧为iOS中的黑魔法啊,实际用起来还是非常爽的。
如果对runtime并不是很熟悉,可以相互学习和交流,在此就不着重讲解runtime的相关知识,只简单讲解对工具类中出现的功能的实现。
在+load{ }方法中对所有属性的setter方法都进行替换,替换为我们自己定义的setter方法setMyAttribute:;这时,当我们对工具类进行属性设置的时候,会调用相应属性的setter方法,因为我们把最原始的setter方法替换成了自定义的setMyAttribute:方法,此时会触发setMyAttribute方法;在该方法中,我们可以拿到原本方法的名称(通过_cmd),我们根据原本的setter方法名进行字符串的剖析会知道相应属性,这时已经是万事具备了,属性的名称有了,属性的值也有了(参数即是属性的值)。哈哈哈,是不是内心小开心了一把,通过key-value,将信息存储到本地的用户偏好设置中。ok,就这么轻松的搞定了~~~~
(4)当然,取数据的时候,也是通过交换方法的方式,将存储在本地的数据取出来;在这里就不啰嗦了。
4..登出操作,当用户退出登录或者用户信息过期被下线,以及在其他地方登录挤下线。都可以调用登出操作方法,将本地的所有用户的信息都清除掉
文采不好,可能讲述的不太清楚,希望大家多多提建议。该类中多处涉及到runtime的相关知识,在使用的时候记得不要忘记导入 <objc/runtime.h>文件喔~~~~
如果有对runtime感兴趣的小伙伴,可以留下联系方式一同交流学习。
附上代码的github地址:github.com/tandepeng/UserInfoManager.git
网友评论
[manager performSelector:setSeletor withObject:value];
}
在构造完setter方法之后,判断对象是否响应该setter方法。如果不响应的话,说明工具类中不含有该属性。