You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

171 lines
4.8 KiB

//
// TFUserInfoManager.m
// WXReader
//
// Created by 谢腾飞 on 2020/12/3.
// Copyright © 2020 xtfei_2011@126.com. All rights reserved.
//
#import "TFUserInfoManager.h"
#import "NSObject+Utils.h"
#import <ShareSDK/ShareSDK.h>
@implementation TFUserInfoManager
static TFUserInfoManager *_userInfoInstance;
+ (instancetype)shareInstance
{
return [[self alloc] init];
}
+ (instancetype)allocWithZone:(struct _NSZone *)zone
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_userInfoInstance = [super allocWithZone:zone];
_userInfoInstance = [self dynamicInit];
});
return _userInfoInstance;
}
- (instancetype)init
{
if ([[NSFileManager defaultManager] fileExistsAtPath:TFUserInfoManager.userInfoPath] && kObjectIsEmpty(_userInfoInstance.token)) {
_userInfoInstance = [NSKeyedUnarchiver unarchiveObjectWithFile:TFUserInfoManager.userInfoPath];
}
return _userInfoInstance;
}
- (id)copyWithZone:(NSZone *)zone
{
return _userInfoInstance;
}
- (id)mutableCopyWithZone:(NSZone *)zone
{
return _userInfoInstance;
}
+ (BOOL)isLogin
{
return !kObjectIsEmpty([[self shareInstance] token]);
}
static NSDictionary<NSString *, NSString *> *_property;
+ (instancetype)logout
{
[self dynamicInit];
// 删除本地用户信息
[[NSFileManager defaultManager] removeItemAtPath:self.userInfoPath error:nil];
return _userInfoInstance;
}
+ (NSDictionary<NSString *, id> *)modelCustomPropertyMapper
{
return @{
@"token" : @"user_token",
@"vip" : @"is_vip",
@"masterRemain" : @"goldRemain",
@"subRemain" : @"silverRemain",
@"totalRemain" : @"remain"
};
}
/// 动态初始化Model所有值,避免Null、nil
+ (instancetype)dynamicInit
{
if (_userInfoInstance == nil) _userInfoInstance = [self shareInstance];
// 动态获取属性列表,遍历属性并初始化.
_property = _property ? : [self propertyDict];
[_property enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, NSString * _Nonnull value, BOOL * _Nonnull stop) {
SEL sel = [TFUtilsHelper createSetterWithPropertyName:key];
if ([_userInfoInstance respondsToSelector:sel]) {
Class t_class = NSClassFromString(value);
[self updateWithSel:sel obj:[t_class new]];
}
}];
return _userInfoInstance;
}
+ (instancetype)updateWithDict:(NSDictionary *)dict
{
if (_userInfoInstance == nil) _userInfoInstance = [self shareInstance];
// 动态获取属性列表,遍历并更新属性
_property = _property ? : [self propertyDict];
[_property enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, NSString * _Nonnull value, BOOL * _Nonnull stop) {
SEL sel = [TFUtilsHelper createSetterWithPropertyName:key];
if ([_userInfoInstance respondsToSelector:sel]) {
NSDictionary *t_dict = [self modelCustomPropertyMapper];
id t_name = t_dict[key];
if ([t_name isKindOfClass:NSArray.class]) {
for (NSString *obj in t_name) {
[self updateWithSel:sel obj:dict[obj]];
}
} else if ([t_name isKindOfClass:NSString.class]) {
[self updateWithSel:sel obj:dict[t_name]];
} else {
[self updateWithSel:sel obj:dict[key]];
}
}
}];
// 删除本地用户信息
[[NSFileManager defaultManager] removeItemAtPath:self.userInfoPath error:nil];
// 保存用户信息到本地
[NSKeyedArchiver archiveRootObject:_userInfoInstance toFile:self.userInfoPath];
return _userInfoInstance;
}
+ (void)updateWithSel:(SEL)sel obj:(id)obj
{
if (!obj) return;
if ([obj isKindOfClass:NSNumber.class]) {
NSNumber *number = obj;
((void (*)(id, SEL, uint64_t))(void *) objc_msgSend)((id)_userInfoInstance, sel, (uint64_t)number.longLongValue);
return;
}
((void (*)(id, SEL, id))(void *) objc_msgSend)((id)_userInfoInstance, sel, obj);
}
+ (void)initialize
{
[[NSNotificationCenter defaultCenter] addObserver:self.class selector:@selector(logout) name:Notification_Logout object:nil];
}
+ (instancetype)modelWithDictionary:(NSDictionary *)dictionary
{
_userInfoInstance = [super modelWithDictionary:dictionary];
[NSKeyedArchiver archiveRootObject:_userInfoInstance toFile:self.userInfoPath];
return _userInfoInstance;
}
- (instancetype)initWithCoder:(NSCoder *)coder
{
return [self modelInitWithCoder:coder];
}
- (void)encodeWithCoder:(NSCoder *)coder
{
[self modelEncodeWithCoder:coder];
}
+ (NSString *)userInfoPath
{
return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject stringByAppendingPathComponent:@"userInfo"];
}
@end