您的位置:首页 > 其它

仿新浪微博学习笔记之封装思想

2015-07-03 19:35 411 查看
当我向服务器发送一个请求后,服务器会返回一个JSON数据包给我,然后我需要解析这个数据包。在OC中,JSON相当于一个字典,我个人觉得解析的方法比较好的是通过模型,这样更加能够体现OC的封装思想。
下面是抽取出来的部分代码,功能是下拉刷新(已经是封装过的)

/*
*    下拉刷新
*/
- (void) loadNewData
{
// 0.清除提醒数字
self.tabBarItem.badgeValue = nil;

// 1.封装请求参数
QLDHomeStatusesParam *param = [QLDHomeStatusesParam param];
if (self.statusFrames.count) {
QLDStatusFrame *statusFrame = self.statusFrames[0];
//加载ID比since_id大的微博
param.since_id= @([statusFrame.status.idstr longLongValue]);
}
[QLDStatusTool homeStatusesWithParams:param success:^(QLDHomeStatusResult *result) {
//创建frame模型对象
NSMutableArray *statusFrameArray = [NSMutableArray array];
for (QLDStatus *status in result.statuses) {
QLDStatusFrame *statusFrame = [[QLDStatusFrame alloc] init];
//传递微博模型数据
statusFrame.status = status;
[statusFrameArray addObject:statusFrame];
}

//将最新的数据追加到旧数据的最前面
//旧数据:self.statusFrames
//新数据:statusFrameArray
NSMutableArray *tempArray = [NSMutableArray array];
[tempArray addObjectsFromArray:statusFrameArray];
[tempArray addObjectsFromArray:self.statusFrames];
self.statusFrames = tempArray;

//刷新表格
[self.tableView reloadData];

//让刷新控件停止显示刷新状态
[self.header endRefreshing];

//显示最新微博的数量(给用户一些友善的提示)
[self showNewStatusCount:statusFrameArray.count];
} failure:^(NSError *error) {
//让刷新控件停止显示刷新状态
[self.header endRefreshing];
}];

}


下面来解释哪里封装了,为什么要封装,怎么封装。

1.哪里封装了,为什么封装?
在上面可以看到发送封装参数的时候,参数是经过了封装的QLDHomeStatusesParam
,参数封装之后更加能够方便使用,如果直接使用字典的话,很容易写错,而这个不容易写错,而且还会有提示。

还有
QLDStatusTool也进行了封装,可以看出这个封装里面是需要URL的,就是联网了

最后就是QLDHomeStatusResult,也进行了封装,这个可以看出是对结果的封装

2.怎么封装?

先看参数的封装QLDHomeStatusesParam:
根据新浪微博的开放接口的文档来看,要实现下拉刷新,即加载首页微博数据,需要传递4个参数:since_id,max_id,count,access_token,由于很多参数里都需要用到access_token,所以又建了一个基类,放access_token
所以,在QLDHomeStatusesParam.h里面申明:

#import <Foundation/Foundation.h>
#import "QLDBaseParam.h"

@interface QLDHomeStatusesParam : QLDBaseParam

//若指定此参数,则返回ID比since_id大的微博(即比since_id时间晚的微博),默认为0
@property (nonatomic, strong) NSNumber *since_id;

//若指定此参数,则返回ID小于或等于max_id的微博,默认为0
@property (nonatomic, strong) NSNumber *max_id;

//单页返回的记录条数,最大不超过100,默认为20
@property (nonatomic, strong) NSNumber *count;
@end


这样就可以,但是为什么要用NSNumber呢,我今天又看了一遍视频,用NSNumber不用NSInteger的原因是:
如果用NSInteger,那么到时候在解析JSON的时候,需要进行判断,如果结果是NULL的,那么会出现bad,那么如果要让NULL也能不出错,就需要进行一个一个的判断,太过繁琐,所以需要用到NSNumber,NSNumber不会出现上面的情况。

接下来就是封装QLDHomeStatusResult了

QLDHomeStatusResult.h

#import <Foundation/Foundation.h>

@interface QLDHomeStatusResult : NSObject

//statuses数组里面放的都是QLDStatus模型
@property (nonatomic, strong) NSArray *statuses;

@property (nonatomic, assign) long long previous_cursor;
@property (nonatomic, assign) long long next_cursor;

//总数
@property (nonatomic, assign) long long total_number;

@end

QLDHomeStatusResult.m
#import "QLDHomeStatusResult.h"
#import "MJExtension.h"
#import "QLDStatus.h"

@implementation QLDHomeStatusResult

-(NSDictionary *)objectClassInArray
{
return @{@"statuses" : [QLDStatus class]};
}

@end


因为statuses里面存放的是模型,所以在.m文件中需要进行复制,这个方法是在MJExtension里面的

上面是2个模型,参数模型和结果模型,下面需要在工具类中用到:QLDStatusTool

在QLDStatusTool.h

#import <Foundation/Foundation.h>
#import "QLDHomeStatusesParam.h"
#import "QLDHomeStatusResult.h"

@interface QLDStatusTool : NSObject

/*
*    加载首页的微博数据
*   @param params     请求参数
*   @param success    请求成功后的回调
*   @param failure       请求失败后的回调
*/
+ (void)homeStatusesWithParams: (QLDHomeStatusesParam *)param success:(void(^) (QLDHomeStatusResult *result))success failure:(void (^) (NSError *error))failure;

@end


这个实例方法可以就是为了加载首页的微博数据,里面用到上面的2个模型,分别作为参数和成功时的结果,这里需要注意的是block的写法

在QLDStatusTool.m

#import "QLDStatusTool.h"
#import "QLDHttpTool.h"
#import "MJExtension.h"

@implementation QLDStatusTool
+ (void)homeStatusesWithParams: (QLDHomeStatusesParam *)param success:(void(^) (QLDHomeStatusResult *result))success failure:(void (^) (NSError *error))failure;
{
[QLDHttpTool getWithURL:@"https://api.weibo.com/2/statuses/home_timeline.json" params:param.keyValues success:^(id json) {
if (success) {
QLDHomeStatusResult *result = [QLDHomeStatusResult objectWithKeyValues:json];
success(result);
}
} failure:^(NSError *error) {
if (failure) {
failure(error);
}
}];
}

@end


从上面可以知道此次是用了get请求,result里面就是存放了解析结果的,同时success(result);调用。

从上面可以看出封装之后代码更加整洁,同时相互独立能够分解出来,最后做修改的时候能够更加的方便。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: