需求
这两个获取一个需求,需要做一个打卡列表,显示上个月所有打卡的信息,及这个月到今天的的打卡信息,并且标注出来月份。设计界面大致如此:
需求图片后台接口只能返回已经打卡的信息。如果当天没有打卡,是不返回的。
//接口返回数据结构
"data": [
{
"signLastTime": 1522199821084, //当天最后一次打卡时间
"signMonth": 3, //当天属于几月
"week": "周三", //当天属于周几
"inDate": 1522199817934, //数据库返回时间,本地无用
"signDay": 28, //当天属于几号
"signItems": [ //当天打卡次数,返回每次打卡数据
{
"longitude": 123566, //经度
"signAdress": "北京市海淀区上地地铁口", //地址
"signTime": 1522199817934, //打卡时间
"latitude": 456233 //纬度
},
{
"longitude": 456233,
"signAdress": "北京市海淀区西直门地铁口",
"signTime": 1522199821084,
"latitude": 123566
}
],
"reDate": 1522199821084, //数据库返回时间,无用
"signYear": 2018, //本次打卡数据年份
"id": "5abaed0923130b394c1e10ce", //id
"signFirstTime": 1522199817934, //当天首次打卡时间
"userId": 111225, //打卡人id
"status": 1 //客户端无用
}
大家可以先不看我的解决方法,自己思考一下如何来写这个算法,才能达到最优。
我的解决方案
声明一下,我的解决方案可能不是最优的,如果有好的想法,我们在留言可以一起讨论。
- 按照后台接口返回,创建model类。
- 创建一个config类,通过后台返回数据,返回能被tableView解析显示的数据。
config作为配置类,所有的算法配置写在这个类中。类大概是
思路:
- 通过获取当月到今天的天数 currentMonthDay,在获取上个月总天数lastMonthDay。
- 使用for循环来循环,次数 = currentMonthDay + lastMonthDay, 来生成一个只包含'yyyy-MM-dd'字符串类型的数组【数组A】,生成一个字典包含key: 是上面的字符串,value:model的类【字典A】
- 使用for循环, 次数 = punchList.count ,已经打卡的天数。再通过打卡时某一天,替换上面字典A中的value:model值。
- 通过for循环【数组A】,来获取【字典A】中的model值,生成一个新的数组【数组B】。使用这一步主要是确保时间的顺序。
- 返回【数组B】就是需要的这两个月的打卡数据model数组
6 通过在index = 0处插入当月的月份,在 index = currentMonthDay +1 处插入上个月的月份。就生成了需要的结果。
结果类型
{
monthStr = 4;
},
<NTOutdoorPunchInfoModel: 0x10eb40830>,
<NTOutdoorPunchInfoModel: 0x10eb3f6b0>,
<NTOutdoorPunchInfoModel: 0x10eb1da40>,
{
monthStr = 3;
},
<NTOutdoorPunchInfoModel: 0x10ec4e810>,
<NTOutdoorPunchInfoModel: 0x10ec1dc40>,
<NTOutdoorPunchInfoModel: 0x108896f00>,
......
上代码
//config.m
@property (nonatomic, strong)NSMutableDictionary *monthDicInfo;
//public 对外放开接口的类,主要是来配置解析数据的方法
- (NSArray *)configForPunchList:(NSArray *)punchList {
// 1. 首先创建返回解析好的数组,作为返回值返回
NSMutableArray *monthInfo = [[NSMutableArray alloc] init];
//2. 调用getMonthList 来获取一个数组(备注1)和一个字典(备注2)
NSArray *monthList = [self getMonthList];
//3. for 循环 服务器返回的数据,来更
for (NSDictionary *dic in punchList) {
NTOutdoorPunchInfoModel *model = [NTOutdoorPunchInfoModel getModelFromDic:dic];
NSTimeInterval firstTimePunch = model.signFirstTime;
NSString *timeStr = [TimeUtil getDateStr:firstTimePunch/1000];
[self.monthDicInfo setValue:model forKey:timeStr];
}
//4. 确定今天是几月,通过今天是几月,得出上个月是几月,设置保存上个月的一个字典
NSInteger nowMonthInt = [self getYearOrMonthOrDayForDate:[NSDate date] calendarUnit:NSCalendarUnitMonth];
NSInteger lastMonthInt = (nowMonthInt == 1) ? 12 : nowMonthInt -1;
NSDictionary *nowMonthDic = @{@"monthStr":[NSString stringWithFormat:@"%ld",(long)nowMonthInt]};
NSDictionary *lastMonthDic = @{@"monthStr":[NSString stringWithFormat:@"%ld",(long)lastMonthInt]};
[monthInfo addObject:nowMonthDic];
// 5. for循环备注1的数组,通过key值,顺序获取备注2中的model值,保存到monthInfoList
for (NSString *timeStr in monthList) {
NTOutdoorPunchInfoModel *model = [self.monthDicInfo objectForKey:timeStr];
[monthInfo addObject:model];
}
//6. 确定几天是几号,在monthInfoList插入到index = nowDay + 1数组中去
NSInteger nowDay = [self getYearOrMonthOrDayForDate:[NSDate date] calendarUnit:NSCalendarUnitDay];
[monthInfo insertObject:lastMonthDic atIndex:nowDay + 1];
return monthInfo;
//7. 返回配置好的
return monthInfoList
}
//private
//返回一个字符串数组,数组包括从当天开始到上个月1号的日期,格式yyyy-MM-dd
//并且创建了一个字典,key是yyyy-MM-dd的日期字符串,value是model类
- (NSMutableArray *)getMonthList {
NSMutableArray *monthList = [[NSMutableArray alloc] init];
NSDate *currentDate = [NSDate date];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"yyyy-MM-dd"];
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
NSDateComponents *lastMonthComps = [[NSDateComponents alloc] init];
//当月现在是几日
NSInteger nowDay = [self getYearOrMonthOrDayForDate:[NSDate date] calendarUnit:NSCalendarUnitDay];
NSInteger lastMonthDays = [self getDaysWithLastMonth];
int count = 0;
for (NSInteger i = nowDay+lastMonthDays; i > 0; i --) {
// [lastMonthComps setYear:1]; // year = 1表示1年后的时间 year = -1为1年前的日期,month day 类推
[lastMonthComps setDay:-count];
NSDate *newdate = [calendar dateByAddingComponents:lastMonthComps toDate:currentDate options:0];
NSString *dateStr = [formatter stringFromDate:newdate];
[monthList addObject:dateStr];
//保存每个model
NTOutdoorPunchInfoModel *model = [[NTOutdoorPunchInfoModel alloc] init];
model.signYear = [NSString stringWithFormat:@"%ld",(long)[self getYearOrMonthOrDayForDate:newdate calendarUnit:NSCalendarUnitYear]];
model.signMonth = [NSString stringWithFormat:@"%ld",(long)[self getYearOrMonthOrDayForDate:newdate calendarUnit:NSCalendarUnitMonth]];
model.signDay = [NSString stringWithFormat:@"%ld",(long)[self getYearOrMonthOrDayForDate:newdate calendarUnit:NSCalendarUnitDay]];
model.week = [self getWeekStrForDate:newdate];
[self.monthDicInfo setValue:model forKey:dateStr];
count++;
}
return monthList;
}
//private
//通过一个日期字符串返回date
- (NSDate *)getDateWithDateStr:(NSString *)str {}
//private
//获取上个月有多少天
- (NSInteger)getDaysWithLastMonth {}
//private
//根据date日期,和calendarUnit返回date属于哪一年,月,日
- (NSInteger)getYearOrMonthOrDayForDate:(NSDate *)date calendarUnit:(NSCalendarUnit)unit {
}
//private
//根据date日期获取是周几,转化为例如'星期天' 表达
- (NSString *)getWeekStrForDate:(NSDate *)date {}
结尾:
可以优化的地方:如果当天多次进入到这个页面,可以把获取的【数组A】【字典A】缓存一下,每次进来查看【数组A】首条是否是当天,如果是当天直接使用,不用走第二步,节省点计算时间。
网友评论