Shecare iOS SaaS SDK 开发文档

Demo 地址

https://github.com/iKangtai/ShecareSDKDemo-iOS.git

类定义

核心服务类:ShecareService

1
2
3
4
5
6
7
/**
单例
*/
class func shared() -> ShecareService

/// 设置 SDK 环境,可以不设置。默认是 线上环境 .release
public var environment: YCEnvironment = .release

YCEnvironment 定义如下:

1
2
3
4
5
6
7
///  SDK 使用的服务器环境
public enum YCEnvironment: Int {
/// 正式服务器
case release = 0
/// 测试服务器
case tester = 1
}

温度类:YCTemperatureModel

1
2
3
4
5
6
7
8
/**
构造方法
- parameters:
- temperature: 温度
- measureTime: 温度的测量时间。⚠️不能为空⚠️
- deleted: 是否删除该温度。true 表示删除,false 表示不删除
*/
convenience public init(temperature: String, measureTime date: NSDate, deleted: Bool)

属性列表:

1
2
3
4
5
6
///  是否已删除
public var deleted: Bool = false
/// 测温时间
public var measureTime: NSDate?
/// 温度数据
public var temperature: NSString = ""

经期类:YCPeriodModel

1
2
3
4
5
6
7
/**
构造方法
- parameters:
- date: 日期
- period: 经期信息,1 表示经期开始,2 表示经期结束,0 表示删除经期或无经期信息。经期开始和结束应该成对出现
*/
convenience public init(date: NSDate, period: Int)

属性列表:

1
2
3
4
///  记录日期
public var date: NSDate?
/// 经期信息:1 表示经期开始,2 表示经期结束,0 表示删除经期或无经期信息。经期开始和结束应该成对出现
public var period: Int = 0

用户基础信息类:YCUserInfoModel

1
2
3
4
5
6
7
8
9
10
/**
构造方法
- parameters:
- cycleLength: 周期长度
- mensLength: 经期长度
- birth:出生年月
- height:身高 cm
- weight:体重 公斤
*/
convenience public init(cycleLength: Int, mensLength: Int, birth:String,height:Int,weight:Float)

属性列表:

1
2
3
4
5
6
7
8
9
10
///  周期长度,默认值 28
public var cycleLength: Float = 28.0
/// 经期长度,默认值 5
public var mensLength: Float = 5.0
/// 出生年月,默认值
public var birth: String = "1995年1月"
/// 身高,默认值 160
public var height: Int = 160
/// 体重,默认值45
public var weight: Float=45.2

用户生理信息类:YCPhyModel

1
2
3
4
5
6
7
8
9
10
11
/**
构造方法
- parameters:
- mucus: 白带
- lh: LH值
- hadSex:同房
- bUltra:B超 0 未记录,1确认不排卵,2,确认排卵
- hormoneSix:激素六项
- symptom:症状 0 未记录
*/
convenience public init(mucus: Int, lh: Int, hadSex:Int,bUltra:Int,hormoneSix:String,symtom:Int)

属性列表:

1
2
3
4
5
6
7
8
9
10
11
12
13
///  白带,默认值0
public var mucus: Int = 0
/// LH,默认值 0
public var lh: Int = 0
/// 同房,默认值 0
public var hadSex: Int = 0
/// B超,默认值
public var bUltra: Int = 160
/// 激素六项,默认值null
public var hormoneSix: String="以Json的形式组织相关的激素六项记录"
{"e2":300,"fsh":14,"lh":13,"p":20,"t":0.30,"prl":0.14}
/// 症状,默认0
public var symptom: Int = 0

用户基础信息类:YCHealthInfoModel

1
2
3
4
5
6
/**
构造方法
- parameters:
- health:用户健康信息
*/
convenience public init(health:String)

属性列表:

1
2
3
///  健康信息,默认值 null
public var health: String = "以Json的形式上传"
如:{"pcos":1,"endometriosis":0,"tubalOperation":0,"abortion":0,"ivf":0,"lpd":0}

接口说明

SDK 初始化

AppDelegate 里需要使用 ShecareService 设置第三方 appID、appSecret 和用户 ID,如下:

1
2
3
4
5
6
7
8
9
/// 设置 appID
/// - parameter identifier: 由 SaaS 服务端提供
public func setApplicationIdentifier(_ identifier: String)
/// 设置 appSecret
/// - parameter identifier: 由 SaaS 服务端提供
public func setApplicationSecret(_ identifier: String)
/// 设置 UserID
/// - parameter identifier: App 用户标识符,由 App 提供
public func setUserIdentifier(_ identifier: String)

示例如下:

1
2
3
ShecareService.shared().setApplicationIdentifier(appID)
ShecareService.shared().setApplicationSecret(appSecret)
ShecareService.shared().setUserIdentifier(userID)

数据初始化

SDK 首次加载时,需要把用户的历史数据(包括经期、体温等)一次性传入,用于算法计算。后续有新数据时,只需要传人新数据即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
判断 SDK 是否需要数据初始化
- returns:
返回 true 时,App 需要调用 initData 方法进行数据初始化
*/
func needInitData() -> Bool

/**
数据初始化。
- parameters:
- temperatures: 用户的体温数据,可为空
- periods:用户的经期数据,可为空
- userInfo:用户的基础生理信息,不可为空
- completion:完成回调
*/
public func initData(temperatures: [YCTemperatureModel]?, periods: [YCPeriodModel]?, userInfo: YCUserInfoModel, completion: @escaping (NSError?) -> Void)

示例如下:

1
2
3
4
5
6
7
8
9
if ShecareService.shared().needInitData() {
ShecareService.shared().initData(temperatures: temperatures, periods: periods, userInfo: userInfo, completion: { (result) in
if result {
// Shecare SDK 数据初始化成功
} else {
// Shecare SDK 数据初始化失败
}
})
}

绑定设备

绑定页面 UI 由 SDK 提供,绑定过程中与设备的交互也由 SDK 负责。App 只需要打开 SDK 绑定页即可。
绑定页面类定义:YCBindViewController
属性:

1
2
3
4
/**
代理
*/
weak public var delegate: YCBindViewControllerDelegate?

实例化和设置代理,示例如下:

1
2
3
4
let vc = YCBindViewController()
vc.delegate = self
let navC = UINavigationController(rootViewController: vc)
self.show(navC, sender: nil)

代理方法:

1
2
3
4
5
6
7
8
/**
返回绑定结果的代理方法
- parameters:
- bindViewController: 当前的绑定页面控制器
- macAddress: 绑定的设备 MAC 地址
- error: 错误信息。当为空时,表示没有错误
*/
func bindViewController(_ bindViewController: YCBindViewController, didBind macAddress: String, error: NSError?)

实现代理方法,示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
extension ViewController: YCBindViewControllerDelegate {
func bindViewController(_ bindViewController: YCBindViewController, didBind macAddress: String) {
showAlert(title: "绑定成功", message: macAddress, confirmHandler: { (_) in
bindViewController.dismiss(animated: true, completion: nil)
}, cancelHandler: nil)
}

func bindViewController(_ bindViewController: YCBindViewController, didFailedToBind macAddress: String, errorMessage: String) {
showAlert(title: "绑定失败", message: macAddress + "\n" + errorMessage, confirmHandler: { (_) in
bindViewController.dismiss(animated: true, completion: nil)
}, cancelHandler: nil)
}
}

解绑设备

1
2
3
4
5
/**
- parameters:
- macAddress:需要解绑的设备 MAC 地址
*/
public func unBind(macAddress: String)

示例如下:

1
ShecareService.shared().unBind(macAddress: "C8:FD:19:02:95:7E")

增量上传 温度、经期和用户基础生理信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/**
新增、更新、删除温度。触发时机:用户进行体温修改时
- parameters:
- temperatures: 用户操作的体温数据。SDK 会根据传入的数据自动决定操作类型,详见 YCTemperatureModel 类定义
- completion:完成回调
*/
func upload(temperatures: [YCTemperatureModel]?, completion: @escaping (NSError?) -> Void)

/**
新增、更新、删除经期记录。触发时机:用户修改经期数据时
- parameters:
- periods:用户操作的经期数据。SDK 会根据传入的数据自动决定操作类型,详见 YCPeriodModel 类定义
- completion:完成回调
*/
func upload(periods: [YCPeriodModel]?, completion: @escaping (NSError?) -> Void)

/**
新增、更新用户基础生理信息。触发时机:用户修改基础生理信息时。一个用户只能有一组基础生理信息,其中包括周期长度,经期长度
新版增加了:身高,体重,出生年月。
- parameters:
- userInfo:用户的基础生理信息,不可为空
- completion:完成回调
*/
func upload(userInfo: YCUserInfoModel, completion: @escaping (NSError?) -> Void)



/**
新增、更新用户生理信息。包括:白带,LH试纸,同房,B超,激素六项,症状数据。触发时机:用户编辑或修改生理信息时。
数据项介绍:
白带:int 分别为4个档次,传入数据为1,2,3,4,0是未记录
LH值:使用LH试纸测出的LH值,单位为mlU/ml,正常范围0-100。
同房:0,未记录,1未同房,2,同房
B超:用户是否确认排卵,
激素六项:
--睾酮单位:nmol/L
--雌二醇单位:pmol/L
--孕酮单位:nmol/L
--促黄体生成素单位:mlU/ml
--催乳素:nmol/L
--促卵泡生成激素:mlU/ml
病状数据:具体的症状信息,可参见我们的app设计

- parameters:
- phyInfo:用户的生理信息,不可为空
- completion:完成回调
*/
func upload(phyInfo: YCPhyModel, completion: @escaping (NSError?) -> Void)

/**
新增、更新用户健康数据,既往病史。触发时机:用户编辑或修改健康数据时。
目前健康数据包括:多囊卵巢,子宫内膜异位症,输卵管手术,流产过,试管婴儿,黄体不足。
- parameters:
- healthInfo:用户的生理信息,不可为空
- completion:完成回调
*/
func upload(healthInfo: YCHealthModel, completion: @escaping (NSError?) -> Void)

返回基础体温曲线页面 URL

1
2
3
4
5
6
/**
返回基础体温曲线页面 URL 路径,App 端使用 WebView 加载此路径即可
- returns:
返回基础体温曲线页面 URL
*/
func temperatureCharts() -> String

示例如下:

1
2
3
4
let webVC = YCWebViewController()
webVC.urlString = ShecareService.shared().temperatureCharts()
webVC.title = "体温曲线"
self.navigationController?.pushViewController(webVC, animated: true)

返回 智能分析 结果。App 端根据需要对分析结果进行处理。

1
2
3
4
5
6
7
8
/**
智能分析接口
- parameters:
- completion:完成回调
- error: 错误信息
- result: 智能分析结果。详见 “智能分析结果说明”
*/
func analysis(_ completion: @escaping (_ error: NSError?, _ result: NSDictionary?)

示例如下:

1
2
3
4
5
6
7
ShecareService.shared().analysis({ (error, result) in
if let error = error {
print(error)
} else {
print(result ?? "analysis result is nil.")
}
})

智能分析结果说明:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
{
"code": 0,
"message": null,
"data": {
"listAll": [
{
"list": [
{
"state": "normal",
"msg": "测温时间不规律,大部分在10点和11之间。",
"guanjian": null,
"url": null
},
{
"state": "bigwave",
"msg": "到目前体温测量一切正常,加油哦!",
"guanjian": null,
"url": null
},
{
"state": "pregnant",
"msg": "根据基础体温,确定排卵日为2018年3月1日。",
"guanjian": null,
"url": null
},
{
"state": "noyellow",
"msg": "黄体升温幅度较低,速度较慢,疑似黄体功能不足。",
"guanjian": null,
"url": null
}
],
"nowdate": "当前周期:2018年2月18日--今天"
},
{
"list": [
{
"state": "normal",
"msg": "测温时间不规律,大部分在10点和11之间。",
"guanjian": null,
"url": null
},
{
"state": "bigwave",
"msg": "到目前体温测量一切正常,加油哦!",
"guanjian": null,
"url": null
},
{
"state": "pregnant",
"msg": "根据基础体温,确定排卵日为2018年1月29日。",
"guanjian": null,
"url": null
},
{
"state": "noyellow",
"msg": "黄体升温幅度较低,速度较慢,疑似黄体功能不足。",
"guanjian": null,
"url": null
},
{
"state": "noyellow",
"msg": "本周期黄体期长度为18。长度过长,正常黄体其长度为10-16天。",
"guanjian": null,
"url": null
}
],
"nowdate": "历史周期:2018年1月1日--2018年2月17日"
},
{
"list": [
{
"state": "normal",
"msg": "本周期无有效的基础体温。",
"guanjian": null,
"url": null
}
],
"nowdate": "历史周期:2017年11月17日--2017年12月31日"
},
{
"list": [
{
"state": "normal",
"msg": "本周期无有效的基础体温。",
"guanjian": null,
"url": null
}
],
"nowdate": "历史周期:2017年10月1日--2017年11月16日"
},
{
"list": [
{
"state": "normal",
"msg": "周期长度最长48天,最短45天,平均周期长度47,周期长度稳定!",
"guanjian": null,
"url": null
},
{
"state": "normal",
"msg": "经期长度最长6天,最短3天,平均经期长度4,经期长度稳定。",
"guanjian": null,
"url": null
}
],
"nowdate": "整体周期分析:"
}
]
}
}

备注:当 code 非0时,说明内部分析出错,此时会在 message 中返回错误信息; listall 中的数据主要用到了:nowdate 和 message,nowdate 表示该段数据所处的周期, message 表示对这段周期分析的结果。

蓝牙

类定义:BLEThermometer

1
2
3
4
/**
单例
*/
class public func shared() -> BLEThermometer
属性列表:
1
2
3
4
5
6
7
8
///  当前连接的外部设备
public var activePeripheral: CBPeripheral?
/// 设备的版本号
public var firmwareVersion = ""
/// 设备的 MAC 地址
public var macAddress = ""
/// 代理。代理方法见 “蓝牙代理方法列表”
weak public var delegate: BLEThermometerDelegate?
YCBLEConnectType,蓝牙连接类型,定义如下:
1
2
3
4
5
6
7
///  蓝牙连接类型
public enum YCBLEConnectType: Int {
/// 绑定页的连接,可以连接所有设备
case binding = 0
/// 非绑定页的连接,只能连接已绑定的设备
case notBinding = 1
}
YCBLEState,蓝牙状态,定义如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
///  蓝牙状态
public enum YCBLEState: Int {
/// 正常打开
case valid = 0
/// 未知状态
case unknown = 1
/// 设备不支持蓝牙 4.0
case unsupported = 2
/// 未授权 App 使用蓝牙
case unauthorized = 3
/// 蓝牙已关闭
case poweredOff = 4
/// 蓝牙正在重启
case resetting = 5
}
BLEFirmwareImageType,设备镜像版本,用于 OAD 空中升级,定义如下:
1
2
3
4
5
6
7
8
9
///  用户硬件镜像版本
public enum BLEFirmwareImageType: Int {
/// 未知版本
case unknown
/// A 版本
case typeA
/// B 版本
case typeB
}
BLENotifyType,设备可接收的指令,定义如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
///  指令类型
public enum BLENotifyType: Int {
/// 把温度计的温度单位设置为摄氏度
case setTemperatureUnitC = 0
/// 把温度计的温度单位设置为华氏度
case setTemperatureUnitF = 1
/// 让温度计开始传输温度
case transmitTemperature = 2
/// 返回 “接收的温度数量” 给温度计(温度计收到此指令后,会校验发送的数量和接收的数量是否一致,如果一致,即认为温度发送成功,下次不再重复发送)
case temperatureCount = 3
/// 获取温度计电量
case thermometerPower = 4
}

方法列表

扫描并连接设备
1
2
3
4
5
6
7
8
9
/**
扫描并连接设备
- parameters:
- type: 需要连接的类型。详见 YCBLEConnectType 的定义
- macList: “已绑定” 的设备 MAC 地址列表,有多个设备时中间用 “,” 分隔即可。对于 type 为 notBinding 的连接有效,可以限制 App 只能连接地址列表里的设备
- returns:
返回 “是否成功开始扫描”
*/
public func connectThermometer(type: YCBLEConnectType, macList: String) -> Bool
停止扫描
1
2
3
4
/**
停止扫描
*/
public func stopScan()
返回蓝牙状态
1
2
3
4
5
6
/**
返回当前的蓝牙状态
- returns:
蓝牙状态,详见 YCBLEState 的定义
*/
public func bleState() -> YCBLEState
断开当前连接的设备
1
2
3
4
/**
断开当前连接的设备
*/
public func disconnectActiveThermometer()
同步设备时间
1
2
3
4
/**
同步设备时间
*/
public func asynchroizationTimeFromLocal(date: Date)
发送特定指令
1
2
3
4
5
6
7
/**
发送特定指令给设备
- parameters:
- type: 指令类型。详见 BLENotifyType 的定义
- value: 仅用于 temperatureCount 指令
*/
public func setNotifyValue(type: BLENotifyType, value: UInt8)

蓝牙代理方法列表

1
2
///  设备蓝牙状态改变的回调
func bleThermometerDidUpdateState(_ bleThermometer: BLEThermometer)
1
2
///  获取设备镜像版本的回调,详见 BLEFirmwareImageType 定义
optional func bleThermometer(_ bleThermometer: BLEThermometer, didReadFirmwareImageType type: BLEFirmwareImageType)
1
2
///  设备连接成功的回调
optional func bleThermometer(_ bleThermometer: BLEThermometer, didConnect peripheral: CBPeripheral)
1
2
3
4
///  设备连接失败的回调
optional func bleThermometer(_ bleThermometer: BLEThermometer,
didFailToConnect peripheral: CBPeripheral,
error: Error?)
1
2
3
4
///  设备断开连接的回调
optional func bleThermometer(_ bleThermometer: BLEThermometer,
didDisconnect peripheral: CBPeripheral,
error: Error?)
1
2
3
///  获取温度的回调
optional func bleThermometer(_ bleThermometer: BLEThermometer,
didUpload temperatures: [YCTemperatureModel])
1
2
///  设置设备温度单位的回调
optional func bleThermometer(_ bleThermometer: BLEThermometer, didSetTemperatureUnit success: Bool)
1
2
///  获取设备版本号的回调
optional func bleThermometer(_ bleThermometer: BLEThermometer, didGetFirmwareVersion firmwareVersion: String)
1
2
///  同步设备时间的回调
optional func bleThermometer(_ bleThermometer: BLEThermometer, didSetThermometerTime success: Bool)
1
2
///  获取设备电量的回调
optional func bleThermometer(_ bleThermometer: BLEThermometer, didGetThermometerPower value: Double)