Skip to content

Commit 28c32ab

Browse files
committed
updated documentation
1 parent a7744b7 commit 28c32ab

3 files changed

Lines changed: 152 additions & 47 deletions

File tree

ContentAPI.md

Lines changed: 149 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ The KinesteX Content API allows you to fetch workout plans, workouts, and exerci
1212

1313
- **API Key**: You must have a valid API key provided by KinesteX.
1414
- **Company Name**: Your company's name as registered with KinesteX.
15-
- **Dependencies**: Ensure you have Kotlin Coroutines in your project and latest version of KinesteXSDK. Check latest version [here](https://jitpack.io/#KinesteX/KinesteX-SDK-Kotlin)
15+
- **Dependencies**: Ensure you have Kotlin Coroutines in your project and the latest version of KinesteXSDK. Check the latest version [here](https://jitpack.io/#KinesteX/KinesteX-SDK-Kotlin).
1616

1717
### Fetching Content
1818

@@ -22,6 +22,8 @@ You can fetch different types of content by specifying the `ContentType`. The av
2222
- `ContentType.PLAN`
2323
- `ContentType.EXERCISE`
2424

25+
Additionally, you can fetch lists of content by providing optional parameters such as `category`, `bodyParts`, `limit`, and `lastDocId` for pagination.
26+
2527
Here's how you can fetch content:
2628

2729
```kotlin
@@ -33,18 +35,57 @@ btnApiRequest.setOnClickListener {
3335

3436
// Switch to IO dispatcher for network request
3537
val result = withContext(Dispatchers.IO) {
38+
// FOR FETCHING PLANS LIST
3639
fetchContent(
3740
apiKey = apiKey,
3841
companyName = company,
3942
contentType = ContentType.PLAN,
40-
title = "Circuit Training" // example plan
43+
category = "Cardio",
44+
limit = 5
4145
)
4246

43-
// FOR FETCHING WORKOUT
44-
// fetchContent(apiKey, company, ContentType.WORKOUT, title = "Fitness Lite")
45-
46-
// FOR FETCHING EXERCISE
47-
// fetchContent(apiKey, company, ContentType.EXERCISE, title = "Squats")
47+
// FOR FETCHING WORKOUTS LIST (with category and body parts)
48+
// fetchContent(
49+
// apiKey = apiKey,
50+
// companyName = company,
51+
// contentType = ContentType.WORKOUT,
52+
// category = "Fitness",
53+
// bodyParts = listOf(BodyPart.ABS),
54+
// limit = 5
55+
// )
56+
57+
// FOR FETCHING EXERCISES LIST (with body parts)
58+
// fetchContent(
59+
// apiKey = apiKey,
60+
// companyName = company,
61+
// contentType = ContentType.EXERCISE,
62+
// bodyParts = listOf(BodyPart.ABS),
63+
// limit = 5
64+
// )
65+
66+
// FOR FETCHING a Specific Plan
67+
// fetchContent(
68+
// apiKey = apiKey,
69+
// companyName = company,
70+
// contentType = ContentType.PLAN,
71+
// title = "Circuit Training"
72+
// )
73+
74+
// FOR FETCHING a Specific Workout
75+
// fetchContent(
76+
// apiKey = apiKey,
77+
// companyName = company,
78+
// contentType = ContentType.WORKOUT,
79+
// title = "Fitness Lite"
80+
// )
81+
82+
// FOR FETCHING a Specific Exercise
83+
// fetchContent(
84+
// apiKey = apiKey,
85+
// companyName = company,
86+
// contentType = ContentType.EXERCISE,
87+
// title = "Squats"
88+
// )
4889
}
4990

5091
// Handle the result on the main thread
@@ -68,7 +109,7 @@ btnApiRequest.setOnClickListener {
68109

69110
- **Button Click Listener**: When the button is clicked, a coroutine is launched in the lifecycle scope.
70111
- **Switch to IO Dispatcher**: The `withContext(Dispatchers.IO)` block ensures that the network request is performed on an IO thread, preventing UI blocking.
71-
- **Fetch Content**: The `fetchContent` function is called with the necessary parameters to fetch the desired content.
112+
- **Fetch Content**: The `fetchContent` function is called with the necessary parameters to fetch the desired content. You can uncomment the relevant lines to fetch lists or specific items based on your needs.
72113
- **Handle Result**: After fetching, the result is passed to `handleAPIResult` to process the response.
73114

74115
### Fetch Content Function
@@ -79,14 +120,24 @@ private suspend fun fetchContent(
79120
companyName: String,
80121
contentType: ContentType,
81122
id: String? = null,
82-
title: String? = null
123+
title: String? = null,
124+
lang: String = "en",
125+
category: String? = null,
126+
lastDocId: String? = null,
127+
limit: Int? = null,
128+
bodyParts: List<BodyPart>? = null
83129
): APIContentResult {
84130
return KinesteXAPI.fetchAPIContentData(
85131
apiKey = apiKey,
86132
companyName = companyName,
87133
contentType = contentType,
134+
id = id,
88135
title = title,
89-
id = id
136+
lang = lang,
137+
category = category,
138+
lastDocId = lastDocId,
139+
limit = limit,
140+
bodyParts = bodyParts
90141
)
91142
}
92143
```
@@ -99,6 +150,10 @@ private suspend fun fetchContent(
99150
- `contentType`: The type of content to fetch (`WORKOUT`, `PLAN`, `EXERCISE`).
100151
- `id` *(optional)*: Specific ID of the content.
101152
- `title` *(optional)*: Title of the content to search for.
153+
- `category` *(optional)*: Filter content by category.
154+
- `lastDocId` *(optional)*: Identifier for pagination to fetch the next set of results.
155+
- `limit` *(optional)*: Limit the number of results returned.
156+
- `bodyParts` *(optional)*: Filter workouts or exercises by targeted body parts using the `BodyPart` enum.
102157
- **Return Value**: An `APIContentResult` object containing the fetched data or an error message.
103158

104159
### Handling the API Result
@@ -124,6 +179,30 @@ private fun handleAPIResult(result: APIContentResult) {
124179
val prettyJson = gson.toJson(exercise)
125180
println("Exercise Data:\n$prettyJson")
126181
}
182+
is APIContentResult.Workouts -> {
183+
val workouts = result.workouts.workouts
184+
workouts.forEach { workout ->
185+
println("Workout Title: ${workout.title}")
186+
println("Body Parts: ${workout.body_parts.joinToString { it.value }}")
187+
println("LastDocId: ${result.workouts.lastDocId}")
188+
}
189+
}
190+
is APIContentResult.Plans -> {
191+
val plans = result.plans.plans
192+
plans.forEach { plan ->
193+
println("Plan Title: ${plan.title}")
194+
println("Categories: ${plan.category.description}")
195+
println("LastDocId: ${result.plans.lastDocId}")
196+
}
197+
}
198+
is APIContentResult.Exercises -> {
199+
val exercises = result.exercises.exercises
200+
exercises.forEach { exercise ->
201+
println("Exercise Title: ${exercise.title}")
202+
println("Body Parts: ${exercise.body_parts.joinToString { it.value }}")
203+
println("LastDocId: ${result.exercises.lastDocId}")
204+
}
205+
}
127206
is APIContentResult.Error -> {
128207
Toast.makeText(
129208
this,
@@ -139,56 +218,80 @@ private fun handleAPIResult(result: APIContentResult) {
139218

140219
- **APIContentResult**: A sealed class representing the result of the API request.
141220
- **Success Cases**:
142-
- `Workout`: Contains a `WorkoutModel`.
143-
- `Plan`: Contains a `PlanModel`.
144-
- `Exercise`: Contains an `ExerciseModel`.
221+
- `Workout`: Contains a single `WorkoutModel`.
222+
- `Plan`: Contains a single `PlanModel`.
223+
- `Exercise`: Contains a single `ExerciseModel`.
224+
- `Workouts`: Contains a list of `WorkoutModel` along with `lastDocId` for pagination.
225+
- `Plans`: Contains a list of `PlanModel` along with `lastDocId` for pagination.
226+
- `Exercises`: Contains a list of `ExerciseModel` along with `lastDocId` for pagination.
145227
- **Error Case**:
146228
- `Error`: Contains an error message.
147229
- **Handling Data**:
148-
- Use `Gson` with pretty printing to convert the result into a readable JSON format.
149-
- Print the data to the console or handle it as needed in your application.
230+
- Use `Gson` with pretty printing to convert single item results into a readable JSON format.
231+
- Iterate through lists (`Workouts`, `Plans`, `Exercises`) and handle each item as needed.
232+
- **Pagination**: After handling the current set of results, use the provided `lastDocId` to fetch the next set of data.
150233
- **Handling Errors**:
151234
- Display a toast message or handle the error appropriately.
152235

153-
---
154-
155-
## Implementation Overview
156-
157-
The core of the Content API lies in the `KinesteXAPI` class and related data models. Here's a brief overview:
236+
### Pagination with `lastDocId`
158237

159-
### KinesteXAPI Class
238+
To implement pagination, utilize the `lastDocId` provided in the response of your initial request. This ID allows you to fetch the next set of results in subsequent API calls.
160239

161-
Responsible for making network requests to the KinesteX server to fetch content data.
240+
#### Example: Fetching the Next Page of Workouts
162241

163242
```kotlin
164-
class KinesteXAPI {
165-
companion object {
166-
private const val BASE_API_URL = "https://admin.kinestex.com/api/v1/"
167-
168-
suspend fun fetchAPIContentData(
169-
apiKey: String,
170-
companyName: String,
171-
contentType: ContentType,
172-
id: String? = null, // id of the plan
173-
title: String? = null,
174-
lang: String = "en"
175-
): APIContentResult {
176-
// Implementation details...
177-
}
243+
// Initial Fetch
244+
val initialResult = fetchContent(
245+
apiKey = apiKey,
246+
companyName = company,
247+
contentType = ContentType.WORKOUT,
248+
category = "Fitness",
249+
limit = 5
250+
)
251+
252+
// Handle Initial Result
253+
handleAPIResult(initialResult)
254+
255+
// Assume you have obtained lastDocId from the initialResult
256+
val lastDocId = when (initialResult) {
257+
is APIContentResult.Workouts -> initialResult.workouts.lastDocId
258+
else -> null
259+
}
178260

179-
private fun containsDisallowedCharacters(text: String): Boolean {
180-
// Validation logic...
181-
}
182-
}
261+
// Fetch Next Page Using lastDocId
262+
if (lastDocId != null) {
263+
val nextPageResult = fetchContent(
264+
apiKey = apiKey,
265+
companyName = company,
266+
contentType = ContentType.WORKOUT,
267+
category = "Fitness",
268+
limit = 5,
269+
lastDocId = lastDocId
270+
)
271+
272+
// Handle Next Page Result
273+
handleAPIResult(nextPageResult)
183274
}
184275
```
185276

277+
#### Explanation
278+
279+
1. **Initial Fetch**: Fetch the first set of workouts with a specified `limit`.
280+
2. **Handle Initial Result**: Process and display the fetched workouts.
281+
3. **Retrieve `lastDocId`**: Extract the `lastDocId` from the initial response to use for the next request.
282+
4. **Fetch Next Page**: Use the retrieved `lastDocId` to fetch the subsequent set of workouts.
283+
5. **Handle Next Page Result**: Process and display the next set of workouts.
284+
285+
---
286+
186287
#### Key Points
187288

188289
- **Endpoints**: Constructs the appropriate endpoint based on `ContentType`.
189290
- **Headers**: Adds `x-api-key` and `x-company-name` to authenticate requests.
190291
- **Network Call**: Uses `OkHttpClient` to perform synchronous network calls.
191292
- **Error Handling**: Returns an `APIContentResult.Error` in case of failures.
293+
- **BodyPart Filtering**: Supports filtering by `BodyPart` enum to fetch targeted content lists.
294+
- **Pagination**: Utilizes `lastDocId` to implement pagination, allowing you to fetch subsequent pages of content.
192295

193296
### Data Models
194297

@@ -198,7 +301,7 @@ Data classes representing the structure of the content:
198301
- **ExerciseModel**
199302
- **PlanModel**
200303

201-
These models represent the data received from the API and are used throughout your application.
304+
These models represent the data received from the API and are used throughout your application. They now include `body_parts` as a list of `BodyPart` enums to ensure type safety and consistency.
202305

203306
---
204307

@@ -228,13 +331,15 @@ val result = withContext(Dispatchers.IO) {
228331
- **Error Handling**: Always handle possible exceptions, especially when dealing with network requests.
229332
- **Thread Safety**: UI updates must occur on the main thread. Ensure that after fetching data on `Dispatchers.IO`, any UI operations are performed on the main thread.
230333
- **Asynchronous Programming**: Utilizing coroutines and proper dispatchers helps in writing asynchronous code that is easy to read and maintain.
334+
- **BodyPart Enum**: Utilize the `BodyPart` enum to specify targeted muscle groups when fetching workouts or exercises, ensuring consistency and type safety.
335+
- **Pagination**: Use the `lastDocId` from your API responses to fetch subsequent pages of content, enabling smooth and efficient data loading.
231336

232337
---
233338

234339
## Conclusion
235340

236-
The KinesteX Content API provides a straightforward way to access workout content within your Android application. By following the usage examples and understanding the importance of coroutine dispatchers, you can efficiently integrate and handle content data.
341+
The KinesteX Content API provides a straightforward way to access workout content within your Android application. By following the usage examples and understanding the importance of coroutine dispatchers and pagination, you can efficiently integrate and handle content data.
237342

238-
For any issues or further assistance, please contact KinesteX support at [support@kinestex.com](mailto:support@kinestex.com).
343+
With the added capability to fetch lists of workouts, plans, and exercises with filters like `category`, `bodyParts`, `limit`, and `lastDocId`, you have greater flexibility in customizing the content retrieval to suit your application's needs.
239344

240-
---
345+
For any issues or further assistance, please contact KinesteX support at [support@kinestex.com](mailto:support@kinestex.com).

app/build.gradle.kts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,15 @@ android {
3838
}
3939

4040
dependencies {
41-
implementation(project(":kinestexsdkkotlin"))
41+
//implementation(project(":kinestexsdkkotlin"))
4242
implementation("androidx.core:core-ktx:1.9.0")
4343
implementation("com.google.code.gson:gson:2.8.8")
4444
implementation("androidx.appcompat:appcompat:1.6.1")
4545
implementation("com.google.android.material:material:1.11.0")
4646
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
4747
testImplementation("junit:junit:4.13.2")
4848
androidTestImplementation("androidx.test.ext:junit:1.1.5")
49-
// implementation("com.github.KinesteX:KinesteX-SDK-Kotlin:1.1.7")
49+
implementation("com.github.KinesteX:KinesteX-SDK-Kotlin:1.1.8")
5050
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
5151
implementation("androidx.activity:activity-ktx:1.9.0")
5252
implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.8.1")

settings.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@ pluginManagement {
1616

1717
rootProject.name = "KinesteXSDKKotlin"
1818
include(":app")
19-
include(":kinestexsdkkotlin")
19+
//include(":kinestexsdkkotlin")

0 commit comments

Comments
 (0)