这周写天气预报用到了网络求值,我用的是URLSession协议传值
总的来说就5步
- 创建请求地址
- 创建请求类
- 创建会话
- 根据会话创建任务
- 启动任务
- 以及它所带的一些方法
下面是URLSession协议传值模版
#define LIST_URL @"https://geoapi.heweather.net/v2/city/lookup?location=beijing&key=b92646e0f4194731b50870798cfad1d0"
- (void) touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
//1.创建请求地址
NSURL *url = [NSURL URLWithString:LIST_URL];
//2.创建请求类
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//3.创建会话
/*
@property (class, readonly, strong) NSURLSessionConfiguration *defaultSessionConfiguration;
@property (class, readonly, strong) NSURLSessionConfiguration *ephemeralSessionConfiguration;
+ (NSURLSessionConfiguration *)backgroundSessionConfigurationWithIdentifier:(NSString *)identifier
*/
//delegateQueue 表示协议方法在哪个线程中执行
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
//4. 根据会话创建任务
NSURLSessionDataTask * dataTask = [session dataTaskWithRequest:request];
//5. 启动任务
[dataTask resume];
}
//接收到服务器的响应
- (void) URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(nonnull NSURLResponse *)response completionHandler:(nonnull void (^)(NSURLSessionResponseDisposition))completionHandler
{
NSLog(@"didReceiveResponse");
if(self.data == nil) {
self.data = [[NSMutableData alloc] init];
}else {
self.data.length = 0;
}
/*
NSURLSessionResponseCancel = 0, 默认请求之后步接受服务器的数据 Cancel the load, this is the same as -[task cancel]
NSURLSessionResponseAllow = 1, 允许接收服务器的数据 Allow the load to continue
NSURLSessionResponseBecomeDownload = 2, 转成下载任务 Turn this request into a download
NSURLSessionResponseBecomeStream 转成流*/
completionHandler (NSURLSessionResponseAllow);
}
//接收到数据,该方法会被调用多次
- (void) URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
{
NSLog(@"didReceiveData");
[self.data appendData:data];
}
//数据请求完成或请求出现错误
- (void) URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(nullable NSError *)error
{
NSLog(@"didCompleteWithError");
if(error == nil) {
//解析数据
id objc = [NSJSONSerialization JSONObjectWithData:self.data options:NSJSONReadingMutableContainers error:nil];
NSLog(@"--%@", objc);
}
}
在实际的运用当中,先放一段我的代码中的节选
- (void)pass:(NSString *)str {
NSLog(@"%@", str);
NSString *string = [NSString stringWithFormat:@"https://yiketianqi.com/api?version=v9&appid=82228326&appsecret=gk6TsRcE&city=%@",str];
//处理字符,有些中文,,,
string = [string stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
//1. 创建请求地址
NSURL *url = [NSURL URLWithString:string];
//2. 创建请求类
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//3. 创建会话
//NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
NSURLSession *session = [NSURLSession sharedSession];
//4. 根据会话创建任务
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
//str = [NSMutableString stringWithFormat:@"%@",dic[@"location"][0][@"now"][@"temp"]];
//NSString *str = [NSString stringWithFormat:@"%@",dic[@"location"][0][@"now"][@"temp"]];
NSString *str1 = [NSString stringWithFormat:@"%@",dic[@"data"][0][@"date"]];
[self.timeArray addObject:str1];
//[self->_tmpDictionary setObject:str forKey:self->_nameArray];
NSLog(@"%@",str1);
//NSLog(@"%@",dic);
//str = [NSMutableString stringWithFormat:@"%@",dic[@"location"][0][@"now"][@"obsTime"]];
NSString *str2 = [NSString stringWithFormat:@"%@",dic[@"data"][0][@"tem"]];
[self.tmpArray addObject:str2];
NSLog(@"%@",str2);
[self.nameArray addObject:str];
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[self.tableView reloadData];
}];
}];
//5. 启动任务
[dataTask resume];
}
- 首先我这个例子是传入了一个字符串,然后接下来之后的动作
- 通常会建一个字符串,用于接收请求的网站,而不是宏定义那个网站,因为搜索的城市或者其他属性会发生变化
- 在第四步根据会话创建任务中,你所请求的内容会根据翻译过来的json字符串发生相应的变化
先看一下我请求到的数据翻译成json的样子
{
"cityid":"101090801",
"city":"衡水",
"cityEn":"hengshui",
"country":"中国",
"countryEn":"China",
"update_time":"2020-08-09 21:12:26",
"data":[
{
"day":"09日(星期日)",
1 "date":"2020-08-09",
"week":"星期日",
"wea":"多云",
"wea_img":"yun",
"wea_day":"多云",
"wea_day_img":"yun",
"wea_night":"多云",
"wea_night_img":"yun",
2 "tem":"29",
"tem1":"33",
"tem2":"25",
"humidity":"74%",
"visibility":"24.09km",
"pressure":"994",
"win":[
"东南风",
"南风"
],
"win_speed":"<3级",
"win_meter":"小于12km/h",
"sunrise":"05:27",
"sunset":"19:18",
"air":"39",
"air_level":"优",
"air_tips":"空气很好,可以外出活动,呼吸新鲜空气,拥抱大自然!",
"alarm":{
"alarm_type":"",
"alarm_level":"",
"alarm_content":""
},
4 "hours":[
{
"hours":"21时",
"wea":"多云",
"wea_img":"yun",
"tem":"27",
"win":"南风",
"win_speed":"<3级"
},
{
"hours":"22时",
"wea":"多云",
"wea_img":"yun",
"tem":"26",
"win":"南风",
"win_speed":"<3级"
},
{
"hours":"23时",
"wea":"晴",
"wea_img":"qing",
"tem":"26",
"win":"南风",
"win_speed":"<3级"
},
{
"hours":"00时",
"wea":"晴",
"wea_img":"qing",
"tem":"26",
"win":"南风",
"win_speed":"<3级"
},
{
"hours":"01时",
"wea":"多云",
"wea_img":"yun",
"tem":"25",
"win":"南风",
"win_speed":"<3级"
},
{
"hours":"02时",
"wea":"多云",
"wea_img":"yun",
"tem":"25",
"win":"南风",
"win_speed":"<3级"
},
{
"hours":"03时",
"wea":"多云",
"wea_img":"yun",
"tem":"25",
"win":"南风",
"win_speed":"<3级"
},
{
"hours":"04时",
"wea":"多云",
"wea_img":"yun",
"tem":"24",
"win":"南风",
"win_speed":"<3级"
},
{
"hours":"05时",
"wea":"多云",
"wea_img":"yun",
"tem":"24",
"win":"南风",
"win_speed":"<3级"
},
{
"hours":"06时",
"wea":"多云",
"wea_img":"yun",
"tem":"25",
"win":"南风",
"win_speed":"<3级"
},
{
"hours":"07时",
"wea":"多云",
"wea_img":"yun",
"tem":"26",
"win":"南风",
"win_speed":"<3级"
}
],
},
{
"day":"10日(星期一)",
"date":"2020-08-10",
3 "week":"星期一",
"wea":"雷阵雨转阴",
"wea_img":"lei",
"wea_day":"雷阵雨",
"wea_day_img":"lei",
"wea_night":"阴",
"wea_night_img":"yin",
"tem":"33",
"tem1":"33",
"tem2":"24",
"humidity":"",
"visibility":"",
"pressure":"",
"win":[
"南风",
"北风"
],
"win_speed":"<3级",
"win_meter":"",
"sunrise":"05:27",
"sunset":"19:17",
"air":"",
"air_level":"",
"air_tips":"",
"alarm":{
"alarm_type":"",
"alarm_level":"",
"alarm_content":""
},
"hours":[
{
"hours":"08时",
"wea":"多云",
"wea_img":"yun",
"tem":"27",
"win":"南风",
"win_speed":"<3级"
},
{
"hours":"09时",
"wea":"雷阵雨",
"wea_img":"lei",
"tem":"28",
"win":"南风",
"win_speed":"<3级"
},
因为只是举例,所以只选取了一部分
例如我的代码里
4. NSString *str1 = [NSString stringWithFormat:@"%@",dic[@"data"][0][@"date"]];
NSString *str2 = [NSString stringWithFormat:@"%@",dic[@"data"][0][@"tem"]];
str1所对应的就是我在上面标注的1的位置的data对应的字符串,是个日期
str2所对应的就是我在上面标注的1的位置的tem对应的字符串,是个维度
5. 我举一些其他的例子
big.cell2time3 = [NSString stringWithFormat:@"%@", dic[@"data"][2][@"week"]];
这个对应的就是data的第二个组数据{}中对应的week,即上面标注3的位置。
for(int i = 0; i < 11; i++) {
//NSString *strhour = [NSString stringWithFormat:@"%@", dic[@"data"][@"hours"][i][@"hours"]];
NSString *strhour = [[NSString alloc] initWithFormat:@"%@",[[[dic objectForKey:@"data"][0] objectForKey:@"hours"][i] objectForKey:@"hours"]];
[self.hourtimeArray addObject:strhour];
}
这个循环,对应的是date里hours里的11个小hours,晴仔细看我上面标注的4位置及4以下的10个hours包括的{}括号,即21时,22时,23时…
这里的objectForKey指进入一个[]包括的内容。
NSString *str = [NSString stringWithFormat:@"%@", dic[@"location"][i][@"name"]];
相等于
NSString *str = [NSString stringWithFormat:@"%@", array[i][@"name"]];
另外这两行代码和上面的json代码无关,我只是想表达,这两行的最终呈现是一样的,只是写法有所不同,便于理解。
在我看来,根据json读取数据来写代码,其实类似于数组取值,大括号时字典,中括号时数组。以上的几个例子也解释了一下,可以对照着好好看看。