天气预报
这一周要写的内容为天气预报,天气预报主要的思路是要进行简单的网络情求,获取天气预报的实时数据,并且把数据存储在数组中进行界面传值(以通知传值和属性传值为主)。
1.简单的网络请求
在这里以模糊搜索为例。
模糊搜索的实现效果如下:
网络请求的5大步骤:
- 创建请求地址
- 创建请求类
- 创建会话
- 根据会话创建任务
- 启动任务
在这里进行模糊搜索需要用到一个网站信息:
获取城市名称所需要的网址
接下来就是网络请求的代码:
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface AddCityViewController : UIViewController <NSURLSessionDelegate>
@property (nonatomic, strong) NSString* cityID;
@property (nonatomic, strong) NSMutableData* data;
@property (nonatomic, strong) NSDictionary* mainDictory;
@end
NS_ASSUME_NONNULL_END
在.h文件中对所需要的属性进行定义。
#import "AddCityViewController.h"
@interface AddCityViewController ()
@end
@implementation AddCityViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.cityID = @"101110102";
[self createUrl];
}
- (void) createUrl {
// 地址(我这里的cityID是外部传进来的字符串,代表查询城市的id)
NSString* urlString = [NSString stringWithFormat:@"https://v0.yiketianqi.com/api?appid=92838572&appsecret=r9xq1WH1&version=v9&cityid=%@&unescape=1", _cityID];
// 对中文和空格字符编码解码
urlString = [urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
// 设置请求地址
NSURL* url = [NSURL URLWithString:urlString];
// 创建请求类
NSURLRequest* request = [NSURLRequest requestWithURL:url];
// 创建会话
NSURLSession* seesion = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
// 根据会话创建任务
NSURLSessionTask* dataTask = [seesion dataTaskWithRequest:request];
// 启动任务
[dataTask resume];
}
// 接收的服务器的响应
- (void) URLSession:(NSURLSession*)session dataTask:(nonnull NSURLSessionDataTask *)dataTask didReceiveResponse:(nonnull NSURLResponse *)response completionHandler:(nonnull void (^)(NSURLSessionResponseDisposition))completionHandler {
// 判断data是否使用过
if (self.data == nil) {
// 未使用过初始化data
self.data = [[NSMutableData alloc] init];
} else {
// 使用过清空上次使用的数据
self.data.length = 0;
}
// 允许接收数据
completionHandler(NSURLSessionResponseAllow);
}
// 接收数据时调用,会被调用多次
- (void) URLSession:(NSURLSession*)session dataTask:(nonnull NSURLSessionDataTask *)dataTask didReceiveData:(nonnull NSData *)data {
// 拼接数据
[self.data appendData:data];
}
// 数据请求完成 或请求出现错误时调用
- (void) URLSession:(NSURLSession*)session task:(nonnull NSURLSessionTask *)task didCompleteWithError:(nullable NSError *)error {
// 请求成功
if (error == nil) {
// 解析数据,将data转换成OC对象,返回的是一个字典
// 用于接收的字典我在别的方法内已经初始化。若没有初始化字典,接收到的永远都是空值。
_mainDictory = [NSJSONSerialization JSONObjectWithData:_data options:kNilOptions error:nil];
} else {
// 请求失败,打印错误
NSLog(@"%@", error);
}
// 回到主线程(进行其他操作)
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
// 打印接收到的字典,确认请求是否成功
NSLog(@"dict = %@", self->_mainDictory);
}];
}
@end
在.m文件中把获取的数据存储到self.data中,再把self.data中的数据再存储到字典中。方便后面进行其他操作(例如传值等操作)。
通知传值
通知中心传值,可以跨越多个页面传值, 一般也是从后面的页面传给前面的页面。
通知传值可以分为三个步骤:
1.在发送者中实现一个方法进行发送通知
- (void) pressadd {
self.dictory = [NSMutableDictionary dictionaryWithObjectsAndKeys:self.labcity, @"city",self.labtemp, @"temp", self.labweather, @"text", self.hourarray, @"hourarr" ,self.temparray, @"temparr", self.weatherarray, @"weatherarr",self.weatharray,@"weatharr",self.dayarray, @"dayarr", self.tempMaxarray,@"tempmaxarr", self.tempMinarray, @"tempminarr", nil];
//实现一个方法进行发送通知这里以发送字典为例
[[NSNotificationCenter defaultCenter] postNotificationName:@"TransDataNoti" object:nil userInfo:_dictory];
[self dismissViewControllerAnimated:YES completion:nil];
}
2.在接收者中注册通知,也就是接收者要进行接收通知,接收通知和发送通知的名字要一致
//接收通知和发送通知的名字要一致(名字都为TransDataNoti)
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notiReceived:) name:@"TransDataNoti" object:nil];
3.在接收者中实现通知中的方法
- (void) notiReceived: (NSNotification*) sender {
[self.arrcity addObject:sender.userInfo[@"city"]];
[self.arrnowtemp addObject:sender.userInfo[@"temp"]];
[self.arrnowweather addObject:sender.userInfo[@"text"]];
[self.hourarray addObject:sender.userInfo[@"hourarr"]];
[self.temparray addObject:sender.userInfo[@"temparr"]];
[self.weatherarray addObject:sender.userInfo[@"weatherarr"]];
[self.weatharray addObject:sender.userInfo[@"weatharr"]];
[self.dayarray addObject:sender.userInfo[@"dayarr"]];
[self.tempMaxarray addObject:sender.userInfo[@"tempmaxarr"]];
[self.tempMinarray addObject:sender.userInfo[@"tempminarr"]];
[_tableview reloadData];
}
4.在不用的时候移除通知
- (void) dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"TransDataNoti" object:nil];
}
注意参数Observer为要删除的观察者,一定不能置为nil。
如果为nil它会报警告:
Null passed to a callee that requires a non-null argument。
iOS9以上对其不进行移除处理不会崩溃,但是如果这个对象是在监听一个单例对象的属性的话,在其他地方,又修改该属性,还是会崩溃。