IOS项目之分层MVVM
在做.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的更多相关文章
- 在iOS项目中引入MVVM
本文翻译自:http://www.objc.io/issue-13/mvvm.html.为了方便读者并节约时间,有些不是和文章主题相关的就去掉了.如果读者要看原文的话可以通过前面的url直接访问.作者 ...
- Ios 项目从头开发 MVVM模式(三)
1.话说,本来想做个聚合查询功能.可是我的重点想研究xmpp聊天功能.所以使用mvvm模式做了全然模式51job主界面的页面. 2.首先给大家看我执行起来的界面. 3.界面非常easy,做这个界面主要 ...
- MVVM 模式下iOS项目目录结构详细说明
➠更多技术干货请戳:听云博客 我们在做项目的时候,会经常用到各种设计模式,最常见的要数 MVC (模型,视图,控制器)了.但是,今天我们要说的是另一种设计模式——MVVM. 所以 MVVM 到底是什么 ...
- 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. ...
- iOS项目的目录结构和开发流程
转自无网不剩的博客 网上相关的资源不多,开源的且质量还不错的iOS项目也是少之又少,最近正好跟同事合作了一个iOS项目,来说说自己的一些想法. 目录结构 AppDelegate Models Ma ...
- 分享我设计的iOS项目目录结构
公司新项目就要着手研发了,希望能为这个项目多准备点知识.回想自己做过的项目,目录结构的划分总不如我的心意,有些目录命名不规范导致表达不明确,有些目录因为不具有代表性,导致在实际中不能充分发挥作用,导致 ...
- iOS项目架构文档
设计的项目架构主要引用MVVM+MVC架构,并以功能模块分级.以下为目录结构. 初级目录: 我们只需要关注SGZH文件夹下的目录,其他为Xcode管理的目录.可以看到此目录为项目初级目录,我们开发过程 ...
- 剑指Offer——企业级项目中分层的含义与依据及多态的优势
剑指Offer--企业级项目中分层的含义与依据及多态的优势 关于以上两点,由于项目经验较少,自己不是很明白,特整理如下. 常见分层架构模式 三层架构 3-tier architecture 微 ...
- 开源 iOS 项目分类索引大全 - 待整理
开源 iOS 项目分类索引大全 GitHub 上大概600个开源 iOS 项目的分类和介绍,对于你挑选和使用开源项目应该有帮助 系统基础库 Category/Util sstoolkit 一套Cate ...
随机推荐
- 创建可复用的自定义 ASP.NET MVC Helpers
通常,在ASP.NET MVC项目中App_Code目录下新建.cshtml编写类似下方的代码就能创建自定义的MVC Helper了, 假设文件名为StrHelper.cshtml,那么在别的视图中的 ...
- HTML5 SSE 数据推送应用开发
javascript表达行为,css表达外观,注意HTML既表达结构(逻辑结构),又表达内容(数据本身)通常需要更新数据时,并不需要更新结构,正是这种不改变组织结构仅改变数据的诉求,推动了数据拉取和数 ...
- MessagingTimeout: Timed out waiting for a reply to message ID
l3中出现大量消息超时错误,对网络的操作各种异常. 报错如下: 2016-02-25 05:54:59.886 15110 ERROR neutron.agent.l3.agent [req-db92 ...
- CentOS6.3上部署Ceph
一.背景知识 搭建ceph的机器分为两种:client和非client(mds.monitor.osd). 配置时client只需要在内核编译时选上ceph就行,而其它三种则还需要编译ceph用户态源 ...
- 3XX重定向
3XX响应结果表明浏览器需要执行某些特殊的处理以正确处理请求 301 Moved Permanently 永久性重定向 该状态码表示请求的资源已经被分配了新的URI,以后应使用资源现 ...
- Elasticsearch(9):使用Logstash-input-jdbc同步数据库中的数
1.数据同步方式 全量同步与增量同步 全量同步是指全部将数据同步到es,通常是刚建立es,第一次同步时使用.增量同步是指将后续的更新.插入记录同步到es. 2.常用的一些ES同步方法 1). elas ...
- itemgetter和groupby
一. itemgetter的使用方法 itemgetter()返回一个指定列表下标或者字典键的函数,通过这个返回的函数作用到对象上,获得才能取得相应的值 1. 排序字典列表的一个例子 from ope ...
- python基础知识梳理-----1变量,常量,注释
因为公司用的是delphi ,所以自学了一阵delphi,但是随着语言的发展,delphi的前景堪忧啊.辞职以后打算好好学学python,然后找找数据分析和爬虫方面的工作. 记录此贴,仅作学习使用,所 ...
- vue重构后台管理系统调研
Q4要来了,我来这家公司已经一个季度了,通过对公司前端框架的整体认识,对业务的一些认识,发现,这些东西也都是可以重构,无论是v2,还是v3的代码. 首先就要那后台管理来开刀来,现有的技术框架就是php ...
- 47.ActiveMQ集群
(声明:本文非EamonSec原创) 使用ZooKeeper实现的Master-Slave实现方式,是对ActiveMQ进行高可用的一种有效的解决方案,高可用的原理:使用ZooKeeper(集群)注册 ...