小说绘上架版本
This commit is contained in:
+79
@@ -0,0 +1,79 @@
|
||||
//
|
||||
// TFReadRecordManager.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
|
||||
|
||||
@class TFBookMarkModel;
|
||||
@interface TFReadRecordManager : NSObject
|
||||
|
||||
+ (instancetype)shareManagerWithProductionType:(TFProductionType)productionType;
|
||||
|
||||
// 添加阅读记录
|
||||
- (BOOL)addReadingRecordWithProduction_id:(NSInteger)production_id chapter_id:(NSInteger)chapter_id chapterTitle:(NSString *)chapterTitle;
|
||||
|
||||
// 获取某个作品当前阅读章节id
|
||||
- (NSInteger)getReadingRecordChapter_idWithProduction_id:(NSInteger)production_id;
|
||||
|
||||
// 获取某个作品当前阅读章节名称
|
||||
- (NSString *)getReadingRecordChapterTitleWithProduction_id:(NSInteger)production_id;
|
||||
|
||||
// 作品章节是否已读
|
||||
- (BOOL)chapterHasReadedWithProduction_id:(NSInteger)production_id chapter_id:(NSInteger)chapter_id;
|
||||
|
||||
// 作品是否已读
|
||||
- (BOOL)productionHasReadedWithProduction_id:(NSInteger)production_id;
|
||||
|
||||
// 设置漫画阅读记录(仅限漫画使用)
|
||||
- (void)setComicReadingRecord:(NSInteger)comic_id chapter_id:(NSInteger)chapter_id offsetY:(CGFloat)offsetY;
|
||||
|
||||
/// 获取漫画阅读记录(章节ID :offsetY)(仅限漫画使用)
|
||||
- (NSDictionary *)getComicReadingRecord:(NSInteger)comic_id;
|
||||
|
||||
// 设置播放器进度(仅限有声功能使用)
|
||||
- (void)addPlayingProgress:(CGFloat)progress production_id:(NSInteger)production_id chapter_id:(NSInteger)chapter_id;
|
||||
|
||||
// 播放作品进度(仅限有声功能使用)
|
||||
- (CGFloat)getPlayingProgressWithProduction_id:(NSInteger)production_id chapter_id:(NSInteger)chapter_id;
|
||||
|
||||
// 是否是当前正在播放的作品(仅限有声功能使用)
|
||||
- (BOOL)isCurrentPlayingProductionWithProduction_id:(NSInteger)production_id;
|
||||
|
||||
// 是否是当前正在播放的章节(仅限有声功能使用)
|
||||
- (BOOL)isCurrentPlayingChapterWithProduction_id:(NSInteger)production_id chapter_id:(NSInteger)chapter_id;
|
||||
|
||||
/* 添加书签
|
||||
@param bookID 书籍ID
|
||||
@param chapterID 章节ID
|
||||
@param chapterSort 章节索引
|
||||
@param chapterTitle 章节标题
|
||||
@param chapterContent 章节内容
|
||||
@param pageContent 当前页内容
|
||||
**/
|
||||
+ (TFBookMarkModel *)addBookMark:(NSString *)bookID chapterID:(NSString *)chapterID chapterSort:(NSInteger)chapterSort chapterTitle:(NSString *)chapterTitle chapterContent:(NSString *)chapterContent pageContent:(NSString *)pageContent;
|
||||
|
||||
/* 获取书籍所有书签
|
||||
@param bookID 书籍ID
|
||||
**/
|
||||
+ (NSArray<TFBookMarkModel *> *)bookMark:(NSString *)bookID;
|
||||
|
||||
/* 获取章节所有书签
|
||||
@param bookID 书籍ID
|
||||
@param chapterID 章节ID
|
||||
**/
|
||||
+ (NSArray<TFBookMarkModel *> *)bookMark:(NSString *)bookID chapterID:(NSString *)chapterID;
|
||||
|
||||
/* 删除指定书签
|
||||
@param markModel 书签Model
|
||||
**/
|
||||
+ (void)removeBookMark:(TFBookMarkModel *)markModel;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
+350
@@ -0,0 +1,350 @@
|
||||
//
|
||||
// TFReadRecordManager.m
|
||||
// WXReader
|
||||
//
|
||||
// Created by 谢腾飞 on 2020/12/3.
|
||||
// Copyright © 2020 xtfei_2011@126.com. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TFReadRecordManager.h"
|
||||
#import "TFBookMarkModel.h"
|
||||
|
||||
// 当前正在阅读作品id key
|
||||
#define current_read_production_id_cache_key(type) ([NSString stringWithFormat:@"%@_%@", @"UkhU98p5", [TFUtilsHelper formatStringWithInteger:type]])
|
||||
|
||||
// 某个作品正在阅读的章节标题 key
|
||||
#define current_read_production_title_cache_key(type, production_id) ([NSString stringWithFormat:@"%@%@%@", @"SOdYb5CO", [TFUtilsHelper formatStringWithInteger:type], [TFUtilsHelper formatStringWithInteger:production_id]])
|
||||
|
||||
// 某个作品正在阅读的章节id
|
||||
#define current_read_chapter_id_cache_key(type, production_id) ([NSString stringWithFormat:@"%@_%@_%@", @"KBOwoFvR", [TFUtilsHelper formatStringWithInteger:type], [TFUtilsHelper formatStringWithInteger:production_id]])
|
||||
|
||||
// 某个章节的播放进度 key
|
||||
#define current_playing_chapter_progress(type, production_id) ([NSString stringWithFormat:@"%@_%@_%@", @"TLIo2gaz", [TFUtilsHelper formatStringWithInteger:type], [TFUtilsHelper formatStringWithInteger:production_id]])
|
||||
|
||||
// 某个章节是否已读 key
|
||||
#define has_readed_cache_key(type, production_id ) ([NSString stringWithFormat:@"%@%@%@", @"KNU5HliF", [TFUtilsHelper formatStringWithInteger:type], [TFUtilsHelper formatStringWithInteger:production_id]])
|
||||
|
||||
@interface TFReadRecordManager ()
|
||||
|
||||
@property (nonatomic ,strong) NSMutableDictionary *readRecordDictionary;
|
||||
|
||||
@end
|
||||
|
||||
@implementation TFReadRecordManager
|
||||
|
||||
static TFProductionType _productionType;
|
||||
static TFReadRecordManager *_instance_record;
|
||||
|
||||
+ (instancetype)shareManagerWithProductionType:(TFProductionType)productionType
|
||||
{
|
||||
static dispatch_once_t once_token_record;
|
||||
dispatch_once(&once_token_record, ^{
|
||||
_instance_record = [[self alloc] init];
|
||||
});
|
||||
|
||||
_productionType = productionType;
|
||||
|
||||
return _instance_record;
|
||||
}
|
||||
|
||||
// 添加阅读记录
|
||||
- (BOOL)addReadingRecordWithProduction_id:(NSInteger)production_id chapter_id:(NSInteger)chapter_id chapterTitle:(NSString *)chapterTitle
|
||||
{
|
||||
// 记录当前正在阅读作品id
|
||||
[self.readRecordDictionary setObject:[TFUtilsHelper formatStringWithInteger:production_id] forKey:current_read_production_id_cache_key(_productionType)];
|
||||
|
||||
// 记录当前正在阅读章节id
|
||||
[self.readRecordDictionary setObject:[TFUtilsHelper formatStringWithInteger:chapter_id] forKey:current_read_chapter_id_cache_key(_productionType, production_id)];
|
||||
|
||||
// 记录当前阅读章节名称
|
||||
[self.readRecordDictionary setObject:chapterTitle?:@"" forKey:current_read_production_title_cache_key(_productionType, production_id)];
|
||||
|
||||
// 设置已读作品
|
||||
if (![self chapterHasReadedWithProduction_id:production_id chapter_id:chapter_id]) {
|
||||
NSMutableDictionary *t_dic = [[self.readRecordDictionary objectForKey:has_readed_cache_key(_productionType, production_id)] mutableCopy];
|
||||
if (!t_dic) {
|
||||
t_dic = [NSMutableDictionary dictionary];
|
||||
}
|
||||
[t_dic setObject:@"1" forKey:[TFUtilsHelper formatStringWithInteger:chapter_id]];
|
||||
|
||||
[self.readRecordDictionary setObject:[t_dic copy] forKey:has_readed_cache_key(_productionType, production_id)];
|
||||
}
|
||||
|
||||
return [self writeToPlistFile];
|
||||
}
|
||||
|
||||
// 获取某个作品当前阅读章节id
|
||||
- (NSInteger)getReadingRecordChapter_idWithProduction_id:(NSInteger)production_id
|
||||
{
|
||||
NSString *chapter_id_string = [self.readRecordDictionary objectForKey:current_read_chapter_id_cache_key(_productionType, production_id)];
|
||||
return [chapter_id_string integerValue];
|
||||
}
|
||||
|
||||
// 获取某个作品当前阅读章节名称
|
||||
- (NSString *)getReadingRecordChapterTitleWithProduction_id:(NSInteger)production_id
|
||||
{
|
||||
NSString *chapter_id_string = [self.readRecordDictionary objectForKey:current_read_production_title_cache_key(_productionType, production_id)];
|
||||
return chapter_id_string;
|
||||
}
|
||||
|
||||
// 作品章节是否已读
|
||||
- (BOOL)chapterHasReadedWithProduction_id:(NSInteger)production_id chapter_id:(NSInteger)chapter_id
|
||||
{
|
||||
NSMutableDictionary *t_dic = [[self.readRecordDictionary objectForKey:has_readed_cache_key(_productionType, production_id)] mutableCopy];
|
||||
if (t_dic.count == 0) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
return [t_dic objectForKey:[TFUtilsHelper formatStringWithInteger:chapter_id]]?YES:NO;
|
||||
}
|
||||
|
||||
// 作品是否已读
|
||||
- (BOOL)productionHasReadedWithProduction_id:(NSInteger)production_id
|
||||
{
|
||||
NSMutableDictionary *t_dic = [[self.readRecordDictionary objectForKey:has_readed_cache_key(_productionType, production_id)] mutableCopy];
|
||||
if (t_dic.count == 0) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
// 设置播放器进度(仅限有声功能使用)
|
||||
- (void)addPlayingProgress:(CGFloat)progress production_id:(NSInteger)production_id chapter_id:(NSInteger)chapter_id
|
||||
{
|
||||
NSMutableDictionary *t_dic = [[self.readRecordDictionary objectForKey:current_playing_chapter_progress(_productionType, production_id)] mutableCopy];
|
||||
if (!t_dic) {
|
||||
t_dic = [NSMutableDictionary dictionary];
|
||||
}
|
||||
[t_dic setObject:[TFUtilsHelper formatStringWithFloat:progress] forKey:[TFUtilsHelper formatStringWithInteger:chapter_id]];
|
||||
|
||||
[self.readRecordDictionary setObject:[t_dic copy] forKey:current_playing_chapter_progress(_productionType, production_id)];
|
||||
}
|
||||
|
||||
// 播放作品进度(仅限有声功能使用)
|
||||
- (CGFloat)getPlayingProgressWithProduction_id:(NSInteger)production_id chapter_id:(NSInteger)chapter_id
|
||||
{
|
||||
NSDictionary *t_dic = [[self.readRecordDictionary objectForKey:current_playing_chapter_progress(_productionType, production_id)] copy];
|
||||
|
||||
NSString *progress = [t_dic objectForKey:[TFUtilsHelper formatStringWithInteger:chapter_id]];
|
||||
if (progress && progress.length > 0) {
|
||||
|
||||
if ([progress floatValue] > 0.95) {
|
||||
return 0;
|
||||
}
|
||||
return [progress floatValue];
|
||||
}
|
||||
return 0.f;
|
||||
}
|
||||
|
||||
// 是否是当前正在播放的作品(仅限有声功能使用)
|
||||
- (BOOL)isCurrentPlayingProductionWithProduction_id:(NSInteger)production_id
|
||||
{
|
||||
if ([[self.readRecordDictionary objectForKey:current_read_production_id_cache_key(_productionType)] isEqualToString:[TFUtilsHelper formatStringWithInteger:production_id]]) {
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
// 是否是当前正在播放的章节(仅限有声功能使用)
|
||||
- (BOOL)isCurrentPlayingChapterWithProduction_id:(NSInteger)production_id chapter_id:(NSInteger)chapter_id
|
||||
{
|
||||
if ([self getReadingRecordChapter_idWithProduction_id:production_id] == chapter_id) {
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (NSMutableDictionary *)readRecordDictionary
|
||||
{
|
||||
if (!_readRecordDictionary) {
|
||||
_readRecordDictionary = [NSMutableDictionary dictionary];
|
||||
}
|
||||
|
||||
NSMutableDictionary *t_dic = [_readRecordDictionary objectForKey:[NSString stringWithFormat:@"%@", [TFUtilsHelper formatStringWithInteger:_productionType]]];
|
||||
if (!t_dic) {
|
||||
t_dic = [NSMutableDictionary dictionaryWithContentsOfFile:[self cacheFilePath]];
|
||||
[_readRecordDictionary setObject:t_dic forKey:[NSString stringWithFormat:@"%@", [TFUtilsHelper formatStringWithInteger:_productionType]]];
|
||||
}
|
||||
|
||||
return t_dic;
|
||||
}
|
||||
|
||||
- (NSString *)cacheFilePath
|
||||
{
|
||||
NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectOrNilAtIndex:0];
|
||||
NSString *rootFloderPath = [documentPath stringByAppendingPathComponent:[@"WXYZ_ReadingRecordFileFloder" md5String]];
|
||||
// 创建章节文件夹
|
||||
if (![[NSFileManager defaultManager] fileExistsAtPath:rootFloderPath]) {
|
||||
[[NSFileManager defaultManager] createDirectoryAtPath:rootFloderPath withIntermediateDirectories:YES attributes:nil error:nil];
|
||||
}
|
||||
|
||||
NSString *cacheFilePath = @"";
|
||||
switch (_productionType) {
|
||||
case TFProductionTypeNovel:
|
||||
cacheFilePath = [rootFloderPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.plist", [@"BookReadingRecordFile" md5String]]];
|
||||
break;
|
||||
case TFProductionTypeComic:
|
||||
cacheFilePath = [rootFloderPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.plist", [@"ComicReadingRecordFile" md5String]]];
|
||||
break;
|
||||
case TFProductionTypeAudio:
|
||||
cacheFilePath = [rootFloderPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.plist", [@"AudioReadingRecordFile" md5String]]];
|
||||
break;
|
||||
case TFProductionTypeAi:
|
||||
cacheFilePath = [rootFloderPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.plist", [@"AiReadingRecordFile" md5String]]];
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (![[NSFileManager defaultManager] fileExistsAtPath:cacheFilePath]) {
|
||||
[@{} writeToFile:cacheFilePath atomically:NO];
|
||||
}
|
||||
|
||||
return cacheFilePath;
|
||||
}
|
||||
|
||||
// 写入文件
|
||||
- (BOOL)writeToPlistFile
|
||||
{
|
||||
NSDictionary *t_dic = [self.readRecordDictionary copy];
|
||||
if (t_dic.count == 0) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
// 写入文件
|
||||
if (![t_dic writeToFile:[self cacheFilePath] atomically:NO]) {
|
||||
return NO;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
+ (TFBookMarkModel *)addBookMark:(NSString *)bookID chapterID:(NSString *)chapterID chapterSort:(NSInteger)chapterSort chapterTitle:(NSString *)chapterTitle chapterContent:(NSString *)chapterContent pageContent:(NSString *)pageContent
|
||||
{
|
||||
NSString *fullPath = [[self bookMarkRootPath] stringByAppendingFormat:@"/bookMark_%@.plist", bookID];
|
||||
NSMutableDictionary *t_dict = [NSMutableDictionary dictionaryWithContentsOfFile:fullPath];
|
||||
if (!t_dict) {
|
||||
t_dict = [NSMutableDictionary dictionary];
|
||||
}
|
||||
|
||||
NSMutableArray<NSString *> *t_arr = t_dict[chapterID];
|
||||
if (!t_arr) {
|
||||
t_arr = [NSMutableArray array];
|
||||
}
|
||||
|
||||
TFBookMarkModel *t_model = [[TFBookMarkModel alloc] init];
|
||||
t_model.chapterID = chapterID;
|
||||
t_model.chapterSort = chapterSort;
|
||||
t_model.chapterTitle = chapterTitle;
|
||||
t_model.timestamp = [TFUtilsHelper getTimeStamp];
|
||||
t_model.pageContent = pageContent;
|
||||
t_model.bookID = bookID;
|
||||
t_model.specificIndex = [chapterContent rangeOfString:pageContent].location;
|
||||
// 将Model转换成String
|
||||
NSString *bookMark = [t_model modelToJSONString];
|
||||
|
||||
[t_arr addObject:bookMark];
|
||||
[t_dict setValue:t_arr forKey:chapterID];
|
||||
|
||||
[t_dict writeToFile:fullPath atomically:YES];
|
||||
|
||||
return t_model;
|
||||
}
|
||||
|
||||
+ (NSArray<TFBookMarkModel *> *)bookMark:(NSString *)bookID
|
||||
{
|
||||
NSString *fullPath = [[self bookMarkRootPath] stringByAppendingFormat:@"/bookMark_%@.plist", bookID];
|
||||
if (![[NSFileManager defaultManager] fileExistsAtPath:fullPath]) return @[];
|
||||
|
||||
NSMutableDictionary *t_dict = [NSMutableDictionary dictionaryWithContentsOfFile:fullPath];
|
||||
NSMutableArray<TFBookMarkModel *> *markArr = [NSMutableArray array];
|
||||
for (NSString *key in t_dict) {
|
||||
NSArray<NSString *> *t_arr = t_dict[key];
|
||||
for (NSString *obj in t_arr) {
|
||||
NSDictionary *dict = [TFUtilsHelper dictionaryWithJsonString:obj];
|
||||
TFBookMarkModel *t_model = [TFBookMarkModel modelWithDictionary:dict];
|
||||
[markArr addObject:t_model];
|
||||
}
|
||||
}
|
||||
|
||||
return markArr;
|
||||
}
|
||||
|
||||
+ (NSArray<TFBookMarkModel *> *)bookMark:(NSString *)bookID chapterID:(NSString *)chapterID
|
||||
{
|
||||
NSString *fullPath = [[self bookMarkRootPath] stringByAppendingFormat:@"/bookMark_%@.plist", bookID];
|
||||
if (![[NSFileManager defaultManager] fileExistsAtPath:fullPath]) return @[];
|
||||
|
||||
NSMutableDictionary *t_dict = [NSMutableDictionary dictionaryWithContentsOfFile:fullPath];
|
||||
NSArray<NSString *> *t_arr = t_dict[chapterID];
|
||||
if (!t_arr) return @[];
|
||||
|
||||
NSMutableArray<TFBookMarkModel *> *markArr = [NSMutableArray array];
|
||||
for (NSString *obj in t_arr) {
|
||||
NSDictionary *dict = [TFUtilsHelper dictionaryWithJsonString:obj];
|
||||
TFBookMarkModel *t_model = [TFBookMarkModel modelWithDictionary:dict];
|
||||
[markArr addObject:t_model];
|
||||
}
|
||||
|
||||
return markArr;
|
||||
}
|
||||
|
||||
+ (void)removeBookMark:(TFBookMarkModel *)markModel
|
||||
{
|
||||
NSString *fullPath = [[self bookMarkRootPath] stringByAppendingFormat:@"/bookMark_%@.plist", markModel.bookID];
|
||||
if (![[NSFileManager defaultManager] fileExistsAtPath:fullPath]) return;
|
||||
|
||||
NSMutableDictionary *t_dict = [NSMutableDictionary dictionaryWithContentsOfFile:fullPath];
|
||||
NSMutableArray<NSString *> *t_arr = t_dict[markModel.chapterID];
|
||||
if (!t_arr) return;
|
||||
|
||||
NSString *bookMark = [markModel modelToJSONString];
|
||||
[t_arr removeObject:bookMark];
|
||||
[t_dict setValue:t_arr forKey:markModel.chapterID];
|
||||
[t_dict writeToFile:fullPath atomically:YES];
|
||||
}
|
||||
|
||||
+ (NSString *)bookMarkRootPath
|
||||
{
|
||||
NSString *rootPath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject;
|
||||
rootPath = [rootPath stringByAppendingPathComponent:@"bookMark"];
|
||||
if (![[NSFileManager defaultManager] fileExistsAtPath:rootPath]) {
|
||||
[[NSFileManager defaultManager] createDirectoryAtPath:rootPath withIntermediateDirectories:YES attributes:@{} error:nil];
|
||||
}
|
||||
return rootPath;
|
||||
}
|
||||
|
||||
- (void)setComicReadingRecord:(NSInteger)comic_id chapter_id:(NSInteger)chapter_id offsetY:(CGFloat)offsetY
|
||||
{
|
||||
NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
|
||||
path = [path stringByAppendingPathComponent:@"comic_record.plist"];
|
||||
if (![[NSFileManager defaultManager] fileExistsAtPath:path]) {
|
||||
[[NSFileManager defaultManager] createFileAtPath:path contents:[NSData data] attributes:@{}];
|
||||
}
|
||||
|
||||
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithContentsOfFile:path];
|
||||
if (!dict) {
|
||||
dict = [NSMutableDictionary dictionary];
|
||||
}
|
||||
NSDictionary *params = @{
|
||||
[NSString stringWithFormat:@"%zd", chapter_id] : [NSString stringWithFormat:@"%f", offsetY]
|
||||
};
|
||||
[dict setValue:params forKey:[NSString stringWithFormat:@"%zd", comic_id]];
|
||||
[dict writeToFile:path atomically:NO];
|
||||
}
|
||||
|
||||
- (NSDictionary *)getComicReadingRecord:(NSInteger)comic_id
|
||||
{
|
||||
NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
|
||||
path = [path stringByAppendingPathComponent:@"comic_record.plist"];
|
||||
if (![[NSFileManager defaultManager] fileExistsAtPath:path]) return @{};
|
||||
|
||||
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];
|
||||
if ([dict valueForKey:[NSString stringWithFormat:@"%zd", comic_id]]) {
|
||||
return [dict valueForKey:[NSString stringWithFormat:@"%zd", comic_id]];
|
||||
} else {
|
||||
return @{};
|
||||
}
|
||||
}
|
||||
@end
|
||||
Reference in New Issue
Block a user