IOS_网络请求中的MVC应用(数据模型类)

来自本群【言志_iOS_厦门】的投稿,当天预约,当天出稿子,很感谢每一个支持Mark群的人。附加补充Demo点击下载

简单总结下Blog内容就是 “把数据层抽离出来 ,解析MVC模式,是一个MVC的应用实例,在网络请求时,将MVC分离。

个人觉得这个分享很实用,还包含了设计模式的理念在里面。

以下是言志兄的分享内容:


1.在初学iOS时,大部分人会遇到的头疼问题是:用NSURLConnection请求一个URL,然后将返回的数据显示到UIView上。
2.如果没有很好的MVC概念,估计会把这些东西东西全部写在ViewController里面。


================================华丽的分割线===============================
一.讲解如何将这个过程区分开
1.曾经我一直坚信不疑的以为ViewController是一个C()。后来才知道ViewController类和所有的控件都是属于MVC中的V(View)(当我知道这个以后,万念俱灰啊)。
2.C的作用就是将ViewController和Modal相连接。
3.MVC的顺序: V->C->M  M-C->V。下面4-9就阐述了这么一个过程。
4.ViewController类中的click()方法调用了Controller类中refresh()方法。
5.getInformation()方法里调用了NetWork()类中的request();
6.request()请求完成后,等待系统调用- (void)connectionDidFinishLoading:(NSURLConnection *)connection()方法。
7.- (void)connectionDidFinishLoading:(NSURLConnection *)connection()方法通过NetWork类中的delegate,去调用refresh()方法[_delegate refresh]。
8.在Controller中具体实现refresh(),通过Controller中的delegate,去调用getInformationFromRequest()协议 [delegate getInformationFromRequest];

9.最后在ViewController中具体实现getInformationFromRequest()方法。



==================================具体实现代码参考==============================


=======================V->C->NetWork->Modal========================
ViewController类中点击按钮触发事件
//请求Flurry API
- (IBAction)getEventsInformation:(id)sender
{
    Reachability *r = [Reachability reachabilityWithHostName:@"baidu.com"];
    switch ([r currentReachabilityStatus]) {
        case NotReachable:
        {
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"网络异常" message:@"请检查下网络" delegate:self cancelButtonTitle:@"好的" otherButtonTitles:nil, nil];
            [alert show];
            break;
        }
        case ReachableViaWWAN:
        {
        }
        case ReachableViaWiFi:
        {
        }default:
        {
            //调用MBProgressHUD这个方法,在网络请求的时候就会转圈圈了!圈圈啊~画圈圈诅咒你。
[MBProgressHUD showHUDAddedTo:self.view animated:YES];
            //_requestController是MVC中的C(Controller)
            [_requestController getInformation];
        }
    }
}


//RequestController类
- (void)getInformation
{
    //_request为网络请求的实例
    [_request requestFlurry];
}


//EventRequest类
@protocol EventRequestDelegate <NSObject>
@required
- (void)refresh;
- (void)refreshFail;
@end


@interface EventRequest : NSObject<NSURLConnectionDataDelegate>
@property (nonatomic,weak) id<EventRequestDelegate> delegate;


@implementation EventRequest
//请求Flurry
- (void) requestFlurry
{
    _eventData = [[NSMutableData alloc] init];
    NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:Flurry_Event_URL,Access_Code,BEAUTY_FLURRY_APPKEY,Start_Time,[EventRequest getAmericaTime]]];
    NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];
    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    [connection start];
}


//因为网络数据是分批进来的,所以将每次获得的data数据追加到 _eventData中
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    [_eventData appendData:data];
}


//获取数据并写到plist文件中
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{


    _totalInformation = [[TotalInformation alloc] init];
    NSError *jsonError;
//TotalInformation为Modal,Request请求后所获得的数据保存到_totalInformation中。
    _totalInformation.totalDic = [NSJSONSerialization JSONObjectWithData:_eventData options:0 error:&jsonError];
    //将数据写到plist文件中,以后读取数据可以直接访问本地的plist文件进行读取
    [_totalInformation writeToPlist];
    //通过委托调用refresh
    [_delegate refresh];
//    [MatchingData match:[_totalInformation readFromPlist] withPlist:@"1001"];
    NSLog(@"Finish");
}
//数据获取失败调用该方法
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    if (error) {
        NSLog(@"%@",error);
        //通过委托调用refreshFail
        [_delegate refreshFail];
    }
}




//TotalInformation类
@property (nonatomic,strong) NSDictionary *totalDic;
@property (nonatomic,strong) NSArray *event;




//至于是NSDictionary还是NSArray,需要根据你返回的数据来决定
//存入plist文件
- (void)writeToPlist
{
    _event = [_totalDic objectForKey:@"event"];
    NSFileManager* fm = [NSFileManager defaultManager];
    [fm createFileAtPath:Total_Information_Path contents:nil attributes:nil];
    NSLog(@"%@",Total_Information_Path);
    [_event writeToFile:Total_Information_Path atomically:YES];
    NSLog(@"%@",_event);
    
}


//从plist文件中读取
- (NSArray *)readFromPlist
{
    _event = [NSArray arrayWithContentsOfFile:Total_Information_Path];
    return _event;
}




=======================NetWork->C->View========================
//RequestController类
@protocol RequestControllerDelegate <NSObject>
@required
- (void)getInformationFromRequest;
- (void)getInformationFromRequestFail;
@end
@interface RequestController : NSObject<EventRequestDelegate>
@property (nonatomic,strong) TotalInformation *totalInformation;
@property (nonatomic,weak) id<RequestControllerDelegate> delegate;


@implementation RequestController
//初始化时设置request.delegte = self; 这样才会调用下面的refresh()和refreshFail()方法
- (id)init
{
    if (self = [super init])
    {
        _request = [[EventRequest alloc]init];
        _request.delegate = self;
    }
    return self;
}


//实现EventRequestDelegate协议中的方法
//网络请求成功时
- (void)refresh
{
    [_delegate getInformationFromRequest];
}
//网络请求失败时
- (void)refreshFail
{
    [_delegate getInformationFromRequestFail];
}


//ViewController
//记得写RequestControllerDelegate
@interface ViewController : UIViewController<MBProgressHUDDelegate,RequestControllerDelegate>


@implementation ViewController


//设置RequestController的delegate.
- (void)viewDidLoad
{
    _finishLabel.hidden = YES;
    _requestController = [[RequestController alloc] init];
    _requestController.delegate = self;
    [super viewDidLoad];
//    self.delegate = self;
// Do any additional setup after loading the view, typically from a nib.
}


//实现RequestControllerDelegate中的两个方法
#pragma mark - RequestControllerDelegate methods
//刷新完成,隐藏指示器和Label
- (void)getInformationFromRequest
{
    //请求成功后将圈圈隐藏掉
    [MBProgressHUD hideHUDForView:self.view animated:YES];
    //To-do   这里可以通过Controller类来调用Modal中的数据,将Modal中的数据赋值给对应的视图
}


//刷新异常,隐藏指示器和Label
- (void)getInformationFromRequestFail
{
    //请求失败后也将圈圈隐藏掉
    [MBProgressHUD hideHUDForView:self.view animated:YES];
    //To-do   这里可以通过Controller类来调用Modal中的数据,将Modal中的数据赋值给对应的视图

}


-------------------------------------------------------------------------------------------------------------------------------------

附上言志兄弟的原稿JPG


你可能感兴趣的:(ios,mvc,Model)