前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >iOS 接入 Strava 分享模块(上篇:FitSDK)

iOS 接入 Strava 分享模块(上篇:FitSDK)

作者头像
零式的天空
发布2022-03-25 11:31:40
9280
发布2022-03-25 11:31:40
举报
文章被收录于专栏:零域Blog

fit 是一种文件协议,体积小巧,多用于可穿戴设备记录、传输运动与健康数据。官方提供了 C、C++、Java 语言的 SDK 和非常详细的使用文档。因此在 iOS 端接入 fit 就需要在 C 或 C++ 的 SDK 基础上进行一点面向对象的封装。

认识 Fit

我使用的 C 语言的 SDK,官方有示例 demo,在 fit_mgr 文件中提供了一些示例,这些代码未必全部都要用到。创建一个最简单的 .fit 文件的流程是:

写 fileid

代码语言:javascript
复制
void fit_transaction_file(FIT_FILE type, FIT_MANUFACTURER manufacturer, FIT_UINT16 product, FIT_UINT32Z serial_number){
    // Write file id message.
    FIT_UINT8 local_mesg_number = 0;
    FIT_FILE_ID_MESG file_id;
    Fit_InitMesg(fit_mesg_defs[FIT_MESG_FILE_ID], &file_id);

    // @xaoxuu: type FIT_FILE_ACTIVITY = 4 活动数据
    file_id.type = type;
    // @xaoxuu: 厂商
    file_id.manufacturer = manufacturer;
    // @xaoxuu: 产品
    //        file_id.product_name
    file_id.product = product;
    // @xaoxuu: 序列号
    file_id.serial_number = serial_number;
    // @xaoxuu: 生产日期
    //        time_t now;
    //        time(&now);
    //        file_id.time_created = now;

    WriteMessageDefinition(local_mesg_number, fit_mesg_defs[FIT_MESG_FILE_ID], FIT_FILE_ID_MESG_DEF_SIZE, static_fp);
    WriteMessage(local_mesg_number, &file_id, FIT_FILE_ID_MESG_SIZE, static_fp);
}

void fit_transaction_field_desc() {
    // Write a Field Description
    FIT_UINT8 local_mesg_number = 1;
    FIT_FIELD_DESCRIPTION_MESG field_description_mesg;

    Fit_InitMesg(fit_mesg_defs[FIT_MESG_FIELD_DESCRIPTION], &field_description_mesg);
    field_description_mesg.developer_data_index = 0;
    field_description_mesg.field_definition_number = 0;
    field_description_mesg.fit_base_type_id = FIT_BASE_TYPE_UINT16;
    WriteMessageDefinition(local_mesg_number, fit_mesg_defs[FIT_MESG_FIELD_DESCRIPTION], FIT_FIELD_DESCRIPTION_MESG_DEF_SIZE, static_fp);
    WriteMessage(local_mesg_number, &field_description_mesg, FIT_FIELD_DESCRIPTION_MESG_SIZE, static_fp);
}

写 record

代码语言:javascript
复制
// 写入Record Defenition
void fit_transaction_record_def(){
    FIT_UINT8 local_mesg_number = 2;
    WriteMessageDefinition(local_mesg_number, fit_mesg_defs[FIT_MESG_RECORD], FIT_RECORD_MESG_DEF_SIZE, static_fp);
}
// 循环写入record数据
void fit_transaction_record_msg(unsigned int timestamp, int position_lat, int position_long, unsigned int distance, unsigned short altitude, unsigned short speed, unsigned char heart_rate){
    //Record message
    FIT_UINT8 local_mesg_number = 2;
    FIT_RECORD_MESG record;

    Fit_InitMesg(fit_mesg_defs[FIT_MESG_RECORD], &record);
    record.timestamp = timestamp;
    record.position_lat = position_lat;
    record.position_long = position_long;
    record.distance = distance;
    record.altitude = altitude;
    record.speed = speed;
    record.heart_rate = heart_rate;
    WriteMessage(local_mesg_number,&record,FIT_RECORD_MESG_SIZE,static_fp);
}

开始封装

设计模型

FitActivity.h

代码语言:javascript
复制
//
//  FitAcitvity.h
//  FitSDK
//
//  Created by xaoxuu on 04/07/2017.
//  Copyright © 2017 xaoxuu. All rights reserved.
//

#import <Foundation/Foundation.h>

@class FitActivityRecord;
typedef NS_ENUM(NSUInteger, FitActivityType) {
    FitActivityTypeWalk = 11, // 枚举值等于FIT_SPORT值
    FitActivityTypeRun = 1,
    FitActivityTypeRide = 2,
    FitActivityTypeSwim = 5,
    FitActivityTypeHike = 17,
};

@interface FitActivity : NSObject

// @xaoxuu: fit 文件路径
@property (copy, readonly, nonatomic) NSString *path;

// @xaoxuu: 活动名
@property (copy, nonatomic) NSString *name;

// @xaoxuu: 活动类型
@property (assign, nonatomic) FitActivityType type;

// @xaoxuu: 活动类型
@property (copy, readonly, nonatomic) NSString *typeString;

// @xaoxuu: records
@property (strong, nonatomic) NSMutableArray<FitActivityRecord *> *records;

/**
 添加一条record

 @param record record
 */
- (void)addRecord:(void (^)(FitActivityRecord *aRecord))record;

@end

@interface FitActivityRecord : NSObject

// @xaoxuu: timestamp
@property (assign, nonatomic) unsigned int timestamp;

// @xaoxuu: position_lat
@property (assign, nonatomic) int position_lat;

// @xaoxuu: position_long
@property (assign, nonatomic) int position_long;

// @xaoxuu: distance
@property (assign, nonatomic) unsigned int distance;

// @xaoxuu: altitude
@property (assign, nonatomic) unsigned short altitude;

// @xaoxuu: speed
@property (assign, nonatomic) unsigned short speed;

// @xaoxuu: heart_rate
@property (assign, nonatomic) unsigned char heart_rate;

@end

FitActivity.m

代码语言:javascript
复制
//
//  FitAcitvity.m
//  FitSDK
//
//  Created by xaoxuu on 04/07/2017.
//  Copyright © 2017 xaoxuu. All rights reserved.
//

#import "FitAcitvity.h"

@implementation FitActivity

- (instancetype)init {
    if (self = [super init]) {
        _records = [NSMutableArray array];
        self.type = FitActivityTypeWalk;
    }
    return self;
}


- (void)setType:(FitActivityType)type{
    _type = type;

    switch (type) {
        case FitActivityTypeWalk:
            _typeString = @"walk";
            break;
        case FitActivityTypeRun:
            _typeString = @"run";
            break;
        case FitActivityTypeRide:
            _typeString = @"ride";
            break;
        case FitActivityTypeSwim:
            _typeString = @"swim";
            break;
        case FitActivityTypeHike:
            _typeString = @"hike";
            break;

    }
}


- (void)setName:(NSString *)name{
    _name = name;
    _path = [self pathWithName:name];
}

- (void)addRecord:(void (^)(FitActivityRecord *aRecord))record{
    if (record) {
        FitActivityRecord *rec = [FitActivityRecord new];
        record(rec);
        [self.records addObject:rec];
    }
}

- (NSString *)pathWithName:(NSString *)name{
    NSString *path = [[NSTemporaryDirectory() stringByAppendingPathComponent:@"com.xaoxuu.fitsdk"] stringByAppendingPathComponent:name];
    path = [path stringByAppendingPathExtension:@"fit"];
    // create dir if not exist
    NSFileManager *fm = [NSFileManager defaultManager];
    NSString *dir = path.stringByDeletingLastPathComponent;
    BOOL result = [fm createDirectoryAtPath:dir withIntermediateDirectories:YES attributes:nil error:nil];
    if (!result) {
        NSLog(@"can not create the directory at path %@",dir);
    }
    return path;
}

@end

@implementation FitActivityRecord

- (instancetype)init{
    if (self = [super init]) {
        _timestamp = 702940946;
        _position_lat = 0;
        _position_long = 0;
        _distance = 0;
        _altitude = 0;
        _speed = 0;
        _heart_rate = 0;
    }
    return self;
}

@end

封装接口

FitSDK.h

代码语言:javascript
复制
//
//  FitSDK.h
//  FitSDK
//
//  Created by xaoxuu on 04/07/2017.
//  Copyright © 2017 xaoxuu. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "FitAcitvity.h"

@interface FitSDK : NSObject

/**
 创建一个活动数据fit文件

 @param activity 活动数据
 @return 活动数据模型
 */
+ (FitActivity *)createActivity:(void (^)(FitActivity *activity))activity;

@end

FitSDK.m

代码语言:javascript
复制
//
//  FitSDK.m
//  FitSDK
//
//  Created by xaoxuu on 04/07/2017.
//  Copyright © 2017 xaoxuu. All rights reserved.
//

#import "FitSDK.h"
#import "fit_mgr.h"

@implementation FitSDK

+ (FitActivity *)createActivity:(void (^)(FitActivity *activity))activity{
    FitActivity *act = [FitActivity new];
    if (activity) {
        activity(act);
    }
    [self createActivityWithModel:act];
    return act;
}


+ (void)createActivityWithModel:(FitActivity *)activity{
    // @xaoxuu: fit file
    const char *fp = [activity.path cStringUsingEncoding:NSUTF8StringEncoding];
    fit_transaction(fp, activity.type, ^{
        [activity.records enumerateObjectsUsingBlock:^(FitActivityRecord * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            fit_transaction_record_msg(obj.timestamp, obj.position_lat, obj.position_long, obj.distance, obj.altitude, obj.speed, obj.heart_rate);
        }];
    });
}

@end

使用

代码语言:javascript
复制
FitActivity *activity = [FitSDK createActivity:^(FitActivity *activity) {
    activity.name = @"test";
    activity.type = FitActivityTypeRun;
    for (int i = 0; i<100; i++) {
        [activity addRecord:^(FitActivityRecord *aRecord) {
            aRecord.timestamp = [[NSDate date] timeIntervalSince1970] - 631065600;
            aRecord.position_lat = 495280430+i*1000;
            aRecord.position_long = -872696681-i*1500;
            aRecord.distance = 2+i/100;
            aRecord.altitude = 287.2+i;
            aRecord.speed = 0.29+i/50;
            aRecord.heart_rate = 68+i/4;
        }];
    }
}];
// activity.path就是生成的fit文件路径
NSLog(@"%@", activity.path);
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017-06-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 认识 Fit
    • 写 fileid
      • 写 record
      • 开始封装
        • 设计模型
          • 封装接口
          • 使用
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档