(五)iOS 实战项目开发:团购之网络请求

  • 通知中心传值

  • 网络基础相关

  • 网络数据请求

  • 通知中心传值
    通知中心:(NSNotificationCenter):
    使用了操作系统的功能,通过NSNotificationCenter可以让对象之间进行通讯,这些对象相互间可以不认识。当你用一个并行的流来推送通知,或者刷新数据库,并希望在界面中能够看到时,这非常有用。

  • 通知中心和协议代理等传值有什么区别?
    如果我们现在好几个界面又要传递同一个值,也就是说我们当前这个界面都要得到另一个界面给它传值,用代理的话那么我们是不是要把那些界面都要实现本界面的协议?才能获取到值?这是效率非常低下的一种做法,要实现数据一对多的情况下,通知中心是一个好的解决方案。

(五)iOS 实战项目开发:团购之网络请求_第1张图片
Paste_Image.png

图中黄色的线代表addObserver也就是添加观察者,当数据发生改变的时候通过紫色的线也就是postNotification发送通知,当我们的通知中心发送了通知的时候,所有的addObserver都能接收到通知。

  • 步骤:
  1. 注册通知
 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(myText:) name:@"myTest" object:nil];```
2. 发送通知

[[NSNotificationCenter defaultCenter] postNotificationName:@"myText" object:array];```

  • 回到具体项目中
(五)iOS 实战项目开发:团购之网络请求_第2张图片
Paste_Image.png

如图,我们在下拉菜单中选择了台湾菜,那么上方的item中就要显示台湾菜,同时我们的下拉菜单也要收起,然后呢我们的主界面还要显示数据。UI变化:

  1. 收起下拉菜单
  2. 改变item中值
  3. 刷新首页数据
  • 实现思路:
    1:点击商品分类发出通知
    2:主界面接收到通知
    3:主界面根据接收到的通知发出网络请求

1:点击商品分类发出通知:
之前我们封装了一套下拉菜单,封装的时候我们只写了数据源的方法,现在我们想要发出通知肯定是在TableView的DidSelected方法中来写,那么我们就需要再写一个tableView的代理方法,用来处理点击事件,但是我们封装的下拉二级菜单有两个TableView,我们就需要两个代理方法分别是左侧TableView的点击代理方法,右侧的TableView的点击代理方法

  • popView代理方法
@protocol MyPopViewDelegate 

// 点击左侧TableView的代理方法
- (void)tableView:(popView *)popView didSelectRowAtLeftTable:(NSInteger)row;
// 点击右侧TableView的代理方法
- (void)tableView:(popView *)popView didSelectRowAtRightTable:(NSInteger)row;

@end```

- 声明代理指针

@property (nonatomic, assign) id delegate; // tableView 代理指针```

  • 实现代理方法
/**
 *  TableView DidSelected Delegate
 *
 *  @param tableView 当前TableView
 *  @param indexPath 当前行
 */
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (tableView == _leftTVC) {
        self.selectRow = indexPath.row; // 记录选中的行号
        [_rightTVC reloadData];
        
        // 左侧TableView的代理方法
        if ([self.delegate respondsToSelector:@selector(tableView:didSelectRowAtLeftTable:)]) {
            [self.delegate tableView:self didSelectRowAtLeftTable:indexPath.row];
        }
    }else
    {
        // 右侧TableView的代理方法
        if ([self.delegate respondsToSelector:@selector(tableView:didSelectRowAtRightTable:)]) {
            [self.delegate tableView:self didSelectRowAtRightTable:indexPath.row];
        }
    }
}```

- 遵守代理

@interface PopViewController ()```

  • 设置代理
popView *pop = [popView makePopView];
    pop.dataSource = self;
    pop.delegate = self;
    [self.view addSubview:pop];```

- 实现代理方法并发送通知信息

pragma mark - popView Delegate

  • (void)tableView:(popView *)popView didSelectRowAtLeftTable:(NSInteger)row
    {
    self.selectModel = _categotyArray[row];
    if (!_selectModel.subcategories.count) {
    // 发送通知
    [[NSNotificationCenter defaultCenter] postNotificationName:@"categoryDidChanged" object:nil userInfo:@{@"categoryModel":_selectModel}];
    }
    }

  • (void)tableView:(popView *)popView didSelectRowAtRightTable:(NSInteger)row
    {
    // 发送右侧通知
    [[NSNotificationCenter defaultCenter] postNotificationName:@"subCategoriesName" object:nil userInfo:@{@"subCategoryName":_selectModel.subcategories[row]}];
    }```

  • 首页接收通知并绑定方法

// 注册左边TableView通知
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(categoryDidChanged:) name:@"categoryDidChanged" object:nil];
    // 注册右边TableView通知
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(subcategotiesNameDidChanged:) name:@"subCategoriesName" object:nil];```

- 实现接收通知调用的方法

pragma mark - 类目发生改变的方法

  • (void)categoryDidChanged:(NSNotification *)info{
    CategoriyModel *md = info.userInfo[@"categoryModel"];
    NSLog(@"%@", md.name);
    }

pragma mark - 子类目发生变化的方法

  • (void)subcategotiesNameDidChanged:(NSNotification *)info{
    NSString *subCategoriesName = info.userInfo[@"subCategoryName"];
    NSLog(@"%@", subCategoriesName);
    }```

  • 类目的两个通知写好了之后我们还要设置城市,城市的通知等同于类目的写法

/**
 *  用户选择城市
 *
 *  @param tableView tableView
 *  @param indexPath 当前行
 */
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    CityModel *model = _dataArray[indexPath.section];
    // 发送选择城市的通知
    [[NSNotificationCenter defaultCenter] postNotificationName:@"cityDidChanged" object:nil userInfo:@{@"cityName":model.cities[indexPath.row]}];
    // 让选择城市的控制器消失
    [self dismissViewControllerAnimated:YES completion:nil];
}```

- 主页面注册并接收城市改变的通知

// 选择城市的通知接收
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(cityDidChanged:) name:@"cityDidChanged" object:nil];

pragma mark - 城市发生改变的方法

  • (void)cityDidChanged:(NSNotification *)info{
    _selectedCityName = info.userInfo[@"cityName"];
    NSLog(@"选择的城市%@", _selectedCityName);

    [self createRequest];
    }```

  • 移除通知

#pragma mark - 移除通知
- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}```

- 至此,我们已经实现了点击下拉菜单向首页发送通知消息的功能,接下来我们来处理首页收到通知后进行网络数据请求的功能

- 网络基础相关
iOS开发网络请求我们可以理解为调用后台给我们的接口,通过接口我们可以进行数据的请求和发送
1:同步POST/GET请求
2:异步POST/GET请求
- 同步请求和异步请求的区别:
异步请求需要开辟新的线程,而同步请求都是在主线程中进行的

- iOS网络请求的类
1:NSURLConnection
2:ASIHTTPRequest
3:AFNetWorking

- 请求步骤
1:设置请求路径
2:创建请求对象
3:设置请求体(POST)
4:发送请求

- 我们这里使用大众点评的官网API来请求数据
步骤:
1:导入API
![Paste_Image.png](http://upload-images.jianshu.io/upload_images/189984-9ed56b97ccfbf045.png?imageMogr2/auto-orient/strip|imageView2/2/w/1240)

2: 遵循API代理

@interface FirstViewCollectionViewController ()```

3:创建网络请求并设置其参数,参数为我们左右下拉菜单通知传递过来的值

#pragma mark - 网络请求
- (void)createRequest
{
    DPAPI *api = [[DPAPI alloc] init];
    NSMutableDictionary *params = [[NSMutableDictionary alloc] init];
    [params setValue:_selectedCityName forKey:@"city"]; // 城市
    [params setValue:_selectedCategory forKey:@"category"]; // 选择的类目
    [api requestWithURL:@"v1/deal/find_deals" params:params delegate:self];
}```

4:实现网络请求完毕之后的代理方法,即接收值,同时实现请求错误的方法

  • (void)request:(DPRequest *)request didFinishLoadingWithResult:(id)result
    {
    NSLog(@"请求成功返回的数据%@", result);
    }
  • (void)request:(DPRequest *)request didFailWithError:(NSError *)error
    {
    NSLog(@"%@", error);
    }
- 运行结果:我们发现数据已经请求成功!
![Paste_Image.png](http://upload-images.jianshu.io/upload_images/189984-9be0a400827293d4.png?imageMogr2/auto-orient/strip|imageView2/2/w/1240)

- 总结
1:通知中心的使用
2:网络数据请求

你可能感兴趣的:((五)iOS 实战项目开发:团购之网络请求)