在做.Net时,有用到三层架构,使项目分层。ios项目使用AFNetWork把网络层这块也放进了ViewController中,数据解析缓存这些也在里面,这样层次结构可能不够清楚,今天就试着分离了一下。

1.类结构

首页主要有三个部分组成,顶部的广告,中部的图标,和下部的一些单元格。设计了三个类,AdModel、IconModel、HomeFeedModel,参考MVVM同时设计了一个ViewModel,声明了服务电话以及三个存储上面类对象的数组。原以为将前面的三个类实现NSCoding协议就可以了没想到ViewModel也要实现。

2.AFNetWorking分离

(1)遇到的问题

想着写一个方法可以获取请求数据的同时也能把错误信息返回出来所以开始就写了下面的代码, 运行发现msg、errmsg都是空,断点之后发现AFNetWork请求部分是异步的,return之前还没有给msg赋值,让我很是纠结, 这样就没有返回值。另block中修改外部变量要加__block

(2)解决

由于上面出现的问题,两个类的传值还是有问题,属于有多个返回值,问了下小伙伴,说结构有问题,需要用代理或者block,于是我又加了一个block,这下试了是可以的 @Class前置声明

#import <Foundation/Foundation.h>
@class HomeModel;
typedef void(^homeModelBlock) (HomeModel *model,NSString *errmsg);
@interface HomeModel : NSObject
@property(nonatomic,strong) NSString *telPhone;
@property(nonatomic,strong) NSMutableArray *adList;
@property(nonatomic,strong) NSMutableArray *iconList;
@property(nonatomic,strong) NSMutableArray *homeFeedList;
@property(nonatomic,copy)  homeModelBlock homeBlock;

-(void)GetHomeData;

@end
//
//  HomeModel.m
//  XQB
//
//  Created by City--Online on 15/6/24.
//
//

#import "HomeModel.h"
#import "AdModel.h"
#import "IconModel.h"
#import "HomeFeed.h"
#import "Global.h"

@implementation HomeModel

//NSCoding协议
-(void)encodeWithCoder:(NSCoder *)aCoder
{
    [aCoder encodeObject:self.telPhone forKey:@"telPhone"];
    [aCoder encodeObject:self.adList forKey:@"adList"];
    [aCoder encodeObject:self.iconList forKey:@"iconList"];
    [aCoder encodeObject:self.homeFeedList forKey:@"homeFeedList"];
}
- (instancetype)initWithCoder:(NSCoder *)coder
{
    self = [super init];
    if (self) {
        _telPhone=[coder decodeObjectForKey:@"telPhone"];
        _adList=[coder decodeObjectForKey:@"adList"];
        _iconList=[coder decodeObjectForKey:@"iconList"];
        _homeFeedList=[coder decodeObjectForKey:@"homeFeedList"];
    }
    return self;
}

- (instancetype)init
{
    self = [super init];
    if (self) {
        self.adList=[[NSMutableArray alloc]init];
        self.iconList=[[NSMutableArray alloc]init];
        self.homeFeedList=[[NSMutableArray alloc]init];
    }
    return self;
}
//网络请求获取数据
-(void)GetHomeData
{
    __block HomeModel *homeModel=[[HomeModel alloc]init];
    __block NSString *msg=[[NSString alloc]init];
    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager shareManager];
    NSMutableDictionary *parameters = [[NSMutableDictionary alloc] initWithDictionary:[CommonParameters getCommonParameters]];
    [parameters addSignatureKey];
    [manager GET:API_HOME_URL parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
        //        XQBLog(@"\nresponseObject:%@", responseObject);
        if ([[responseObject objectForKey:XQB_NETWORK_ERROR_CODE] isEqualToString:XQB_NETWORK_ERROR_CODE_OK]) {
            NSMutableDictionary *dataDic = [responseObject objectForKey:@"data"];
            homeModel= [self transData:dataDic];
            msg=@"chenggong";
            _homeBlock(homeModel,nil);

        } else {
            //加载服务器异常界面
            homeModel=[self unArchiverData];
            msg=@"服务器异常";
            _homeBlock(homeModel,msg);
        }
    }failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        //加载网络异常界面
        msg=@"网络异常";
        homeModel=[self unArchiverData];
        _homeBlock(homeModel,msg);
    }];
    return ;
}

-(HomeModel *)transData:(NSDictionary *)dic
{
    HomeModel *homeModel=[[HomeModel alloc]init];

    NSString *telPhone = DealWithJSONValue([dic objectForKey:@"telephone"]);
    homeModel.telPhone=telPhone;

     NSArray *adArray = [dic objectForKey:@"ads"];
    for (NSDictionary *adInfo in adArray) {
        AdModel *adModel = [[AdModel alloc] init];
        adModel.adId = [[adInfo objectForKey:@"adId"] stringValue];
        adModel.imageUrl = DealWithJSONValue([adInfo objectForKey:@"image"]);
        adModel.link = DealWithJSONValue([adInfo objectForKey:@"link"]);
        adModel.title = DealWithJSONValue([adInfo objectForKey:@"title"]);
        [homeModel.adList addObject:adModel];
    }

    NSArray *homeIcons = [dic objectForKey:@"homeIcons"];
    for (NSDictionary *homeIconDic in homeIcons) {
        IconModel *item = [[IconModel alloc] init];
        item.title = [homeIconDic objectForKey:@"title"];
        item.icon = [homeIconDic objectForKey:@"icon"];
        item.linkUrl = [homeIconDic objectForKey:@"linkUrl"];
        item.type = [homeIconDic objectForKey:@"type"];
        item.createId = [[homeIconDic objectForKey:@"createId"] stringValue];
        item.iconId = [[homeIconDic objectForKey:@"id"] stringValue];
        item.category = [homeIconDic objectForKey:@"category"];

        [homeModel.iconList addObject:item];

    }
    NSArray *feedsDic = [dic objectForKey:@"feeds"];
    for (NSDictionary *feedDic in feedsDic) {
        HomeFeed *model = [[HomeFeed alloc] init];
        model.feedId = [[feedDic objectForKey:@"feedId"] stringValue];
        model.feedType = [feedDic objectForKey:@"feedType"];
        model.title = DealWithJSONValue([feedDic objectForKey:@"title"]);
        model.icon = DealWithJSONValue([feedDic objectForKey:@"icon"]);
        model.content = DealWithJSONValue([feedDic objectForKey:@"content"]);
        model.feedCity = [feedDic objectForKey:@"feedCity"];
        model.linkType = [feedDic objectForKey:@"linkType"];
        [homeModel.homeFeedList addObject:model];
    }
    [self savefile:homeModel];
    return homeModel;
}

//解档
-(HomeModel *)unArchiverData
{
    NSMutableData *mutableData=[[NSMutableData alloc]initWithContentsOfFile:[self filePath]];
    NSKeyedUnarchiver *unarchiver=[[NSKeyedUnarchiver alloc]initForReadingWithData:mutableData];
    HomeModel *model=[unarchiver decodeObjectForKey:@"homeModel"];
//    NSLog(@"%@   %@",model.telPhone,model.adList);
//    for (IconModel *admodel in model.iconList) {
//        NSLog(@"%@",admodel.title);
//    }
    return model;
}
//归档
-(void)savefile:(HomeModel *)model
{

    NSMutableData *mutableData=[[NSMutableData alloc]init];
    NSKeyedArchiver *archiver=[[NSKeyedArchiver alloc]initForWritingWithMutableData:mutableData];
    [archiver encodeObject:model forKey:@"homeModel"];
    [archiver finishEncoding];
    [mutableData writeToFile:[self filePath] atomically:YES];

}
//获取文件路径
-(NSString *)filePath
{
    NSArray *documents=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentpath=[documents firstObject];
    NSString *filePath=[documentpath stringByAppendingPathComponent:@"home"];
    return filePath;
}
@end

这样就能实现网络和ViewController的分离了,再往下可以将业务逻辑和网络层再分离,项目不大,这里就没有细分

IOS项目之分层MVVM的更多相关文章

  1. 在iOS项目中引入MVVM

    本文翻译自:http://www.objc.io/issue-13/mvvm.html.为了方便读者并节约时间,有些不是和文章主题相关的就去掉了.如果读者要看原文的话可以通过前面的url直接访问.作者 ...

  2. Ios 项目从头开发 MVVM模式(三)

    1.话说,本来想做个聚合查询功能.可是我的重点想研究xmpp聊天功能.所以使用mvvm模式做了全然模式51job主界面的页面. 2.首先给大家看我执行起来的界面. 3.界面非常easy,做这个界面主要 ...

  3. MVVM 模式下iOS项目目录结构详细说明

    ➠更多技术干货请戳:听云博客 我们在做项目的时候,会经常用到各种设计模式,最常见的要数 MVC (模型,视图,控制器)了.但是,今天我们要说的是另一种设计模式——MVVM. 所以 MVVM 到底是什么 ...

  4. ios项目里扒出来的json文件

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Menlo; color: #000000 } p.p2 { margin: 0.0px 0. ...

  5. iOS项目的目录结构和开发流程

    转自无网不剩的博客 网上相关的资源不多,开源的且质量还不错的iOS项目也是少之又少,最近正好跟同事合作了一个iOS项目,来说说自己的一些想法.   目录结构 AppDelegate Models Ma ...

  6. 分享我设计的iOS项目目录结构

    公司新项目就要着手研发了,希望能为这个项目多准备点知识.回想自己做过的项目,目录结构的划分总不如我的心意,有些目录命名不规范导致表达不明确,有些目录因为不具有代表性,导致在实际中不能充分发挥作用,导致 ...

  7. iOS项目架构文档

    设计的项目架构主要引用MVVM+MVC架构,并以功能模块分级.以下为目录结构. 初级目录: 我们只需要关注SGZH文件夹下的目录,其他为Xcode管理的目录.可以看到此目录为项目初级目录,我们开发过程 ...

  8. 剑指Offer——企业级项目中分层的含义与依据及多态的优势

    剑指Offer--企业级项目中分层的含义与依据及多态的优势   关于以上两点,由于项目经验较少,自己不是很明白,特整理如下. 常见分层架构模式 三层架构 3-tier architecture   微 ...

  9. 开源 iOS 项目分类索引大全 - 待整理

    开源 iOS 项目分类索引大全 GitHub 上大概600个开源 iOS 项目的分类和介绍,对于你挑选和使用开源项目应该有帮助 系统基础库 Category/Util sstoolkit 一套Cate ...

随机推荐

  1. Oracle数据库01

    常用函数 COUNT(*):统计所有的数据量,没有过滤功能 COUNT(字段):统计出指定字段不为null的数据量,有过滤功能 COUNT(DISTINCT 字段):统计指定字段不为空并且去掉重复数据 ...

  2. qi zi

    #include<stdio.h> ]; ][]; int N; typedef struct node{ int x; }node; node dui[]; int se(int a) ...

  3. DOM学习日记1

    1.通过 id 查找 HTML 元素 var x=document.getElementById("intro"); 2.通过标签名查找 HTML 元素本例查找 id=" ...

  4. PHP和JS中全局变量和局部变量

    一,PHP中全局变量和局部变量 php与C++中对全局变量和局部变量定义类似,全局变量:函数外定义的变量,在全局通用:局部变量:在函数内定义的变量,只在函数内有效.PHP中变量范围跨越了include ...

  5. jmeter进行https协议的测试

    一.HTTPS和HTTP的区别     超文本传输协议HTTP协议被用于在Web浏览器和网站服务器之间传递信息.HTTP协议以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了Web浏览器和 ...

  6. 分享一些JAVA常用的学习网站

    常用学习网站freecodecamp 一个非常好的网站,教学模式类似游戏中的闯关,通过每关之后会有成就感,在该网站还有设有聊天室,可以进行相关的技术交流,很棒的学习网站. https://www.fr ...

  7. windows10 pip install MySQL-python mysqlclient

    https://dev.mysql.com/downloads/connector/python/ 到上述地址下载对应系统的驱动程序安装即可. 安装mysqlclient方法如下: https://w ...

  8. iOS几个功能:1.摇一摇;2.震动;3.简单的摇动动画;4.生成二维码图片;5.发送短信;6.播放网络音频等

    有一个开锁的功能,具体的需求就类似于微信的“摇一摇”功能:摇动手机,手机震动,手机上的锁的图片摇动一下,然后发送开锁指令.需求简单,但用到了许多方面的知识. 1.摇一摇 相对这是最简单的功能了. 在v ...

  9. js及Java中对于两个时间日期的判断脚本

    JS脚本: function checkDateIsEdited(createDate) { var compareDate = createDate.replace("-",&q ...

  10. 我永远喜欢我的偶像 KIKU