StravaZpot Swift
一个流畅的 API,用于与用 Swift 编写的 iOS 应用于 Strava 集成。
使用方法
本文档解释了如何在您的 Swift iOS 应用中使用 StravaZpot。对于其他问题,您可以查看 Strava 官方文档此处。
身份验证
身份验证视图控制器
Strava 使用 OAuth 2.0 进行用户身份验证,然后请求允许您的应用程序访问权限。要为您的应用程序从 Strava 获取客户端 ID 和密钥,请按照此链接进行操作。
一旦您获取到应用凭据,就可以创建一个 AuthenticationViewController
并使用以下代码设置必要的字段
let authenticationViewController = AuthenticationViewController()
authenticationViewController.url = url // URL
authenticationViewController.redirectURL = redirectURL // String
authenticationViewController.delegate = delegate // AuthenticationDelegate
authenticationViewController.title = "Login to Strava"
您需要发送的 url
包含一些特殊参数。StravaZpot 提供了一种简单的方式来构建它
let url = StravaLogin(clientID: <YOUR_CLIENT_ID>,
redirectURI: <YOUR_REDIRECT_URL>,
approvalPrompt: ApprovalPrompt.force,
accessScope: AccessScope.Write).makeURL()
在使用此调用时,需要注意几个问题
<YOUR_CLIENT_ID>
必须替换为 Strava 在您注册应用程序时提供的 Client ID。<YOUR_REDIRECT_URL>
必须位于您在 Strava 中注册应用时指定的域中。- 参考
ApprovalPrompt
枚举,以获取该参数的更多选项。 - 参考
AccessScope
枚举,以获取该参数的更多选项。
您传递给 AuthenticationViewController
的 delegate
必须实现协议 AuthenticationDelegate
,它由一个方法组成
func authenticationViewController(_ authenticationViewController: AuthenticationViewController, didFinishWithCode code: String) {
// Use code to obtain token
}
获取令牌
每个 Strava API 调用都需要一个令牌来证明用户已认证并且应用有权限访问 API。在您从用户登录获取代码后,您需要将其与 Strava 进行交换以获取令牌。您可以使用以下代码完成此操作
let client = HTTPClientBuilder.authenticationClient(debug: true)
AuthenticationAPI(client: client)
.getToken(forApp: AppCredentials(clientID: <YOUR_CLIENT_ID>,
clientSecret: <YOUR_CLIENT_SECRET>),
withCode: self.code)
.execute { loginResult : StravaResult<LoginResult> in
// Check if result is successful or not
}
请注意,在此调用中,您必须提供 Strava 在您注册应用程序时提供的 Client ID 和 Secret,以及登录过程中获得的代码。此外,执行前面的代码涉及网络请求;**您需要在一个合适的线程(不在 UI 线程上)调用此代码**。否则,您将获得一个异常。
如果前面的请求成功,您将获得一个 LoginResult
,其中包含一个 Token
,您可以在后续的 API 调用中使用它,以及一个代表已认证用户的 Athlete
实例。
来自 Strava API 调用的所有响应都包含在 StravaResult<T>
中,这是一个枚举,表示结果是否成功。成功情况包含 Strava 返回的该对象的实例。失败情况包含解释失败原因的 Error
。
运动员 API
HTTPClient
在介绍AthleteAPI之前,我们需要谈谈HTTPClient
。HTTPClient
是所有StravaZpot中的API都需要的一个协议,用于配置它与Strava交互的方式。一旦你获得令牌,就可以立即创建一个HTTPClient
实例,并在你的应用程序生命周期中重复使用。要创建这样的实例:
let client = HTTPClientBuilder.client(withToken: <YOUR_TOKEN>, debug: true)
你必须提供在认证过程中获得的令牌。debug
参数将打印有关API调用的有用信息。
一旦你有了HTTPClient
,你就可以继续使用所有API了。
创建Athlete API对象
let athleteAPI = AthleteAPI(client: client)
检索当前运动员
athleteAPI.retrieveCurrentAthlete()
.execute { result : StravaResult<Athlete> in ... }
检索其他运动员
athleteAPI.retrieveAthlete(withID: 227615)
.execute { result : StravaResult<Athlete> in ... }
更新运动员信息
ahtleteAPI.updateCurrentAthlete(withCity: "Irvine",
withState: "California",
withCountry: "USA",
withSex: .male,
withWeight: 85.6)
.execute { result : StravaResult<Athlete> in ... }
检索运动员区域
athleteAPI.getAthleteZones()
.execute { result : StravaResult<Zones> in ... }
检索运动员总数据和统计数据
atheleteAPI.getTotalsAndStats(withID: 227615)
.execute { result : StravaResult<Stats> in ... }
列出运动员 K/QOMs/CRs 列表
athleteAPI.listAthleteKOMS(withID: 227615)
.of(page: 2, itemsPerPage: 10)
.execute { result : StravaResult<EquatableArray<SegmentEffort>> in ... }
好友 API
创建好友 API 对象
let friendAPI = FriendAPI(client: client)
列出用户的朋友
friendAPI.listMyFriends()
.of(page: 2, itemsPerPage: 10)
.execute{ result : StravaResult<EquatableArray<Athlete>> in ... }
列出其他运动员的朋友
friendAPI.listAthleteFriends(withID: 227615)
.of(page: 2, itemsPerPage: 10)
.execute{ result : StravaResult<EquatableArray<Athlete>> in ... }
列出用户关注的用户
friendAPI.listMyFollowers()
.of(page: 2, itemsPerPage: 10)
.execute{ result : StravaResult<EquatableArray<Athlete>> in ... }
列出其他运动员关注的用户
friendAPI.listAthleteFollowers(withID: 227615)
.of(page: 2, itemsPerPage: 10)
.execute{ result : StravaResult<EquatableArray<Athlete>> in ... }
列出两个用户共同关注的运动员
friendAPI.listBothFollowing(withID: 227615)
.of(page: 2, itemsPerPage: 10)
.execute{ result : StravaResult<EquatableArray<Athlete>> in ... }
活动API
创建活动API对象
let activityAPI = ActivityAPI(client: client)
创建活动
activityAPI.createActivity(withName: "Rowing session",
withType: .rowing,
withStartDate: Date(day: 20, month: 1, year: 2016, hour: 12, minute: 35, second: 46),
withElapsedTime: Time(seconds: 6345),
withDescription: "Relaxing training",
withDistance: Distance(meters: 1234),
isPrivate: false,
withTrainer: true,
withCommute: false)
.execute { result : StravaResult<Activity> in ... }
检索活动
activityAPI.retrieveActivity(withID: 321934,
includeAllEfforts: true)
.execute{ result : StravaResult<Activity> in ... }
更新活动
activityAPI.updateActivity(withID: 321934,
withName: "Rowing session",
withType: .rowing,
isPrivate: true,
withTrainer: false,
withCommute: true,
withGearID: "b123456",
withDescription: "Best training ever!")
.execute{ result : StravaResult<Activity> in ... }
删除活动
activityAPI.deleteActivity(withID: 321934)
.execute{ result : StravaResult<Bool> in ... }
列出用户的活动
activityAPI.listActivities(before: 1000, after: 2000)
.of(page: 2, itemsPerPage: 10)
.execute{ result : StravaResult<EquatableArray<Activity>> in ... }
列出用户的交友活动
activityAPI.listFriendsActivities(before: 1000)
.of(page: 2, itemsPerPage: 10)
.execute{ result : StravaResult<EquatableArray<Activity>> in ... }
列出相关活动
activityAPI.listRelatedActivities(toActivityWithID: 321934)
.of(page: 2, itemsPerPage: 10)
.execute{ result : StravaResult<EquatableArray<Activity>> in ... }
列出活动区域
activityAPI.listActivityZones(withID: 321934)
.execute{ result : StravaResult<EquatableArray<ActivityZone>> in ... }
列出活动圈数
activityAPI.listActivityLaps(withID: 321934)
.execute{ result : StravaResult<EquatableArray<ActivityLap> in ... }
评论API
创建评论API对象
let commentAPI = CommentAPI(client: client)
列出活动评论
commentAPI.listActivityComments(withID: 123)
.of(page: 2, itemsPerPage: 10)
.execute{ result : StravaResult<EquatableArray<Comment>> in ... }
赞API
创建Kudos API对象
let kudosAPI = KudosAPI(client: client)
列出活动赞者
kudosAPI.listActivityKudos(withID: 321934)
.of(page: 2, itemsPerPage: 10)
.execute{ result : StravaResult<EquatableArray<Athlete>> in ... }
照片API
创建照片API对象
let photoAPI = PhotoAPI(client: client)
列出活动照片
photoAPI.listActivityPhotos(withID: 81121657)
.execute{ result : StravaResult<EquatableArray<Photo>> in ... }
俱乐部API
创建俱乐部API对象
let clubAPI = ClubAPI(client: client)
检索俱乐部
clubAPI.retrieveClub(withID: 1)
.execute{ result : StravaResult<Club> in ... }
列出俱乐部公告
clubAPI.listClubAnnouncements(withID: 109984)
.execute{ result : StravaResult<EquatableArray<Announcement>> in ... }
列出俱乐部小组活动
clubAPI.listClubGroupEvents(withID: 1)
.execute{ result : StravaResult<EquatableArray<Event>> in ... }
列出用户所属俱乐部
clubAPI.listAthleteClubs()
.execute{ result : StravaResult<EquatableArray<Club>> in ... }
列出俱乐部成员
clubAPI.listClubMembers(withID: 123)
.execute{ result : StravaResult<EquatableArray<Athlete>> in ... }
列出俱乐部管理员
clubAPI.listClubAdmins(withID: 123)
.execute{ result : StravaResult<EquatableArray<Athlete>> in ... }
列表俱乐部活动
clubAPI.listClubActivities(withID: 123, before: 9999)
.of(page: 2, itemsPerPage: 10)
.execute{ result : StravaResult<EquatableArray<Activity>> in ... }
加入俱乐部
clubAPI.joinClub(withID: 123)
.execute{ result : StravaResult<JoinResult> in ... }
离开俱乐部
clubAPI.leaveClub(withID: 123)
.execute{ result : StravaResult<LeaveResult> in ... }
gear API
创建Gear API对象
let gearAPI = GearAPI(client: client)
检索装备
gearAPI.getGear(withID: "b105763")
.execute{ result : StravaResult<Gear> in ... }
路由API
生成路线API
let routeAPI = RouteAPI(client: client)
获取一个路线
routeAPI.retrieveRoute(withID: 1263727)
.execute{ result : StravaResult<Route> in ... }
列出运动员的路线
routeAPI.listAthleteRoutes(withID: 1234)
.execute{ result : StravaResult<EquatableArray<Route>> in ... }
分段API
生成分段API对象
let segmentAPI = SegmentAPI(client: client)
获取一个分段
segmentAPI.retrieveSegment(withID: 229781)
.execute{ result : StravaResult<Segment> in ... }
列出用户收藏的分段
segmentAPI.listMyStarredSegments()
.execute{ result : StravaResult<EquatableArray<Segment>> in ... }
列出其他运动员的收藏片段
segmentAPI.listAthleteStarredSegments(withID: 1234)
.execute{ result : StravaResult<EquatableArray<Segment>> in ... }
收藏一个片段
segmentAPI.starSegment(withID: 229781)
.execute{ result : StravaResult<Segment> in ... }
取消收藏一个片段
segmentAPI.unstarSegment(withID: 229781)
.execute{ result : StravaResult<Segment> in ... }
列出片段成绩
segmentAPI.listSegmentEfforts(withID: 229781,
forAthleteWithID: 1234,
withStartDate: Date(day: 1, month: 1, year: 2015, hour: 0, minute: 0, second: 1),
withEndDate: Date(day: 31, month: 12, year: 2015, hour: 23, minute: 59, second: 59))
.of(page: 2, itemsPerPage: 10)
.execute{ result : StravaResult<EquatableArray<SegmentEffort>> in ... }
检索片段排行榜
segmentAPI.retrieveSegmentLeaderboard(withID: 229781,
withGender: .female,
withAgeGroup: .age_25_34,
withWeightClass: .kg_65_74,
following: true,
withClubID: 321,
inDateRange: .thisMonth,
withContextEntries: 4)
.of(page: 2, itemsPerPage: 10)
.execute{ result : StravaResult<Leaderboard> in ... }
探索片段
segmentAPI.explore(inRegion: Bounds(southWest: Coordinates(latitude: 15, longitude: -24),
northEast: Coordinates(latitude: -32, longitude: 40)),
withActivityType: .running,
withMinCategory: 3,
withMaxCategory: 7)
.execute{ result : StravaResult<ExploreResult> in ... }
片段努力API
创建分段努力API对象
let segmentEffortAPI = SegmentEffortAPI(client: client)
检索分段努力
segmentEffortAPI.retrieveSegmentEffort(withID: 269990681)
.execute{ result : StravaResult<SegmentEffort> in ... }
流API
创建流API对象
let streamAPI = StreamAPI(client: client)
检索活动流
streamAPI.listActivityStreams(withID: 112233,
forTypes: .altitude, .time, .temperature,
withResolution: .low,
withSeriesType: .time)
.execute{ result : StravaResult<EquatableArray<Stream>> in ... }
检索分段努力流
streamAPI.listSegmentEffortStreams(withID: 112233,
forTypes: .altitude, .time, .temperature,
withResolution: .low,
withSeriesType: .time)
.execute{ result : StravaResult<EquatableArray<Stream>> in ... }
检索分段流
streamAPI.listSegmentStreams(withID: 112233,
forTypes: .altitude, .time, .temperature,
withResolution: .low,
withSeriesType: .time)
.execute{ result : StravaResult<EquatableArray<Stream>> in ... }
检索路线流
streamAPI.listRouteStreams(withID: 112233)
.execute{ result : StravaResult<EquatableArray<Stream>> in ... }
上传API
创建上传API对象
let uploadAPI = UploadAPI(client: client)
上传文件
Strava 允许您上传 GPX、FIT 或 TCX 格式的文件。我们建议使用 TCXZpot 生成可以上传到 Strava 的 TCX 文件。
uploadAPI.upload(file : URL(string: "file://path_to_file")!,
withFilename : "filename.fit",
withDataType : .fit,
withActivityType : .ride,
withName : "A complete ride around the city",
withDescription : "No description",
isPrivate : false,
hasTrainer : false,
isCommute : false,
withExternalID : "test.fit")
.execute{ result : StravaResult<UploadStatus> in ... }
检查上传状态
uploadAPI.checkUploadStatus(withId: 16486788)
.execute{ result : StravaResult<UploadStatus> in ... }
下载
您可以从 CocoaPods 获取 StravaZpot。只需将此行添加到您的 Podfile 中。
pod 'StravaZpot-Swift', '~> 1.0.5'
许可证
Copyright 2017 SweetZpot AS
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://apache.ac.cn/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.