在做.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. css细节复习笔记——内边距、边框和外边距

    一个元素的内边距.边框和外边距属性会影响着整个文档如何布局,更重要的是,它们会严重影响给定元素的外观. 高度和宽度 这两个属性不能应用到行内非替换元素,其高度和宽度由链接的内容确定,而不是由创作人员确 ...

  2. mac下MySQL Workbench安装

    参见:http://www.cnblogs.com/macro-cheng/archive/2011/10/25/mysql-001.html 去mysql官网下载社区的.dmg安装包 分别安装: 分 ...

  3. SoundPool

    如果应用程序经常播放密集.急促而又短暂的音效(如游戏音效)那么使用MediaPlayer显得有些不太适合了.因为MediaPlayer存在如下缺点: 1) 延时时间较长,且资源占用率高. 2) 不支持 ...

  4. 激活xmind的方法

    https://blog.csdn.net/qq_38238041/article/details/81107127 这里以windows为例来演示,其它操作系统需根据情况修改相应步骤. 下载安装包 ...

  5. [ActionScript 3.0] 记录几个ByteArray 十六进制 String等相互转换的方法

    /** * 通过hax数据返回ByteArray * @param hax 格式 "AA5A000100FF" */ private function getHax(hax:Str ...

  6. 修改linux的文件时,如何快速找到要修改的内容

    ♦ 在linux系统下,找到需要修改的文件.使用cd+目录的命令进行文件所在的目录,使用ls命令查看是否有该文件. ♦ 使用vim+文件名,打开该文件 ♦ 快速在文件中找到需要修改的地方.如我们需要修 ...

  7. Python Socket 编程示例 Echo Server

    简评:我们已经从「Python Socket 编程概览」了解了 socket API 的概述以及客户端和服务器的通信方式,接下来让我们创建第一个客户端和服务器,我们将从一个简单的实现开始,服务器将简单 ...

  8. google Agent

    一句话:改HOSTS文件 有时候要查看appengine.google.com的后台,但死活上不去,怎么办?还是那个老办法: 1.在cmd下Ping www.google.com.hk,获得IP地址, ...

  9. 调用jdbc已经写成的方法----jdbc工具类抽取方式二

    先创建db.properties driver=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/web08?useUnicode=true& ...

  10. 总结day13 ----内置函数

    内置函数 我们一起来看看python里的内置函数.什么是内置函数?就是Python给你提供的,拿来直接用的函数,比如print,input等等.截止到python版本3.6.2,现在python一共为 ...