// // YMGiftStorage.m // YUMI // // Created by YUMI on 2021/11/17. // #import "XPGiftStorage.h" #import "GiftInfoModel.h" #import "NSObject+MJExtension.h" #import "NSArray+Safe.h" @interface XPGiftStorage () ///key: 房间id value:房间对应的所有礼物列表,default 表示無房間 id 的默認禮物列表 @property (nonatomic, strong) NSCache *> *roomGiftCache; ///包括面板 tab 和所有禮物的數據 @property (nonatomic, strong) NSCache *> *roomGiftPanelTagsCache; ///当前房间的uid @property (atomic, copy) NSString *currentRoomUid; @end @implementation XPGiftStorage + (instancetype)shareStorage { static dispatch_once_t onceToken; static XPGiftStorage * storage; dispatch_once(&onceToken, ^{ storage = [[XPGiftStorage alloc] init]; }); return storage; } - (NSString *)defaultKey { return @"default"; } ///只保存所有禮物數據, - (void)saveGiftDatasource:(NSArray *)giftArray roomUid:(NSString *)roomUid { if (giftArray.count > 0 && roomUid.length > 0) { // 確保排序,後續使用二分法查找 NSArray *sortedGiftLists = [giftArray sortedArrayUsingComparator:^NSComparisonResult(GiftInfoModel *obj1, GiftInfoModel *obj2) { NSComparisonResult result = [@(obj1.seqNo) compare:@(obj2.seqNo)]; if (result == NSOrderedSame) { return [@(obj2.giftId) compare:@(obj1.giftId)]; } return result; }]; @synchronized (self.roomGiftCache) { [self.roomGiftCache setObject:sortedGiftLists forKey:roomUid]; } } } ///保存 tabs 和所tab 下相關禮物數據 - (void)saveGiftPanelTagsDatasource:(NSArray *)tagsArray roomUid:(NSString *)roomUid { if (tagsArray.count > 0 && roomUid.length > 0) { [self.roomGiftPanelTagsCache setObject:tagsArray forKey:roomUid]; } } ///獲取全部禮物數據 - (NSArray *)getGiftDatasource:(NSString *)roomUid { if (roomUid.length > 0) { self.currentRoomUid = roomUid; NSArray *giftLists = [self.roomGiftCache objectForKey:roomUid]; if (giftLists.count > 0) { return giftLists; } else { giftLists = [self.roomGiftCache objectForKey:[self defaultKey]]; return giftLists; } } return nil; } ///獲取 tabs 和所tab 下相關禮物數據 - (NSArray *)getGiftPanelTagsDatasource:(NSString *)roomUid { if (roomUid.length > 0) { self.currentRoomUid = roomUid; NSArray *tagsList = [self.roomGiftPanelTagsCache objectForKey:roomUid]; if (tagsList.count > 0) { return tagsList; } else { return [self.roomGiftPanelTagsCache objectForKey:[self defaultKey]]; } } return nil; } /// 获取当前房间的数据中的礼物 /// @param giftId 礼物的id - (GiftInfoModel *)findGiftInfo:(NSString *)giftId inRoom:(NSString *)roomUid { NSInteger giftIdInt = giftId.integerValue; NSArray *giftLists = [self getGiftDatasource:roomUid]; if (giftLists.count == 0) return nil; // 改用字典查询 static NSCache *> *giftIdMapCache; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ giftIdMapCache = [[NSCache alloc] init]; giftIdMapCache.countLimit = 100; // 设置合理的缓存限制 }); __block NSDictionary *giftMap = [giftIdMapCache objectForKey:roomUid]; if (!giftMap) { // 构建映射表 NSMutableDictionary *map = [NSMutableDictionary new]; for (GiftInfoModel *gift in giftLists) { map[@(gift.giftId)] = gift; } NSDictionary *newGiftMap = [map copy]; [giftIdMapCache setObject:newGiftMap forKey:roomUid]; giftMap = newGiftMap; } return giftMap[@(giftIdInt)]; } - (NSCache *> *)roomGiftCache { if (!_roomGiftCache) { _roomGiftCache = [[NSCache alloc] init]; // 设置缓存数据的数目 // _roomGiftCache.countLimit = 50; } return _roomGiftCache; } - (NSCache *> *)roomGiftPanelTagsCache { if (!_roomGiftPanelTagsCache) { _roomGiftPanelTagsCache = [[NSCache alloc] init]; // 设置缓存数据的数目 _roomGiftPanelTagsCache.countLimit = 50; } return _roomGiftPanelTagsCache; } - (void)updateRoomUID:(NSString *)roomUID { self.currentRoomUid = roomUID; } ///處理 API 數據,分別緩存所有禮物和 tab/tab禮物 - (NSArray *)cacheTagsWith:(NSDictionary *)response inRoom:(NSString *)roomUid { NSArray *tabModels = [GiftPanelTabModel modelsWithArray:response[@"tabList"]]; NSDictionary *contents = response; if ([[response allKeys] containsObject:@"giftTabMap"]) { contents = [response objectForKey:@"giftTabMap"]; } NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"seq" ascending:YES]; NSMutableArray *mutableTabs = [tabModels sortedArrayUsingDescriptors:@[sortDescriptor]].mutableCopy; // 构建每个 Tab 下的礼物 for (GiftPanelTabModel *model in mutableTabs) { NSString *key = model.key; NSArray *giftsArray = [contents objectForKey:key]; if (giftsArray.count > 0) { NSArray *giftModels = [GiftInfoModel modelsWithArray:giftsArray]; model.gifts = giftModels; } } // 所有礼物,福袋爆出的礼物会从这里获取 NSMutableArray *totalInfo = [NSMutableArray array]; for (NSString *key in contents) { NSArray *giftModels = [GiftInfoModel modelsWithArray:[contents objectForKey:key]]; [totalInfo addObjectsFromArray:giftModels]; } [self saveGiftDatasource:totalInfo roomUid:roomUid]; [self saveGiftPanelTagsDatasource:mutableTabs roomUid:roomUid]; self.currentRoomUid = roomUid; return mutableTabs; } - (NSArray *)getRoomGiftDatasource:(NSString *)roomUid { return [self getCachedData:self.roomGiftCache forKey:roomUid] ?: @[]; } - (NSArray *)getCachedData:(NSCache *)cache forKey:(NSString *)key { NSArray *data = [cache objectForKey:key]; return data ?: [cache objectForKey:[self defaultKey]]; } @end