(0026)iOS 开发之模块化封装初步实践
由于工程不大不小,功能也不断增加!之前没有很好的架构,造成工程现在很混乱。每次更新都会带来一些麻烦!一直想把工程模块化和插件化!经验有限!现在开始一些实践!这里对工程一个消息中心的模块,进行模块化开发,效果很好!
需求:消息类型(登录可见和未登录可见) 消息属性:标题型和图文型
1.消息类型和详情由服务器从数据库中筛选
2.进入分类分类角标清零 且需要回执服务器
3.消息标题列表(过期和已读)都需要回执服务器
4.客户端有消息提醒和角标变化
5.点击进入 app 是否路由到消息的页面
消息推送和查看流程:
第一步:确保服务器推送的消息都是服务器进行过条件筛选的(很关键)
第三步:确保收到了消息之后,统计消息数量,显示到通知栏
第四步:当用户点击通知栏,查询数据库,回执对应的消息
第五步:回执成功,那么我就删除,回执失败我继续发送请求
实现功能:消息中心(参看掌上生活的消息中心和长江汇的消息中心)
设计介绍: 一般消息中心:由消息类别列表(PageA)和某一类别列表(PageB)、以及消息详情页(PageC)。
核心在于PageB,在PageB使用同一接口根据类别不同返回某一类别列表(使用一个包含所有类别属性的model)。
这样在PageB处理分页或者刷新,只要处理一次。
设计思路:消息中心设计成一个模块。一种显示信息。进入使用,查看消息,返回。
一种商品推荐。进入使用,查看消息,过渡到其他模块。
思考:由于PageB的内容都是一条一条的用tableView实现即可,只是cell的样式不同而已。 所以主要对PageB 的cell 动态化加载(runtime实现)。而不去创建多个viewController 分别加载每个不同的类别列表。可以减少viewController 的数量,简化跳转。
实现:
第一步:建一PageA(MessageCenterViewController)跳转识传递类型和cell 的类名。
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row <=self.modelsArray.count)
{
MessageModel *model =self.modelsArray[indexPath.row];
NSString *typeCode = model.noticeTypeCode;
CommonRemindViewController *commonVC = [[CommonRemindViewControlleralloc]init];
commonVC.noticeTypeCode = typeCode;
if ([typeCodeisEqualToString:@"0001"]) {
commonVC.title =@"官方公告";
commonVC.cellString =@"OfficalNoticeTableViewCell";
} elseif ([typeCodeisEqualToString:@"0002"]) {
commonVC.title =@"商品推荐";
commonVC.cellString =@"GoodsRecommendTableViewCell";
} elseif ([typeCodeisEqualToString:@"0003"]) {
commonVC.title =@"消费提醒";
commonVC.cellString =@"ConsumeRemindTableViewCell";
}
[self.navigationControllerpushViewController:commonVCanimated:YES];
}
}
第二步:建一个带tableView 的控制器 PageB(通用CommonRemindViewController)加载不通类型的cell。
#import <objc/runtime.h>
#import <objc/message.h>
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellID =@"cellID";
Class c = NSClassFromString(self.cellString);
id messageCell = [tableViewdequeueReusableCellWithIdentifier:cellID];
if (!messageCell) {
messageCell = [[c alloc]initWithStyle:UITableViewCellStyleDefaultreuseIdentifier:cellID];
}
MessageModel *model =nil;
if (indexPath.row <self.modelsArray.count) {
model = self.modelsArray[indexPath.row];
}
[messageCell configCellWithModel:model]; // 把model 传到不同的cell里显示
_cellHeight = [messageCellgetAutoCellHeight];// 然后获得当前cell高的的数值存储
return messageCell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return_cellHeight;// 高度动态化
}
注意:
cell 的布局使用Masonry。
cell 里的方法
// 数据展示以及约束处理
- (void)configCellWithModel:(MessageModel *)model
{
self.timeLab.text = model.releaseTime;
self.titleLab.text = model.title;
self.goodNumLab.text = model.goodNum;
self.priceLab.text = model.goodsPrice;
[self.bgImgView mas_updateConstraints:^(MASConstraintMaker *make) {
make.bottom.mas_equalTo(_logoImgView.mas_bottom).offset(20);
}];
[self updateConstraints];
[self updateConstraintsIfNeeded];
}
// 获取cell 的高度。
- (float)getAutoCellHeight
{
[self layoutIfNeeded];
/**
* self.最底部的控件.frame.origin.y 为自适应cell中的最后一个控件的Y坐标
* self.最底部的控件.frame.size.height 为自适应cell中的最后一个控件的高
* marginHeight = 15 为自适应cell中的最后一个控件的距离cell底部的间隙
*/
return self.bgImgView.frame.origin.y + self.bgImgView.frame.size.height+10;
}
第三步:跳转到PageC。(一种不用跳转,一种跳到webview中,还有一些跳到特定的页面)。就OK了。
如果想有想把某一类型拆出来,也很简单。这样就完成了消息中心的功能。(实现了模块的思想:高內聚,低耦合)。
一段很独立的模块。看着很干净,思路也很清晰。
以至于,我把支付模块也采用这样的设计。以后渐渐实现模块开发和插件开发的思想!
(0026)iOS 开发之模块化封装初步实践相关推荐
- iOS开发-网络-合理封装请求接口
概述 如今大多App都会与网络打交道,作为开发者,合理的对网络后台请求接口进行封装十分重要.本文要介绍的就是一种常见的采用回调函数(方法)的网络接口封装,也算的是一种构架吧. 这个构架主要的idea是 ...
- iOS开发 - 用AVPlayer封装一个播放器
因为GIF上传的时候一直失败,所以大家到Github查看效果图 https://github.com/codeliu6572/LHHVideoPlayer 由于亮度和音量只能在真机上显现效果,所以GI ...
- 文顶顶iOS开发博客链接整理及部分项目源代码下载
网上的iOS开发的教程很多,但是像cnblogs博主文顶顶的博客这样内容图文并茂,代码齐全,示例经典,原理也有阐述,覆盖面宽广,自成系统的系列教程却很难找.如果你是初学者,在学习了斯坦福iOS7公开课 ...
- iOS开发--TDD的iOS开发初步以及Kiwi使用入门
测试驱动开发(Test Driven Development,以下简称TDD)是保证代码质量的不二法则,也是先进程序开发的共识.Apple一直致力于在iOS开发中集成更加方便和可用的测试,在Xcode ...
- IOS开发基础之音频工具类封装AVAudioPlayer
IOS开发基础之音频工具类封装AVAudioPlayer 源码在我的主页下面 ,项目名称是AVAudioPlayer 关键性代码 工具类的封装 // // LJAudioTool.h // AVAud ...
- IOS开发基础之网易新闻环境搭建异步请求json,AFN网络封装第1天
IOS开发基础之网易新闻环境搭建异步请求json,AFN网络封装第1天 视频资料是2015年的,但是AFN是导入框架的关键文件,我尝试使用cocoapods安装最新的AFN,虽然成功了,但是版本太高, ...
- IOS开发沙盒路径的封装技术
IOS开发沙盒路径的封装技术 实现对NSString 类的分类 导入头文件,即可获取沙盒路径 //沙盒 使用分类的思想 File 填 Sandbox File Type 填 Calegory 分类 C ...
- ios开发之使用多文件上传的简单封装最原始的
ios开发之使用多文件上传的简单封装最原始的 // // ViewController.m // 18-上传多个文件 // // Created by 鲁军 on 2021/2/13. //#impo ...
- ios开发 mvp实践_实践中开发人员的工作流程-我们如何在30天内建立MVP
ios开发 mvp实践 by Léna Faure 莱娜·福雷(LénaFaure) 实践中开发人员的工作流程-我们如何在30天内建立MVP (The developer's workflow i ...
最新文章
- OpenCV使用问题汇总
- 当写了五百行代码忘记保存时…… | 每日趣闻
- Java的内存泄漏和垃圾回收机制
- BS的data-toggle/data-target
- git@github.com - Permission denied publickey错误
- SAP S/4HANA Layer Repository(LREP)的读取逻辑调试
- SAP云平台里给应用创建自定义环境变量
- spark集群详细搭建过程及遇到的问题解决(四)
- python中用rdflib生成rdf,用sparql查询
- 【敏捷开发每日一贴】代码走查
- 计算机三级信息安全技术试题与答案,计算机三级《信息安全技术》练习题与答案...
- window certutil查看文件md5,校验文件MD5
- 易辅客栈 从零学辅助_如何从零启动辅助项目
- TensorFlow 核心流程剖析 -- 2 神经网络模型的构建、分割和优化
- 音频文件按照正常语句,断句拆分的处理方法
- 编译原理实验二:赋值语句的语法分析程序设计
- Three.js - 图形界面工具(lil-gui)(四)
- 提供云媒体服务器图片,云开发 把媒体文件上传到微信服务器 已知报错
- 隐私信息检索(PIR)
- 教师计算机提升返岗总结,语文老师返岗研修心得体会