iOS 简单的网络请求及数据解析(协议方法)

前言

  • 这周写天气预报时需要网络请求才开始正式接触,理解的可能不够全面,有什么不对的地方,敬请斧正

  • 这篇以搜索城市时的联想为例,即
    在这里插入图片描述

思路

  • 第一步当然是初始化UITextField和UITableView,联想词在UITableView里显示
  • 然后创建URL及协议方法
  • 因为输入一个字符联想词也需要同时改变,故我在UITextField的协议方法 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string; 里使用了创建URL方法
  • 最后解析数据

创建网络请求的五大步骤

  • 创建请求地址
  • 创建请求类
  • 创建会话
  • 根据会话创建任务
  • 启动任务

一些会使用到的方法解释

- stringByAddingPercentEncodingWithAllowedCharacters:
处理字符,有些中文输入网站可能会get不到

- sessionWithConfiguration: delegate: delegateQueue:
创建会话的方法

-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler
接收服务器的响应

-(void)URLSession:(NSURLSession *)session dataTask:( NSURLSessionDataTask *)dataTask didReceiveData:( NSData *)data
接收到数据

-(void)URLSession:(NSURLSession *)session task:( NSURLSessionTask *)task didCompleteWithError:( NSError *)error
数据请求完成或者请求出现错误调用的方法
- JSONObjectWithData: options: error:
解析数据时使用的方法(使用 NSDictionary 接收)

- [[NSOperationQueue mainQueue] addOperationWithBlock:
回到主线程,后接需要调用的方法

代码

首先在 ViewController.h 里声明一些属性及协议

@interface ViewController : UIViewController
<
UITextFieldDelegate,
UITableViewDelegate,
UITableViewDataSource,
NSURLSessionDelegate
>

@property (nonatomic, strong) UITextField *textField;
@property (nonatomic, strong) UITableView *tableView;
@property (nonatomic, strong) NSMutableData *data;
@property (nonatomic, strong) NSMutableArray *cityArray;

在 ViewController.m 里初始化UITextField和UITableView

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    _textField = [[UITextField alloc] init];
    _textField.delegate = self;
    _textField.frame = CGRectMake(50, 100, [UIScreen mainScreen].bounds.size.width - 100, 50);
    [self.view addSubview:_textField];
    _textField.borderStyle = UITextBorderStyleRoundedRect;
    _textField.keyboardType = UIKeyboardTypeDefault;
    [self creatTableView];
    
}

- (void)creatTableView {
    
    _tableView = [[UITableView alloc] initWithFrame:CGRectMake(50, 150, [UIScreen mainScreen].bounds.size.width - 100, 500) style:UITableViewStylePlain];
    [self.view addSubview:_tableView];
    _tableView.delegate = self;
    _tableView.dataSource = self;
    [_tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"111"];
    UIView *view = [[UIView alloc] init];
    _tableView.tableFooterView = view;
    
}

然后创建URL及协议方法

- (void)creatUrl {
    //1.创建请求地址
    NSString *urlString = [NSString stringWithFormat:@"https://search.heweather.com/find?location=%@&key=71f533964a994355bb1abfccb161d241", _textField.text];
    //处理字符
    urlString = [urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    //创建URL
    NSURL *url = [NSURL URLWithString:urlString];
    NSLog(@"%@", urlString);
    //2.创建请求类
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    //3.创建会话
    //delegateQueue 表示协议方法在哪个线程中执行
    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self  delegateQueue:[NSOperationQueue mainQueue]];
    //4.根据会话创建任务
    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request];
    //5.启动任务
    [dataTask resume];
    
}

URL协议方法:

//接收服务器的响应
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler {
    NSLog(@"didReceiveResponse");
    
    if(self.data == nil){
        self.data = [[NSMutableData alloc] init];
    } else {
        self.data.length = 0;
    }
    //允许接收数据
    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:( NSError *)error {
    NSLog(@"didCompleteWithError");
    if (error == nil) {
        //解析数据
        NSDictionary *secondDictionary = [NSJSONSerialization JSONObjectWithData:_data options:kNilOptions error:nil];
        NSMutableArray *timeArray = [[NSMutableArray alloc] init];
        timeArray = secondDictionary[@"HeWeather6"][0][@"basic"];
        for (int i = 0; i < timeArray.count; i++) {
            NSMutableString *str = [NSMutableString stringWithFormat:@"%@-%@",timeArray[i][@"parent_city"],timeArray[i][@"location"]];
            [_cityArray addObject: str];
        }
        for (int i = 0; i < _cityArray.count; i++) {
            NSLog(@"%@", _cityArray[i]);
        }
        NSLog(@"-----------over");
    } else {
        NSLog(@"error = %@", error);
    }
    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
        [self->_tableView reloadData];
    }];
    
}

UITableView的协议方法:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"111" forIndexPath:indexPath];
    while ([cell.contentView.subviews lastObject] != nil) {
        [(UIView *)[cell.contentView.subviews lastObject] removeFromSuperview];
    }
    cell.textLabel.text = _cityArray[indexPath.row];
    cell.textLabel.font = [UIFont systemFontOfSize:20];
    cell.textLabel.textAlignment = NSTextAlignmentCenter;
    
    return cell;
    
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return _cityArray.count;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return 30;
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [_textField endEditing:YES];
}

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值