IOS-小項目(餓了麼 網路部分 簡單實現)

來源:互聯網
上載者:User

標籤:work   sub   .pch   .text   ssi   程式啟動   conf   工作   break   

在介紹小項目之前,在此說明一下此代碼並非本人所寫,我只是隨筆的整理者。

在介紹之前先展現一下。

看過大家應該很熟悉了,就是餓了麼的一個介面而已,值得注意的是,實現時並沒有採用本地串連,而是實打實的網路連接。看一下檔案架構。

這一採用的是MVC設計模式,雖然檔案很少,但是也可以看。

下面開始正式介紹小項目的實現。

首先介紹Model的實現,很簡單,實現模型即可,

Shop.h
////  Shop.h//  CX-小項目(餓了麼 網路部分 簡單實現)////  Created by ma c on 16/3/23.//  Copyright ? 2016年 xubaoaichiyu. All rights reserved.//#import <Foundation/Foundation.h>@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 <Foundation/Foundation.h>#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 <Foundation/Foundation.h>@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 <Foundation/Foundation.h>@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 <UIKit/UIKit.h>#import <Foundation/Foundation.h>#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 <UIKit/UIKit.h>@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 ()<UITableViewDataSource,UITableViewDelegate>//分頁的頁數@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 <UIKit/UIKit.h>#import <UIKit/UIKit.h>#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

就這樣一個小項目就這麼的完成了。

IOS-小項目(餓了麼 網路部分 簡單實現)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.