开源项目Running Life 源码分析(一)

468 查看

项目简介

基于HeathKit和高德地图开发健康跑步App,实现实时绘画运动轨迹、健康数据管理功能。
做这个项目出于两个原因:
1、喜欢跑步(也为了减减肥);
2、喜欢运用自己的知识实际,里面有我自己写的一些开源组件( 技术有限,设计得不好的地方,大家多多指导);

运行效果如下:

图片标题

项目目录

111fd8fe6f59cef14dde334b328e2f7667
title

Config目录:接口配置文件、宏定义和头文件配置文件;
AppINit目录:关于App的启动设置,如第三方SDK初始化、界面初始化、HeathKit初始化配置;
Module目录:业务模块,由以下这几个模块组成:公共模块、跑步模块、记录模块、个人模块、设置模块、登陆注册模块;
Resource目录:图片资源和字体资源;
RunKit目录:一些类的拓展、工具类、网络层方案、持久化存储层方案;
Vendor目录:一些不支持Cocoapod第三方库;
Pod:支持Cocoapod第三方库;

业务层架构

124197db2f9bc8d42034917e1a760f479a

MVVM架构(使用Facebook的KVOController实现view和viewModel的绑定,项目往ReactCocoa迁移中)

viewModel如何设计?

viewModel负责从原始数据源获取原始数据,运用对应的数据处理逻辑,转化为view层显示的数据。他不引入UIKit相关类,所以他与UI无关,也方便我们进行单元测试。实际上,它就是一层function core,理想上对于相同的输入会导出相同的结果。所以viewmodel得设计主要包含三部分内容:输入、输出、命令,简化成函数表达就是y = f(x),f函数指的是命令,x是输入,y就是输出,这里要注意输出对外界来说只是一个只读属性。示例如下:

viewModel与view如何绑定?

绑定的目的就是为了解决view与viewModel通信的问题。MVVM天然最好的绑定机制就是Facebook的ReactCocoa,它是函数式响应式编程思想的一个体现,它的核心就是响应数据的变化、统一异步编程模型,绑定的具体做法就是view层通过订阅viewModel上面的信号,先模拟处理一遍,这里模拟的意思是先从脑海里过一遍逻辑,实际不响应,当有信号发过来的时候才实际触发。
但是他需要一定的学习成本,学习成本较大,本人也在不断学习当中,所有我们换种方式来实现这种响应机制。想一下,cocoa中是不是有提供这种监听-响应的机制,没错,就是KVO,但是原生KVO写起来会恶心死人,所有我们可以借助Facebook提供一个KVO框架(kvoController)来实现优雅的绑定。(Facebook真是为了iOS的开发做出很多贡献,开源了那么多好用的工具)。
绑定方式就是view层 kvo viewModel层的readonly属性,一旦属性变化就触发响应的处理逻辑。示例如下:

功能实现

项目搭好条条框框,现在来分析具体的功能实现。本项目有两个功能,一个是跑步,另外一个就是记录,每个大功能点下又分几个小功能点,功能的示意图如下:

13ba9d97fde99ee5b4539fea48dde26af8

跑步

这里主要分析跑步过程的具体逻辑,界面如下:

14dd0fedfe024ccec3fca75b7f517a618b

源码在这个文件:”NewRunViewModel.m”

跑步数据源

跑步数据来源定位,这里定位SDK选择高德SDK,虽然原生也是高德地图,但经过测试发现原生的定位很不准,我也不知道具体原因是什么。
定义一个定位管理器,设置好相应的配置参数,因为为了跑步数据的精确度,所以将定位的准确度设置为最好,调用 [self.locationManager startUpdatingLocation]开启持续定位,具体实现如下: