前言
作为留校的最后一个任务,天气预报与之前写的demo挺不一样的,对我来说还是挺有挑战性的,网络请求总是对不上,数组和字典看着看着就乱了,开始着手写的前一天半几乎没有进度,一点思路都没有,有一天下午改了一下午的error,一下午都不知道跑出来是什么样子,各种报错,慢慢才开始找到感觉走回正轨。
天气预报需要使用到传值及网络请求,可以参考传值和网络请求
github:天气预报
思路
这是我自己写的顺序,可能不太科学。。。
- 把大概框架建立起来(刚进去的天气显示界面,点击按钮跳转到管理城市界面,再点击添加按钮跳转到搜索城市界面,点击城市名跳转到天气显示界面)
- 自定义UIView,用于天气显示界面
- 天气显示界面左右滑动切换城市,故其为一个大的UIScrollView,根据添加的城市改变大小,加入自定义的UIView
- 刚开始接触网络请求,先拿比较简单的搜索城市时的联想开刀(建议先新建立一个文件跑,如果可以再加入正式文件中),点击城市跳转至管理界面
- 管理界面因为需要有该城市的温度和日期,故在这个界面也需要网络请求和传值
- 在自定义的UIView里进行网络请求,获取数据,传值
碰到的一些坑
- 之前我设置点击确认按钮加入城市, 但是如果用户输入一些不存在的城市(例如:12,T等)点击确认,由于接口访问不到程序就会崩,后来改成了点击城市就可添加
- 因为显示的城市需要统一,代码中涉及到很多传值问题,思路需要理清
- 需要有查重功能,这个只需要遍历就行
- 创建URL时因为不同城市网址不同,我采用循环创建,就会产生同时跑的结果,导致有些数据没有录入就开始UITableView的数据更新了,然后报错,这点解决方法我下文会放代码
- 在管理界面同样循环创建URL,用数组存储需要使用的数据时,它不会按顺序跑,导致值与城市对不上号,这里我使用字典存储解决了
- 因为搜索的接口是全球的,但是天气的接口只有中国的,需要加提示
重要代码
- 循环创建时的bug:
//在执行的代码前加入 if 限制条件,等需要的值加入完成后,再执行操作
if (_messageArray.count && _weekArray.count) {
..........
}
- 没有天气信息的提示, 并且需要删除该城市:
我是让每个城市都请求一遍,如果没有值就删除该城市
当d + a的值等于城市数组的count时,说明全部验证过了,然后执行下一步操作(因为直接遍历的话,也不会正经的按顺序跑,可能直接进行下一步,所有需要有验证条件)
- (void)confirm: (NSString *)name{
NSString *urlString = [NSString stringWithFormat:@"http://api.k780.com/?app=weather.realtime&weaid=%@&ag=today,futureDay,lifeIndex,futureHour&appkey=44524&sign=54dc62def4393a0d5cfe97a2a52646a6&format=json", name];
urlString = [urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
NSURL *url = [NSURL URLWithString: urlString];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLSession *sharedSession = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [sharedSession dataTaskWithRequest:request completionHandler:^(NSData *_Nullable data, NSURLResponse *_Nullable response, NSError *_Nullable error) {
if (data) {
NSMutableDictionary *secondDictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
NSLog(@"success isEqualToString:1 = %i %@", [secondDictionary[@"success"] isEqualToString:@"1"], name);
if ([secondDictionary[@"success"] isEqualToString:@"1"]) {
self->a++;
} else {
[self->_cityArray removeObject:name];
self->d++;
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"该城市消息不完全,不予显示!" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *sure = [UIAlertAction actionWithTitle:@"sure" style:UIAlertActionStyleCancel handler:nil];
[alert addAction:sure];
[self presentViewController:alert animated:NO completion:nil];
}
}
NSLog(@"_cityArray.count = %lu", self->_cityArray.count);
NSLog(@"_cityArray = %@", self->_cityArray);
if ((self->a + self->d) == self->_cityArray.count) {
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[self back];
[self change];
}];
}
}];
[dataTask resume];
}
效果图: