小说绘上架版本

This commit is contained in:
xtfei2011
2021-02-07 11:24:08 +08:00
commit ee5c1c8b12
1762 changed files with 115892 additions and 0 deletions
@@ -0,0 +1,56 @@
//
// TFUserInfoManager.h
// WXReader
//
// Created by 谢腾飞 on 2020/12/3.
// Copyright © 2020 xtfei_2011@126.com. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface TFUserInfoManager : NSObject<NSCopying, NSMutableCopying>
@property (nonatomic ,copy) NSString *token;
@property (nonatomic ,assign) NSInteger uid;
@property (nonatomic ,copy) NSString *nickname;
@property (nonatomic ,copy) NSString *mobile;
@property (nonatomic ,copy) NSString *avatar;
/// 0:未知,1:女,2:男
@property (nonatomic ,assign) NSInteger gender;
@property (nonatomic ,assign ,getter = isVip) BOOL vip;
/// 主货币余额
@property (nonatomic ,assign) NSInteger masterRemain;
/// 子货币余额
@property (nonatomic ,assign) NSInteger subRemain;
/// 月票余额
@property (nonatomic ,assign) NSInteger ticketRemain;
/// 总余额
@property (nonatomic ,assign) NSInteger totalRemain;
/// 自动订阅开启状态
@property (nonatomic ,assign) BOOL auto_sub;
/// 登录状态
@property (nonatomic ,assign ,class ,readonly ,getter = isLogin) BOOL login;
/// 更新Model数据,会自动同步本地数据。
+ (instancetype)updateWithDict:(NSDictionary *)dict;
+ (instancetype)shareInstance;
+ (instancetype)logout;
+ (instancetype)allocWithZone:(struct _NSZone *)zone UNAVAILABLE_ATTRIBUTE;
+ (instancetype)alloc UNAVAILABLE_ATTRIBUTE;
+ (instancetype)new UNAVAILABLE_ATTRIBUTE;
@end
NS_ASSUME_NONNULL_END
@@ -0,0 +1,171 @@
//
// 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