11-12月份iOS团队目标达成情况

团队目标

  • 单元测试编写
  • 路由表方案讨论

单元测试方案与代码编写

首先研究了苹果自带的XCTest,但是不是很符合。后来在网上找了些资料,由于项目是纯swift,因此选择了Quick+Nimble组合框架,其中,这两个框架,在Alamofire、Moya等swift流行框架均采用了它做为单元测试框架。
基于Quick框架,开始写测试用例,选择信e家作为测试项目,但后写登录ViewModel的测试代码,过程中也会遇到些许问题,但是都一一解决了。最后把方案与同事分享,然后一起完成了信e家的单元测试开发。因为只测试了viewModel模块,没有做UI测试,因此覆盖率不是很高:大概50%.
单元测试总结文章


路由表方案

目前,市面上主流的Router方案有三种,分别为:

其中,URL Router代表作为蘑菇街App。它是通过注册URl,然后解析URL中的host path等参数,然后拆解实现跳转。但是,注册了URL之后,会造成不必要的内存常驻,所以,不太建议此方案。
Target-Actionc方案,不需要注册,通过解析字段串,解析出目标与函数的串联,然后彩runtime机制完成调用。经对比,我们采用此方案来实现路由跳转功能。

Target-Action方案

采用CTMediator框架,主要化分为六部分,Controller、View、Model、ViewModel、Category、Target。其中Category与Target分别为路由机制相关的文件。实现如下:

category文件代码:

import CTMediator

//  1. 字符串 是类名 Target_xxx.h 中的 xxx 部分
let kCTMediatorTarget_Face = "Face"
//  2. 字符串是 Target_xxx.h 中 定义的 Action_xxxx 函数名的 xxx 部分
let kCTMediatorActionNavigaTo_pushFaceVc = "pushFaceVc"

extension CTMediator {
    
    func ylx_mediator_pushFaceVcWithParams(params: [String:Any]?) -> UIViewController {
        
        if let registerVc = performTarget(kCTMediatorTarget_Face, action: kCTMediatorActionNavigaTo_pushFaceVc, params: nil, shouldCacheTarget: false) as? UIViewController {
            return registerVc as! XYJBaseVC
        } else {
            // 这里处理异常场景,具体如何处理取决于产品
            return XYJBaseVC.init()
        }
    }
}

Target文件
.h文件
#import <Foundation/Foundation.h>

@interface Target_Face : NSObject
- (XYJFaceVC *)Action_pushFaceVc:(NSDictionary *)params;
@end
.m文件
#import "Target_Face.h"

@implementation Target_Face
- (XYJFaceVC *)Action_pushFaceVc:(NSDictionary *)params
{
    return [[XYJFaceVC alloc] init];
}
@end

然后,在壳工程中调用时,只要通过CTMdiator的分类方法中,拿到控制器,实现调用就行。至于拿到的是什么控制器,可以通过服务器下发,在category中,取到不能的target与action即可实现不同控制器的跳转。参数传递,采用的是NSDictionary方式。如果要传递的是模型,可通过ObjectMapper转字典再传递。

调度方式:
let vc = CTMediator.sharedInstance().ylx_mediator_pushFaceVcWithParams(params: nil)
self.navigationController?.pushViewController(vc, animated: true)

为什么Target要采用oc方法实现?

因为项目是swift项目,如果target用swift方式编写,那么,框架中通过字符串生成Selector会报错。因为swift的方法与oc是有区别。传参后方法名会不一样。

数据顺传逆传

顺传,可直接通过param参数直接传递过去。
逆传:

  • 通过CTMediator分类拿到控制器后,直接对控制闭包或block赋值实现数据逆传。
  • 通过Target中,return控制器前,对闭包或block赋值实现数据逆传。

路由更新方案

  • 路由表下发情况

    • key:value数组的形式,key为类名,value为上述的Target/Action拼接字符串
  • 路由表下发更新缓存方案

    • app每次进入前台,都会获取一下路由配置信息。 如果本地没有版本信息,则把路由配置信息保存到本地,并赋值给单例对象(存放运行内存中,提高效率)。如果有,比较版本号,如果请求的版本号大于本地的,则替换缓存并赋值给单例。如果等于,则直取本地的。
  • 路由表读取跳转方案

    • 因为路由表是key value形式,如果读取key,取出来的值为空,则按默认正常业务逻辑跳转。如果有值,但是取出来的值,按路由方案读取得到的类不存在,还是按默认业务逻辑跳转,否则按路由表取出来的值跳转。

推荐阅读更多精彩内容