在做.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. Java--下载历史版本登录账户

    目前在官网下载低于jdk1.8的java jdk的时候需要登陆,这边分享一个账号,方便下载 2696671285@qq.com 密码:Oracle123 转自-- jdk下载以前版本需要的账号(转) ...

  2. 云架构和openstack的思考

    原文链接: http://ifeve.com/cloud-architecture-openstack/ 作者:罗立树 最近在负责公司内部私有云的建设,一直在思考怎么搞云计算,怎么才能够把云架构设计得 ...

  3. Redis安装与测试

    ①安装,直接安装版本为4.0.1 sudo apt-get install redis-server 启动: redis-server redis-cli 测试: ②新建Student表 ③查看zha ...

  4. html页面pc显示正常,在手机端适配也可以看整个页面

    <meta name="viewport" content="width=1250,initial-scale=0,maximum-scale=2"/&g ...

  5. Mybatis 类的转换器

    想一个事情 ,例: 我数据库的表 定义了一个表student 里面有一个字段 stu_sex  int类型  可是我对应的实体类是 String 类型或者其他类型 这个时候 实体类与数据库表肯定对应不 ...

  6. Lexicographical Substring Search (spoj7259) (sam(后缀自动机)+第k小子串)

    Little Daniel loves to play with strings! He always finds different ways to have fun with strings! K ...

  7. LOJ#6045. 「雅礼集训 2017 Day8」价(最小割)

    题面 传送门 题解 首先先把所有权值取个相反数来求最大收益,因为最小收益很奇怪 然后建图如下:\(S\to\)药,容量\(\inf+p_i\),药\(\to\)药材,容量\(\inf\),药材\(\t ...

  8. django rest framework 向数据库中插入数据时处理外键的方法

    一.models.py中 from django.db import models class UserModel(models.Model) user_name = models.CharField ...

  9. robot framework学习笔记之十-模板

    测试模板可以让关键字驱动测试用例转换为数据驱动测试用例.鉴于普通测试用例是由关键字和可能的参 数组成,使用了模板的测试用例只需要定义模板关键字的参数即可

  10. springboot多数据源动态切换和自定义mybatis分页插件

    1.配置多数据源 增加druid依赖 完整pom文件 数据源配置文件 route.datasource.driver-class-name= com.mysql.jdbc.Driver route.d ...