// // 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 @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 *_property; + (instancetype)logout { [self dynamicInit]; // 删除本地用户信息 [[NSFileManager defaultManager] removeItemAtPath:self.userInfoPath error:nil]; return _userInfoInstance; } + (NSDictionary *)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