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,assign)  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的分离了,再往下可以将业务逻辑和网络层再分离,项目不大,这里就没有细分

时间: 2024-08-01 14:07:59

IOS项目之网络分离的相关文章

iOS项目开发实战——iOS网络编程获取网页Html源代码

如今我们身处互联网的时代,任何一个软件或是App,都会或多或少与网络打交道,并不断发生数据交互.一个没有涉及网络编程的应用会显得比较low,这里我们将会开始使用Swift开发iOS应用,并且主要来实现网络操作方面的功能. 这里的需求是获取某个网页的Html源代码,即从网上获取数据.具体实现如下: (1)创建一个iOS项目,Language选择Swift.然后在ViewController.swift中实现如下代码: override func viewDidLoad() { super.view

iOS项目开发实战——iOS网络编程获取网页Html源码

现在我们身处互联网的时代.不论什么一个软件或是App,都会或多或少与网络打交道,并不断发生数据交互.一个没有涉及网络编程的应用会显得比較low,这里我们将会開始使用Swift开发iOS应用,而且主要来实现网络操作方面的功能. 这里的需求是获取某个网页的Html源码,即从网上获取数据.详细实现例如以下: (1)创建一个iOS项目,Language选择Swift.然后在ViewController.swift中实现例如以下代码: override func viewDidLoad() { super

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.0px 0.0px 0.0px; font: 13.0px Menlo; color: #d12f1b } p.p3 { margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px "PingFang SC"; color: #d12f1b } p.p4 {

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

?更多技术干货请戳:听云博客 我们在做项目的时候,会经常用到各种设计模式,最常见的要数 MVC (模型,视图,控制器)了.但是,今天我们要说的是另一种设计模式——MVVM. 所以 MVVM 到底是什么?下面,我们将结合代码,说明 MVVM 设计模式以及项目目录结构. 一.MVVM 模式介绍  MVVM 是 Model-View-View Model 的缩写,MVVM 听起来好像很复杂的样子,但它本质上就是MVC 的改进版.MVVM 就是将其中的View 的状态和行为抽象化,让我们将视图 UI 和

关于目前自己iOS项目使用的第三方开源库

1.AFNetworking 目前比较推荐的iOS网络请求组件,默认网络请求是异步,通过block回调的方式对返回数据进行处理. 2.FMDB 对sqlite数据库操作进行了封装,demo也比较简单. 3.MBProgressHUD 也是iOS项目常用的一个组件,用于显示过渡效果的,比如网络请求之前显示loading,网络结束隐藏loading.建议封装在BaseViewController中,所有ViewController继承就能使用. 4.MJRefresh 这个是传智播客李明杰老师的作品

iOS项目架构文档

设计的项目架构主要引用MVVM+MVC架构,并以功能模块分级.以下为目录结构. 初级目录: 我们只需要关注SGZH文件夹下的目录,其他为Xcode管理的目录.可以看到此目录为项目初级目录,我们开发过程只需对初级目录内的文件进行操作,其主要划分为3大块: AppDelegate: AppDelegate是程序入口,程序启动和显示逻辑都定义在内部,主要可以让开发人员快速找到代理文件并了解程序从启动到显示过程,也可以快速进行一些初始化测试. Resource: 此目录主要存放一些项目资源文件,如项目切

iOS开发笔记 - 网络篇

计算机网络基础 ??计算机网络是多台独立自主的计算机互联而成的系统的总称,最初建立计算机网络的目的是实现信息传递和资源共享. ??如果说计算机是第二次世界大战的产物,那么计算机网络则是美苏冷战的产物.20世纪60年代初期,美国国防部领导的ARPA提出研究一种崭新的.能够适应现代战争的.生存性很强的通信系统并藉此来应对苏联核攻击的威胁,这个决定促使了分组交换网的诞生,也奠定今天计算机网络的原型,这是计算机网络发展史上第一个里程碑式的事件. ??第二个里程碑式的事件是20世纪80年代初,国际标准化组

iOS项目开发实战——自定义设置导航栏和状态栏背景

在iPhone的状态栏顶部,会有很多的信息,如运营商,信号强弱,网络状况,时间,电量等等.我们使用很多的App,如微信,QQ等等,都会发现导航栏的背景或者说图片都是重新设置过的,这样就能增加用户体验,也能更加节省下方的屏幕空间.那如何来设置导航栏的图片呢? (1)首先建立一个iOS项目,语言选择Swift.并且在Images.xcassets中拖入一张图片,大小要自己设置好,用来作为顶部导航栏的背景. (2)在Main.storyboard中选中ViewController,然后选择Editor

IOS项目-处女作

我最近一直都有在看关于IOS项目的知识,今天也总算是迎来了我的第一个IOS项目.不巧这个项目并不是从头开始开发,而是在基础上维护并添加一些模块. 噗~不管怎么样,还是来分析分析一下源码吧~我这里首先看到的是AppDelegate_iPad.m下的didFinishLaunchingWithOptions方法,这个方法顾名思义应该是应用启动加载完成后所执行的一个方法. - (BOOL)application:(UIApplication *)application didFinishLaunchi