在开发中如果用户的某个操作与网络相关,我们通常会先进行网络请求,然后在请求成功或失败之后再给用户一个反馈。如:用户进行评论,发出评论后先进行网络请求,请求成功,提示用户评论成功,请求失败提示用户评论失败。
现在有一个需求,在评论发出之后,提示用户评论成功(不管实际成功不成功)。这样就需要做本地缓存了,如果网络请求没有成功(如:评论的时候,网络断开),那么就要将网络请求的数据、请求的接口缓存下载,等到有网的时候再去进行评论的网络请求。
至于这样的需求合理不合理,我们不谈,只说如何实现。
缓存:
我的做法:
将所有的数据存储在一个字典里,字典里的key是请求接口和一个ID的组合(只要能唯一确定该请求就行)。
问:什么时候去处理缓存中的数据呢?即将缓存中的数据进行网络请求。
答:当有网的时候 且 当前没有正在处理缓存中的数据
问:如何判断啥时候有网?
答:通过AFNetworkReachabilityManager这个类就能判断,当有网的时候发送一个通知。
问:如果判断当前有没有正在处理缓存中的数据?
答:设置一个标识符,当首次处理的时候就将此标识符设置为YES,当全部处理完后在设置为NO。
问:缓存中等待处理的数据可能有多个,且网络请求是异步的,如何改变标识符的状态呢。
答:等待处理的数据是确定的,在开始处理前先获取待处理数据数A,每处理完成一个数据A就减1(不管是处理成功还是失败),直到A为0代表改变该标志符的状态。
问:在遍历所有的待处理数据时,如果将已经处理的数据从缓存中移除?
答:给每条数据一个是否被处理成功的标识,如果被处理成功,就将该标识设置为处理成功的状态,在下次处理数据的时候创建一个新的字典,将未被处理的数据存储到该字典中,然后重新进行缓存,当然缓存字典的key还是之前的key。
代码:
- (void)completeHasCompletedOrders{
// 监听网络状态,如果有网络,就处理本地存储的工单
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleOrders:) name:kNetworkStatus object:nil];
}
- (void)handleOrders:(NSNotification *)noti{
NSDictionary * userInfo = noti.userInfo;
BOOL status = [userInfo[@"status"] boolValue];
if (status == YES && self.isDealingOrder == NO) { // 在有网且不在处理的时候去处理
YYCache * cache = [YYCache cacheWithName:kProjectCache];
NSDictionary * allOrders = (NSDictionary *)[cache objectForKey:kCompletedOrders];
NSLog(@"allOrders:%@", allOrders);
NSArray * allOrderKeys = [allOrders allKeys];
NSMutableDictionary * newAllOrders = [NSMutableDictionary dictionary];
for (NSInteger i = 0; i < allOrderKeys.count; i ++) {
NSString * orderKey = allOrderKeys[i];
NSDictionary * orderDict = allOrders[orderKey];
NSInteger hasDealed = [orderDict[@"hasDealed"] integerValue];
if (hasDealed == 0) { // 将已经处理的订单移除
newAllOrders[orderKey] = orderDict;
}
}
[cache setObject:newAllOrders forKey:kCompletedOrders];
NSArray * newAllKeys = [newAllOrders allKeys];
__block NSInteger isDealingFlag = newAllKeys.count;
if (newAllKeys.count > 0) {
self.isDealingOrder = YES;
}
for (NSInteger i = 0; i < newAllKeys.count; i ++) {
NSString * key = newAllKeys[i];
NSDictionary * orderDict = newAllOrders[key];
NSString * url = orderDict[@"url"];
NSDictionary * parameters = orderDict;
NSArray * imgs = orderDict[@"imgs"];
if (kArrayIsEmpty(imgs)) {
[HttpTool POST:url parameters:parameters success:^(id responseObject) {
NSMutableDictionary * mutableDict = [NSMutableDictionary dictionaryWithDictionary:parameters];
mutableDict[@"hasDealed"] = @(1);
newAllOrders[key] = mutableDict;
[cache setObject:newAllOrders forKey:kCompletedOrders];
isDealingFlag -= 1;
if (isDealingFlag == 0) {
self.isDealingOrder = NO;
}
} failure:^(NSError *error) {
isDealingFlag -= 1;
if (isDealingFlag == 0) {
self.isDealingOrder = NO;
}
}];
}else{
NSMutableArray * fileNames = [NSMutableArray array];
for (NSInteger i = 0; i < imgs.count; i ++) {
[fileNames addObject:[NSString stringWithFormat:@"image_ios_img_%lu", i]];
}
[HttpTool uploadSomeImages:imgs andFileNames:fileNames withURL:url andParameters:parameters success:^(id responseObject) {
NSMutableDictionary * mutableDict = [NSMutableDictionary dictionaryWithDictionary:parameters];
mutableDict[@"hasDealed"] = @(1);
newAllOrders[key] = mutableDict;
[cache setObject:newAllOrders forKey:kCompletedOrders];
isDealingFlag -= 1;
if (isDealingFlag == 0) {
self.isDealingOrder = NO;
}
} failure:^(NSError *error) {
isDealingFlag -= 1;
if (isDealingFlag == 0) {
self.isDealingOrder = NO;
}
}];
}
}
}
}
本篇文章到这里就结束了,愿大家加班不多工资多,男同胞都有女朋友,女同胞都有男朋友。😊