博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
IOS-小项目( 网络部分 简单实现)
阅读量:5993 次
发布时间:2019-06-20

本文共 17092 字,大约阅读时间需要 56 分钟。

在介绍小项目之前,在此说明一下此代码并非本人所写,我只是随笔的整理者。

在介绍之前先展现一下效果图。

看过效果图大家应该很熟悉了,就是饿了么的一个界面而已,值得注意的是,实现时并没有采用本地连接,而是实打实的网络连接。看一下文件架构。

这一采用的是MVC设计模式,虽然文件很少,但是也可以看。

下面开始正式介绍小项目的实现。

首先介绍Model的实现,很简单,实现模型即可,

Shop.h

////  Shop.h//  CX-小项目(饿了么 网络部分 简单实现)////  Created by ma c on 16/3/23.//  Copyright © 2016年 xubaoaichiyu. All rights reserved.//#import 
@interface Shop : NSObject//建立Shop模型@property (nonatomic, copy) NSString * address;@property (nonatomic, copy) NSString * name;@property (nonatomic, copy) NSString * image_path;//-description这个方法系统占用@property (nonatomic, copy) NSString * desc;@end

 Shop.m

////  Shop.m//  CX-小项目(饿了么 网络部分 简单实现)////  Created by ma c on 16/3/23.//  Copyright © 2016年 xubaoaichiyu. All rights reserved.//#import "Shop.h"@implementation Shop@end

model实现后我们并没有真正的实现方法,下面也不是,接下来是对AFN的封装,之所以封装是因为,我们难以保证在以后该三方还能存在,只要封装,哪怕以后没有了AFN我们也可以在封装框架里运用其他的三方实现。

HttpClient.h HttpClient.m

////  HttpClient.h//  CX-小项目(饿了么 网络部分 简单实现)////  Created by ma c on 16/3/23.//  Copyright © 2016年 xubaoaichiyu. All rights reserved.//#import 
#import "AFNetworking.h"//HTTP请求类别typedef NS_ENUM(NSInteger,HttpRequestType) { HttpRequestGet, HttpRequestPost, HttpRequestPut, HttpRequestDelete,};/** * 请求前预处理block */typedef void(^PrepareExecuteBlock)(void);typedef void(^SuccessBlock)(NSURLSessionDataTask * task, id responseObject);typedef void(^FailureBlock)(NSURLSessionDataTask * task, NSError * error);@interface HttpClient : NSObject+ (HttpClient *)defaultClient;/** * HTTP请求(GET,POST,PUT,DELETE) * * @param url 请求地址 * @param method 请求类型 * @param params 请求参数 * @param prepare 请求前预处理 * @param success 请求成功处理 * @param failure 请求失败处理 */- (void)requestWithPath:(NSString *)url method:(NSInteger)method paramenters:(NSDictionary *)params prepareExecute:(PrepareExecuteBlock)prepare success:(SuccessBlock)success failure:(FailureBlock)failure;@end
////  HttpClient.m//  CX-小项目(饿了么 网络部分 简单实现)////  Created by ma c on 16/3/23.//  Copyright © 2016年 xubaoaichiyu. All rights reserved.//#import "HttpClient.h"@interface HttpClient ()@property (nonatomic, strong) AFHTTPSessionManager * manager;@property (nonatomic, assign) BOOL isConnect;@end@implementation HttpClient- (instancetype)init{    self = [super init];    if (self) {                self.manager = [AFHTTPSessionManager manager];        //设置请求类型        self.manager.requestSerializer = [AFHTTPRequestSerializer serializer];        //设置响应类型        self.manager.responseSerializer = [AFJSONResponseSerializer serializer];                self.manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json",@"text/html", @"text/json", @"text/javascript",@"text/plain",@"image/gif", nil];                //开启监听        [self openNetMonitoring];            }    return self;}//判断是否有网络连接,有网络连接再进行下一操作。- (void)openNetMonitoring {        [[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {                switch (status) {            case AFNetworkReachabilityStatusUnknown:                self.isConnect = NO;                break;            case AFNetworkReachabilityStatusNotReachable:                self.isConnect = NO;                break;            case AFNetworkReachabilityStatusReachableViaWiFi:                self.isConnect = YES;                break;            case AFNetworkReachabilityStatusReachableViaWWAN:                self.isConnect = YES;                break;            default:                break;        }            }];        [[AFNetworkReachabilityManager sharedManager] startMonitoring];        self.isConnect = YES;}//单例+ (HttpClient *)defaultClient {        static HttpClient * instance = nil;    static dispatch_once_t onceToken;    dispatch_once(&onceToken, ^{        instance = [[self alloc] init];    });    return instance;}- (void)requestWithPath:(NSString *)url                 method:(NSInteger)method            paramenters:(NSDictionary *)params         prepareExecute:(PrepareExecuteBlock)prepare                success:(SuccessBlock)success                failure:(FailureBlock)failure {            if ([self isConnectionAvailable]) {                //预处理        if (prepare) {            prepare();        }                switch (method) {            case HttpRequestGet:                [self.manager GET:url parameters:params progress:nil success:success failure:failure];                break;            case HttpRequestPost:                [self.manager POST:url parameters:params progress:nil success:success failure:failure];                break;            case HttpRequestPut:                [self.manager PUT:url parameters:params success:success failure:failure];                break;            case HttpRequestDelete:                [self.manager DELETE:url parameters:params success:success failure:failure];                break;            default:                break;        }            } else {                [self showExceptionDialog];    }}- (BOOL)isConnectionAvailable {        return self.isConnect;}//如果,没有网络,弹出Alert- (void)showExceptionDialog {        [[[UIAlertView alloc] initWithTitle:@"提示" message:@"网络连接异常,请检查网络连接" delegate:nil cancelButtonTitle:@"好的" otherButtonTitles: nil] show];}@end

接下来是对SVProgressHUD进行封装

TollHeper.h TollHeper.m

////  ToolHelper.h//  CX-小项目(饿了么 网络部分 简单实现)////  Created by ma c on 16/3/23.//  Copyright © 2016年 xubaoaichiyu. All rights reserved.//#import 
@interface ToolHelper : NSObject/******************* 指示器方法 ****************///对指示器进行封装,如可出现新的主流三方,可以很好的给予升级//弹出操作错误信息提示框+ (void)showErrorMessage:(NSString *)message;//弹出操作成功信息提示框+ (void)showSuccessMessage:(NSString *)message;//弹出加载提示框+ (void)showProgressMessage:(NSString *)message;//弹出用户信息+ (void)showInfoMessage:(NSString *)message;//取消弹出框+ (void)dismissHUD;@end
////  ToolHelper.m//  CX-小项目(饿了么 网络部分 简单实现)////  Created by ma c on 16/3/23.//  Copyright © 2016年 xubaoaichiyu. All rights reserved.//#import "ToolHelper.h"#import "SVProgressHUD.h"@implementation ToolHelper//弹出操作错误信息提示框+ (void)showErrorMessage:(NSString *)message {        [SVProgressHUD showErrorWithStatus:message];    }//弹出操作成功信息提示框+ (void)showSuccessMessage:(NSString *)message {        [SVProgressHUD showSuccessWithStatus:message];}//弹出加载提示框+ (void)showProgressMessage:(NSString *)message {        [SVProgressHUD showWithStatus:message];    }//弹出用户信息+ (void)showInfoMessage:(NSString *)message {        [SVProgressHUD showInfoWithStatus:message];    }//取消弹出框+ (void)dismissHUD {        [SVProgressHUD dismiss];}@end

做完以上工作之后下面需要解决的便是上面遗留下来的问题,不知道大家有没有发现在model里的注释

//-description这个方法系统占用

 我们该怎么解决这个问题呢,那么我要说的便是三方啦。

MJ的三方解决了这一问题

MJExtensionConfig.h MJExtensionConfig.m

////  MJExtensionConfig.h//  CX-小项目(饿了么 网络部分 简单实现)////  Created by ma c on 16/3/23.//  Copyright © 2016年 xubaoaichiyu. All rights reserved.//#import 
@interface MJExtensionConfig : NSObject@end
////  MJExtensionConfig.m//  CX-小项目(饿了么 网络部分 简单实现)////  Created by ma c on 16/3/23.//  Copyright © 2016年 xubaoaichiyu. All rights reserved.//#import "MJExtensionConfig.h"#import "MJExtension.h"#import "Shop.h"@implementation MJExtensionConfig//程序启动一定会调用+ (void)load {        /**     *  解决网络的JSON字段和本地模型属性名不一致的情况     *     *  @return 左边是本地属性名,右侧是网络JSON名     */        [Shop mj_setupReplacedKeyFromPropertyName:^NSDictionary *{                return @{@"desc" : @"description"};    }];    }@end

(对于load在前面的博客我有详细的解释,不清楚的朋友可以看看)

处理过后,为了方便对整个程序都能用到的便俩个 头文件进行优化,我们采用PCH文件

ELeMe.pch

////  ELeMe.pch//  CX-小项目(饿了么 网络部分 简单实现)////  Created by ma c on 16/3/23.//  Copyright © 2016年 xubaoaichiyu. All rights reserved.//#ifndef ELeMe_pch#define ELeMe_pch#ifdef __OBJC__#import 
#import
#endif#import "ToolHelper.h"/***************SERVER HOST***************/#define SERVER_HOST @"http://restapi.ele.me/v3"/***************SERVER API***************///获取餐馆列表#define API_GetRestaurantsList @"/restaurants"#define SCREEN_WIDTH [UIScreen mainScreen].bounds.size.width#define SCREEN_HEIGHT [UIScreen mainScreen].bounds.size.height#define shopInfoPageLimit 20#endif /* ELeMe_pch */

写完代码我们需要设置一下

设置如下

 

其实整个小项目真的很简单,导致并没有什么可以仔细去想的,写多了就好了。

下面是主要环节(注释说明的很详尽了,我就不多说废话了)

ViewController.h ViewController.m

////  ViewController.h//  CX-小项目(饿了么 网络部分 简单实现)////  Created by ma c on 16/3/23.//  Copyright © 2016年 xubaoaichiyu. All rights reserved.//#import 
@interface ViewController : UIViewController@end
////  ViewController.m//  CX-小项目(饿了么 网络部分 简单实现)////  Created by ma c on 16/3/23.//  Copyright © 2016年 xubaoaichiyu. All rights reserved.//#import "ViewController.h"#import "HttpClient.h"#import "SVProgressHUD.h"#import "Shop.h"#import "MJExtension.h"#import "ShopIconCell.h"#import "MJRefresh.h"static NSString * identifier = @"ShopInfoCell";@interface ViewController ()
//分页的页数@property (nonatomic, assign) NSInteger page;@property (nonatomic, strong) UITableView * tableView;@property (nonatomic, strong) NSMutableArray * dataList;@end@implementation ViewController- (NSMutableArray *)dataList { if (!_dataList) { _dataList = [NSMutableArray array]; } return _dataList;}- (UITableView *)tableView { if (!_tableView) { _tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain]; _tableView.dataSource =self; _tableView.delegate =self; [_tableView registerClass:[ShopInfoCell class] forCellReuseIdentifier:identifier]; _tableView.rowHeight = 80; } return _tableView;}- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return self.dataList.count;}- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { ShopInfoCell * cell = [tableView dequeueReusableCellWithIdentifier:identifier]; cell.shop = self.dataList[indexPath.row]; return cell;}- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. [self.view addSubview:self.tableView]; //使用MJRefresh给我们的talbleView添加下拉刷新上拉加载控件 self.tableView.mj_header = [MJRefreshNormalHeader headerWithRefreshingTarget:self refreshingAction:@selector(loadNewData)]; self.tableView.mj_footer = [MJRefreshBackNormalFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreData)]; // [self loadNewData]; //进入界面执行下拉刷新方法 [self.tableView.mj_header beginRefreshing]; }//上拉加载更多- (void)loadMoreData { NSString * urlString = [NSString stringWithFormat:@"%@%@",SERVER_HOST,API_GetRestaurantsList]; NSDictionary * params = @{@"full_image_path":@"1", @"geohash":@"wx4u14w0649y", @"limit":@(shopInfoPageLimit), @"offset":@(self.page * shopInfoPageLimit), @"type":@"geohash", @"extras[]":@"food_activity", @"extras[]":@"restaurant_activity"}; [[HttpClient defaultClient] requestWithPath:urlString method:HttpRequestGet paramenters:params prepareExecute:^{ [ToolHelper showProgressMessage:@"我在刷新"]; } success:^(NSURLSessionDataTask *task, id responseObject) { NSLog(@"%@",responseObject); //JSON -> MODEL 有很多框架,原理都是KVC. //MJExtenstion JsonModel Mantle YYModel //请求的分页数据 +1 //当返回到数据的count值为0时,说明已经全部加载完毕。 NSArray * shopList = [Shop mj_objectArrayWithKeyValuesArray:responseObject]; // if (shopList.count == 0) { // // //显示已经全部加载完毕 // [self.tableView.mj_footer endRefreshingWithNoMoreData]; // } if (self.page > 2) { [self.tableView.mj_footer endRefreshingWithNoMoreData]; } else { [self.dataList addObjectsFromArray:shopList]; [self.tableView reloadData]; //将上拉加载控件弹下去 [self.tableView.mj_footer endRefreshing]; self.page ++ ; } [ToolHelper showSuccessMessage:@"请求成功"]; } failure:^(NSURLSessionDataTask *task, NSError *error) { NSLog(@"%@",error); //将上拉加载控件弹下去 [self.tableView.mj_footer endRefreshing]; [ToolHelper showErrorMessage:@"请求失败"]; }];}//下拉刷新- (void)loadNewData { NSString * urlString = [NSString stringWithFormat:@"%@%@",SERVER_HOST,API_GetRestaurantsList]; //下拉刷新,上拉加载 请求的地址是一样的 ,只是参数不一样的。 //limit 是不变的、改变 offset。。 // //下拉刷新是加载最新数据,将page页数至为0. //上拉加载加载更多数据。将page++ //MJRefresh EGO下拉刷新 UIRefreshCotrol 自已写上拉下拉 NSDictionary * params = @{@"full_image_path":@"1", @"geohash":@"wx4u14w0649y", @"limit":@(shopInfoPageLimit), @"offset":@(0), @"type":@"geohash", @"extras[]":@"food_activity", @"extras[]":@"restaurant_activity"}; [[HttpClient defaultClient] requestWithPath:urlString method:HttpRequestGet paramenters:params prepareExecute:^{ [ToolHelper showProgressMessage:@"我在刷新"]; } success:^(NSURLSessionDataTask *task, id responseObject) { NSLog(@"%@",responseObject); //JSON -> MODEL 有很多框架,原理都是KVC. //MJExtenstion JsonModel Mantle YYModel //请求的分页数据 +1 self.page = 1 ; //获取最新数据前删除之前的所有数据 [self.dataList removeAllObjects]; NSArray * shopList = [Shop mj_objectArrayWithKeyValuesArray:responseObject]; [self.dataList addObjectsFromArray:shopList]; [self.tableView reloadData]; //重置没有更多的数据(消除没有更多数据的状态) [self.tableView.mj_footer resetNoMoreData]; //将下拉刷新控件弹上去 [self.tableView.mj_header endRefreshing]; [ToolHelper showSuccessMessage:@"请求成功"]; } failure:^(NSURLSessionDataTask *task, NSError *error) { NSLog(@"%@",error); //将下拉刷新控件弹上去 [self.tableView.mj_header endRefreshing]; [ToolHelper showErrorMessage:@"请求失败"]; }];}- (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated.}@end

大家是不是觉得少了些什么,当然是cell的自定义了,蛮简单了。看看就好。

ShopIconCell.h ShopIconCell.m

////  ShopIconCell.h//  CX-小项目(饿了么 网络部分 简单实现)////  Created by ma c on 16/3/23.//  Copyright © 2016年 xubaoaichiyu. All rights reserved.//#import 
#import
#import "Shop.h"@interface ShopInfoCell : UITableViewCell@property (nonatomic, strong) Shop * shop;@end
////  ShopIconCell.m//  CX-小项目(饿了么 网络部分 简单实现)////  Created by ma c on 16/3/23.//  Copyright © 2016年 xubaoaichiyu. All rights reserved.//#import "ShopIconCell.h"#import "UIImageView+WebCache.h"static CGFloat kMargin = 5;@interface ShopInfoCell ()@property (nonatomic, strong) UIImageView * iconView;@property (nonatomic, strong) UILabel * nameLabel;@property (nonatomic, strong) UILabel * descLabel;@end@implementation ShopInfoCell-  (void)setShop:(Shop *)shop {        _shop = shop;            [self.iconView sd_setImageWithURL:[NSURL URLWithString:shop.image_path] placeholderImage:nil];        self.nameLabel.text = shop.name;    self.descLabel.text = shop.desc;}- (UIImageView *)iconView {        if (!_iconView) {        _iconView = [[UIImageView alloc] init];    }    return _iconView;}- (UILabel *)nameLabel {        if (!_nameLabel) {        _nameLabel = [[UILabel alloc] init];    }    return _nameLabel;}- (UILabel *)descLabel {        if (!_descLabel) {        _descLabel = [[UILabel alloc] init];    }    return _descLabel;}-(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {        if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {                [self.contentView addSubview:self.iconView];        [self.contentView addSubview:self.nameLabel];        [self.contentView addSubview:self.descLabel];            }    return self;}- (void)layoutSubviews {        [super layoutSubviews];        self.iconView.frame = CGRectMake(kMargin, kMargin, 70, 70);        self.nameLabel.frame = CGRectMake(CGRectGetMaxX(self.iconView.frame) + kMargin, CGRectGetMinY(self.iconView.frame), SCREEN_WIDTH - CGRectGetMaxX(self.iconView.frame) - 2 * kMargin, 20);        self.descLabel.frame = CGRectMake(CGRectGetMinX(self.nameLabel.frame), CGRectGetMaxY(self.nameLabel.frame) + kMargin, CGRectGetWidth(self.nameLabel.frame), 20);        }- (void)awakeFromNib {}- (void)setSelected:(BOOL)selected animated:(BOOL)animated {    [super setSelected:selected animated:animated];    }@end

就这样一个小项目就这么的完成了。

转载于:https://www.cnblogs.com/angelfeather/articles/5946676.html

你可能感兴趣的文章
搭建Office 2010 KMS服务器
查看>>
ntbackup操作失败
查看>>
LINUX下安装HPL/SQL
查看>>
python 相见恨晚的itertools库
查看>>
vSphere client连接vCenter server时需开放的端口
查看>>
opennms安装心得
查看>>
安装centos 7的时候出现An Unknown Error Has Occurred
查看>>
使用 NGINX 流控和 fail2ban 防止 CC 攻击
查看>>
vim 使用
查看>>
Linux常用命令大全
查看>>
随机点名2
查看>>
7.6 yum更换国内源;7.7 yum下载rpm包;7.8 -7.9 源码包安装
查看>>
ceph存储 磁盘IOPS常识
查看>>
License Server 11.9安装过程中假死
查看>>
【重磅】DeepMind发布通用强化学习新范式,自主机器人可学会任何任务
查看>>
Tomcat在Linux上的安装
查看>>
RedHat 7配置HAProxy实现Web负载均衡
查看>>
探索LSTM:基本概念到内部结构
查看>>
iframe调用父页面javascript函数的方法
查看>>
awt.font在centos上中文乱码的问题
查看>>