在做.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. SQL字符串分割转列,Sql列转字符串

    declare @strVar varchar(2000)declare @ResultVar varchar(2000)set @ResultVar='[薄饼],[点心],[海鲜],[酒吧],[楼面 ...

  2. WebBrowser控件支持WebSocket

    修改html页面,在Header标签中添加如下标签: <meta http-equiv="X-UA-Compatible"content="IE=edge" ...

  3. SQL查询速度慢的原因分析和解决方案

    SQL查询速度慢的原因分析和解决方案 查询速度慢的原因很多,常见如下几种: 1.没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷) 2.I/O吞吐量小,形成了瓶颈效应. 3.没有创建 ...

  4. [SSH]struts2-spring-plugin.jar了解

    在struts2-spring-plugin.jar中有一个struts-plugin.xml,里面声明了action类由spring工厂创建.在struts2插件文档里,这样写着“The Sprin ...

  5. Git 常用知识

    git 常用命令 创建并checkout分支: git checkout -b branch_name git merge 与 git rebase 的区别 git rebase 合并后将形成一条直线 ...

  6. iOS 画图基础

    基础要点: 1,画图不可以在 ViewController 里,而是应该在一个 UIView 的子类中,比如新建一个 DrawView 继承自 UIView. 2,覆盖 UIView 的 drawRe ...

  7. Spring 中aop切面注解实现

    spring中aop的注解实现方式简单实例   上篇中我们讲到spring的xml实现,这里我们讲讲使用注解如何实现aop呢.前面已经讲过aop的简单理解了,这里就不在赘述了. 注解方式实现aop我们 ...

  8. 【文文殿下】浅谈KMP算法next数组与循环节的关系

    KMP算法 KMP算法是一种字符串匹配算法,他可以在O(n+m)的时间内求出一个模式串在另一个模式串下出现的次数. KMP算法是利用next数组进行自匹配,然后来进行匹配的. Next数组 Next数 ...

  9. PHP中运算符优先级

    运算符优先级指定了两个表达式绑定得有多“紧密”.例如,表达式 1 + 5 * 3 的结果是 16 而不是 18 是因为乘号(“*”)的优先级比加号(“+”)高.必要时可以用括号来强制改变优先级.例如: ...

  10. jquery源码解析:jQuery队列操作queue方法实现的原理

    我们先来看一下jQuery中有关队列操作的方法集: 从上图可以看出,既有静态方法,又有实例方法.queue方法,相当于数组中的push操作.dequeue相当于数组的shift操作.举个例子: fun ...