Skip to content

Commit 51bd398

Browse files
authored
feat(algolia-client): Upgrading Algolia client from version 2 to 3.xx (#417)
1 parent 8c9cd63 commit 51bd398

File tree

391 files changed

+3925
-2919
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

391 files changed

+3925
-2919
lines changed

CHANGELOG.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,32 @@
1+
# 4.0.0
2+
3+
### Added
4+
- Insights: v3 events sending for automatic hits view tracking
5+
- Facets search: serialize `SearchParamsObject` into `params` for SearchForFacetValues requests
6+
7+
### Changed
8+
- Kotlin version to `2.2.0`
9+
- Ktor version to `3.3.3`
10+
- Algolia Kotlin API client version to `3.37.2`
11+
- AGP version to `8.7.2`
12+
- Compose UI version to `1.10.0`
13+
- Compose compiler version to `2.2.0`
14+
- Coroutines version to `1.10.2`
15+
- Android `minSdk` to `23` (was `21`)
16+
- Android `compileSdk` to `35` (was `33`)
17+
- Telemetry: base64 encoding uses internal util;
18+
- Facet list tracing now uses `FacetHits`.
19+
- Insights: HTTP repository sends events via `pushEvents`
20+
- Insights: Filter strings are parsed into stored filters
21+
- Tests: Insights client mocked in `InsightsTest`
22+
- Single-index searcher tests updated for auto-sent view events
23+
- Examples: To Support the latest Algolia Kotlin API clients
24+
25+
26+
### Removed
27+
- Answers feature (`SearcherAnswers`, filter-state connection, telemetry hook, tests)
28+
- Primitive wrapper data classes: `Attribute`, `ObjectID`, `AppID`.
29+
130
# 3.3.3
231

332
### Fixed

README.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,10 @@ You can add InstantSearch to your Android application by adding the following li
2323
implementation "com.algolia:instantsearch-android:$instantsearch_version"
2424
```
2525

26-
ℹ️ Please follow the [migration guide](docs/guide/Migration_2.x_3.x.md) to migrate from `2.x` to the latest version.
26+
ℹ️ Please follow the migration guides to upgrade to the latest version:
27+
- [3.x to 4.x migration guide](docs/guide/Migration_3.x_4.x.md)
28+
- [2.x to 3.x migration guide](docs/guide/Migration_2.x_3.x.md)
29+
2730
▶️ See the [documentation][doc]. You can start with the [Getting Started Guide][getting-started].
2831

2932
<details>
@@ -59,8 +62,8 @@ Please refer to the [library](instantsearch-insights/README.md) for more details
5962

6063
## Requirements
6164

62-
* Kotlin 1.9+
63-
* Android SDK 21+
65+
* Kotlin 2.2+
66+
* Android SDK 23+
6467
* Java 8+
6568

6669
### R8 / Proguard rules

build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ plugins {
77
alias(libs.plugins.android) apply false
88
alias(libs.plugins.maven.publish) apply false
99
alias(libs.plugins.spotless) apply false
10+
alias(libs.plugins.kotlin.android) apply false
11+
alias(libs.plugins.compose.compiler) apply false
1012
}
1113

1214
subprojects {

docs/guide/Migration_3.x_4.x.md

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
# Migrate from 3.x to 4.x
2+
3+
The library version `4.0` uses Kotlin version `2.2` and Algolia Kotlin API Client `3.37`. Below are the steps to migrate.
4+
5+
## Table of Contents
6+
7+
- [Requirements](#requirements)
8+
- [Kotlin API Client](#kotlin-api-client)
9+
- [Removed Features](#removed-features)
10+
- [Breaking Changes](#breaking-changes)
11+
12+
## Requirements
13+
14+
InstantSearch Android 4.x has updated minimum requirements:
15+
16+
| Requirement | 3.x | 4.x |
17+
|----------------|:----------|:----------|
18+
| Kotlin | 1.9+ | 2.2+ |
19+
| Android minSdk | 21 | 23 |
20+
| Android compileSdk | 33 | 35 |
21+
| Ktor | 2.3 | 3.3 |
22+
| Algolia Client | 2.x | 3.x |
23+
24+
## Kotlin API Client
25+
26+
The Algolia Kotlin API Client has been upgraded from version `2.x` to `3.x`. This is a major version upgrade with significant changes.
27+
28+
### Key Changes
29+
30+
#### Import Paths
31+
Some classes may have moved to different packages. Update your imports accordingly.
32+
33+
#### Data Classes
34+
The primitive wrapper data classes have been removed:
35+
- `Attribute` - Use `String` directly
36+
- `ObjectID` - Use `String` directly
37+
- `AppID` - Use `String` directly
38+
39+
**Before (3.x):**
40+
```kotlin
41+
val objectID = ObjectID("my-object-id")
42+
val attribute = Attribute("category")
43+
```
44+
45+
**After (4.x):**
46+
```kotlin
47+
val objectID = "my-object-id"
48+
val attribute = "category"
49+
```
50+
51+
#### API Method Changes
52+
Some API methods and response structures have changed. Refer to the [Algolia Kotlin Client 3.x documentation](https://github.com/algolia/algoliasearch-client-kotlin) for details.
53+
54+
## Removed Features
55+
56+
### SearcherAnswers
57+
The Answers feature has been removed as it's no longer supported by Algolia. If you were using `SearcherAnswers`, you'll need to migrate to alternative search approaches:
58+
59+
**Removed:**
60+
- `SearcherAnswers` class
61+
- `SearcherAnswers` filter-state connection
62+
- Related telemetry hooks
63+
64+
### SearcherPlaces
65+
The Places feature has been deprecated and removed. Please refer to [Algolia Places migration guide](https://www.algolia.com/doc/guides/building-search-ui/ui-and-ux-patterns/geo-search/android/) for alternatives.
66+
67+
## Breaking Changes
68+
69+
### Insights Events
70+
The Insights implementation has been updated to use v3 events:
71+
- HTTP repository now sends events via `pushEvents` API
72+
- Filter strings are now parsed into stored filters
73+
- Automatic hits view tracking uses v3 event format
74+
75+
### Facets
76+
- Facet list tracing now uses `FacetHits` instead of older structures
77+
- Facets search now serializes `SearchParamsObject` into `params` for SearchForFacetValues requests
78+
79+
### Dependencies
80+
If you're updating your project, make sure to update related dependencies:
81+
82+
```gradle
83+
// Update Kotlin
84+
kotlin = "2.2.0"
85+
86+
// Update Algolia Client
87+
implementation "com.algolia:algoliasearch-client-kotlin:3.37.2"
88+
89+
// Update Ktor if using directly
90+
ktor = "3.3.3"
91+
92+
// Update Compose if using
93+
androidx.compose.ui = "1.10.0"
94+
```
95+
96+
### Migration Steps
97+
98+
1. **Update dependencies** in your `build.gradle` or `gradle/libs.versions.toml`
99+
2. **Update minimum SDK version** to 23 in your `build.gradle`
100+
3. **Remove wrapper classes**: Replace `ObjectID`, `Attribute`, `AppID` with `String`
101+
4. **Remove Answers usage**: If using `SearcherAnswers`, migrate to standard search
102+
5. **Remove Places usage**: If using `SearcherPlaces`, migrate to alternative geo-search solutions
103+
6. **Update API calls**: Review and update any direct Algolia API client calls according to client 3.x changes
104+
7. **Test thoroughly**: The new versions include significant internal changes, so comprehensive testing is recommended
105+
106+
For more details on specific changes, refer to the [CHANGELOG](../../CHANGELOG.md).

examples/android/build.gradle

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
apply plugin: 'com.android.application'
22
apply plugin: 'kotlin-android'
33
apply plugin: 'kotlinx-serialization'
4+
apply plugin: 'org.jetbrains.kotlin.plugin.compose'
45

56
android {
6-
compileSdkVersion 33
7+
compileSdkVersion 36
78
namespace "com.algolia.instantsearch.examples.android"
89

910
defaultConfig {
1011
applicationId "com.algolia.instantsearch.examples.android"
1112
minSdkVersion 23
12-
targetSdkVersion 33
13+
targetSdkVersion 35
1314
versionCode 1
1415
versionName "1.0"
1516
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@@ -89,6 +90,7 @@ tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach {
8990
'-Xopt-in=kotlin.RequiresOptIn',
9091
'-Xopt-in=com.algolia.instantsearch.ExperimentalInstantSearch',
9192
'-Xopt-in=androidx.compose.material.ExperimentalMaterialApi',
93+
'-opt-in=kotlinx.serialization.InternalSerializationApi',
9294
]
9395
}
9496
}

examples/android/src/main/AndroidManifest.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
<uses-permission android:name="android.permission.INTERNET" />
55
<uses-permission android:name="android.permission.RECORD_AUDIO" />
6+
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
67

78
<application
89
android:name=".App"

examples/android/src/main/kotlin/com/algolia/instantsearch/examples/android/App.kt

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,22 @@
11
package com.algolia.instantsearch.examples.android
22

33
import android.app.Application
4+
import io.ktor.client.plugins.logging.LogLevel
45
import com.algolia.instantsearch.insights.registerInsights
5-
import com.algolia.search.logging.LogLevel
6-
import com.algolia.search.model.APIKey
7-
import com.algolia.search.model.ApplicationID
8-
import com.algolia.search.model.IndexName
9-
import com.algolia.search.model.insights.UserToken
106

117
class App : Application() {
128

139
override fun onCreate() {
1410
super.onCreate()
1511
registerInsights(
1612
context = this,
17-
appId = ApplicationID("latency"),
18-
apiKey = APIKey("afc3dd66dd1293e2e2736a5a51b05c0a"),
19-
indexName = IndexName("instant_search"),
20-
clientLogLevel = LogLevel.All
13+
appId = "latency",
14+
apiKey = "afc3dd66dd1293e2e2736a5a51b05c0a",
15+
indexName = "instant_search",
16+
clientLogLevel = LogLevel.NONE
2117
).apply {
2218
loggingEnabled = true
23-
userToken = UserToken("userToken")
19+
userToken = "userToken"
2420
minBatchSize = 1
2521
}
2622
}

examples/android/src/main/kotlin/com/algolia/instantsearch/examples/android/codex/categorieshits/MainViewModel.kt

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.algolia.instantsearch.examples.android.codex.categorieshits
22

33
import androidx.lifecycle.ViewModel
4+
import com.algolia.client.model.search.FacetHits
45
import com.algolia.instantsearch.compose.hits.HitsState
56
import com.algolia.instantsearch.compose.searchbox.SearchBoxState
67
import com.algolia.instantsearch.core.connection.ConnectionHandler
@@ -11,32 +12,29 @@ import com.algolia.instantsearch.searcher.facets.addFacetsSearcher
1112
import com.algolia.instantsearch.searcher.hits.addHitsSearcher
1213
import com.algolia.instantsearch.searcher.multi.MultiSearcher
1314
import com.algolia.search.helper.deserialize
14-
import com.algolia.search.model.APIKey
15-
import com.algolia.search.model.ApplicationID
16-
import com.algolia.search.model.Attribute
17-
import com.algolia.search.model.IndexName
18-
import com.algolia.search.model.search.Facet
1915

2016
class MainViewModel : ViewModel() {
2117

2218
private val multiSearcher = MultiSearcher(
23-
applicationID = ApplicationID("latency"),
24-
apiKey = APIKey("6be0576ff61c053d5f9a3225e2a90f76")
19+
appId = "latency",
20+
apiKey = "6be0576ff61c053d5f9a3225e2a90f76"
2521
)
26-
private val indexName = IndexName("instant_search")
27-
private val attribute = Attribute("categories")
22+
private val indexName = "instant_search"
23+
private val attribute = "categories"
2824
private val productsSearcher = multiSearcher.addHitsSearcher(indexName)
2925
private val categoriesSearcher = multiSearcher.addFacetsSearcher(indexName, attribute)
3026
private val searchBoxConnector = SearchBoxConnector(multiSearcher)
3127
private val connections = ConnectionHandler(searchBoxConnector)
3228

3329
val searchBoxState = SearchBoxState()
34-
val categoriesState = HitsState<Facet>()
30+
val categoriesState = HitsState<FacetHits>()
3531
val productsState = HitsState<Product>()
3632

3733
init {
3834
connections += searchBoxConnector.connectView(searchBoxState)
39-
connections += categoriesSearcher.connectHitsView(categoriesState) { it.facets }
35+
connections += categoriesSearcher.connectHitsView(categoriesState) { response ->
36+
response.facetHits
37+
}
4038
connections += productsSearcher.connectHitsView(productsState) { it.hits.deserialize(Product.serializer()) }
4139
multiSearcher.searchAsync()
4240
}
Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
package com.algolia.instantsearch.examples.android.codex.categorieshits
22

3+
import com.algolia.instantsearch.core.Indexable
34
import com.algolia.instantsearch.highlighting.Highlightable
4-
import com.algolia.search.model.Attribute
5-
import com.algolia.search.model.ObjectID
6-
import com.algolia.search.model.indexing.Indexable
75
import kotlinx.serialization.Serializable
86
import kotlinx.serialization.json.JsonObject
97

@@ -12,13 +10,13 @@ data class Product(
1210
val name: String,
1311
val description: String,
1412
val image: String,
15-
override val objectID: ObjectID,
13+
override val objectID: String,
1614
override val _highlightResult: JsonObject?
1715
) : Indexable, Highlightable {
1816

1917
val highlightedName
20-
get() = getHighlight(Attribute("name"))
18+
get() = getHighlight("name")
2119

2220
val highlightedDescription
23-
get() = getHighlight(Attribute("description"))
21+
get() = getHighlight("description")
2422
}

examples/android/src/main/kotlin/com/algolia/instantsearch/examples/android/codex/categorieshits/SearchScreen.kt

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
1-
@file:OptIn(ExperimentalFoundationApi::class)
2-
31
package com.algolia.instantsearch.examples.android.codex.categorieshits
42

5-
import androidx.compose.foundation.ExperimentalFoundationApi
63
import androidx.compose.foundation.background
74
import androidx.compose.foundation.layout.Column
85
import androidx.compose.foundation.layout.Row
@@ -27,19 +24,19 @@ import androidx.compose.ui.text.SpanStyle
2724
import androidx.compose.ui.text.style.TextOverflow
2825
import androidx.compose.ui.unit.dp
2926
import coil.compose.AsyncImage
27+
import com.algolia.client.model.search.FacetHits
3028
import com.algolia.instantsearch.compose.highlighting.toAnnotatedString
3129
import com.algolia.instantsearch.compose.hits.HitsState
3230
import com.algolia.instantsearch.compose.searchbox.SearchBoxState
3331
import com.algolia.instantsearch.core.highlighting.HighlightTokenizer
3432
import com.algolia.instantsearch.examples.android.AppColors
3533
import com.algolia.instantsearch.examples.android.showcase.compose.ui.component.SearchBox
36-
import com.algolia.search.model.search.Facet
3734

3835
@Composable
3936
fun SearchScreen(
4037
modifier: Modifier = Modifier,
4138
searchBoxState: SearchBoxState,
42-
categoriesState: HitsState<Facet>,
39+
categoriesState: HitsState<FacetHits>,
4340
productsState: HitsState<Product>,
4441
) {
4542
Scaffold(modifier = modifier, topBar = {
@@ -66,7 +63,7 @@ fun SearchScreen(
6663

6764
@Composable
6865
private fun CategoryItem(
69-
modifier: Modifier = Modifier, category: Facet
66+
modifier: Modifier = Modifier, category: FacetHits
7067
) {
7168
Row(
7269
modifier
@@ -138,4 +135,4 @@ private fun SectionTitle(modifier: Modifier = Modifier, title: String) {
138135
)
139136
}
140137

141-
private fun Facet.highlightedString(): AnnotatedString = HighlightTokenizer()(highlighted).toAnnotatedString()
138+
private fun FacetHits.highlightedString(): AnnotatedString = HighlightTokenizer()(highlighted ?: "").toAnnotatedString()

0 commit comments

Comments
 (0)