Swift API Client
This library allows you to request recommendations and send interactions between users and items (such as views, bookmarks, or purchases) to Recombee. It is a thin wrapper around the Recombee API and provides a simple way to interact with it.
This SDK is designed for use in iOS or macOS applications.
For security reasons, it is not possible to change the item catalog, such as the properties of items, using this SDK. To send your Catalog to Recombee, use one of the following methods:
- Use one of our server-side SDKs, for example using a script which runs periodically (see Managing Item Catalog for more details),
- Or set up a Catalog Feed in the Admin UI.
Install
Add the dependency to your Xcode project using Swift Package Manager:
- In Xcode, go to
File → Add Packages
. - Enter the repository URL:
https://github.com/recombee/swift-api-client
. - Choose the latest version and confirm.
Alternatively, in Package.swift
:
.package(url: "https://github.com/recombee/swift-api-client", from: "5.0.2")
Then add the following to your target dependencies:
.target(
name: "MyApp",
dependencies: ["RecombeeClient"]
)
Configure
In order to use the API, you will need to create an instance of the RecombeeClient
class. You will need:
- the ID of your database,
- the public token.
You can find these in the Admin UI, in your Database's Settings page, under API ID & Tokens.
Along with this information, you can also find a complete code snippet for initializing the client.
Ideally, you should only create one instance of RecombeeClient
in your application. It is a lightweight object and can be reused for multiple requests.
We published a simple iOS example app to help you with the integration. Feel free to use it as a reference.

You can initialize the client as follows:
import RecombeeClient
// Initialize the API client with the ID of your database and the associated public token
let client = RecombeeClient(
databaseId: "database-id",
publicToken: "...db-public-token...",
region: .euWest // the region of your database
)
You can also configure optional parameters when initializing the client:
let client = RecombeeClient(
databaseId: "database-id",
publicToken: "...db-public-token...",
region: .euWest // the region of your database
// Optional parameters:
// Use this if you were assigned a custom URI by the Recombee Support team (default: nil)
baseUri: "custom-uri.recombee.com",
// The port to connect to (default: nil)
port: 443,
// Whether to use HTTPS - can be disabled for debugging (default: true)
useHttpsByDefault: true
)
Send Interactions
After you have initialized the client, you can send interactions between users and items.
The individual interactions are types conforming to the Request
protocol in the Recombee Swift SDK.
You create an instance of the interaction and send it using the send
method of the RecombeeClient
class.
Alternatively, when you don't need to process the response, you can use the sendDetached
method instead, which sends a request to the Recombee API in a detached task with default priority.
// Either create the interaction first and then send it
let bookmark = AddBookmark(userId: "user-13434", itemId: "item-256")
try await client.send(bookmark)
// Or send it directly
try await client.send(
AddCartAddition(
userId: "user-4395",
itemId: "item-129",
recommId: "23eaa09b-0e24-4487-ba9c-8e255feb01bb"
)
)
try await client.send(AddDetailView(userId: "user-9318", itemId: "item-108"))
try await client.send(AddPurchase(userId: "user-7499", itemId: "item-750"))
client.sendDetached(AddRating(userId: "user-3967", itemId: "item-365", rating: 0.5))
client.sendDetached(SetViewPortion(userId: "user-4289", itemId: "item-487", portion: 0.3))
Each interaction has both mandatory and optional parameters.
The most important optional parameter is recommId
— if the interaction is based on a previous recommendation, it is the ID of the recommendation request that returned the item.
Providing this ID allows you to track successful recommendations. For more information, read about Reported Metrics.
For a full list of interactions and their parameters, refer to the API Reference.
You can also send multiple interactions at once using the Batch
request:
let batch = Batch(requests: [
AddBookmark(userId: "user-13434", itemId: "item-256"),
AddCartAddition(userId: "user-4395", itemId: "item-129", cascadeCreate: true),
AddDetailView(userId: "user-9318", itemId: "item-108")
])
let responses = try await client.send(batch)
To handle errors gracefully, use do-catch
blocks:
do {
try await client.send(
AddRating(
userId: "user-3967",
itemId: "item-365",
rating: 0.5,
cascadeCreate: true
)
)
print("Interaction sent successfully")
} catch let error as ClientError {
print("ClientError: \(error.localizedDescription)")
} catch {
print("Unexpected error: \(error.localizedDescription)")
}
Get Recommendations
With an initialized client, you can also request recommendations.
There are multiple types of recommendations, such as:
- Recommend Items to User,
- Recommend Items to Item,
- Recommend Item Segments to User (these can be categories, genres, artists, etc.),
- or others.
Each recommendation request is a struct within the RecombeeClient
module and is sent using the send
method.
let client = RecombeeClient(
databaseId: "your-database-id",
publicToken: "your-public-token",
region: .usWest
)
do {
let request = RecommendItemsToUser(
userId: "user-x",
count: 10,
scenario: "homepage-for-you"
)
let response = try await client.send(request)
print("recommId: \(response.recommId)")
for item in response.recomms {
print("ID: \(item.id)")
}
} catch {
print("Error: \(error)")
// Provide fallback...
}
For a full list of request parameters and possible responses, visit the API Reference.
Personalized Search
Personalized full-text search is requested in the same way as recommendations:
let request = SearchItems(
userId: "user-x",
searchQuery: "headphones",
count: 10,
scenario: "search",
returnProperties: true
)
do {
let response = try await client.send(request)
print("recommId: \(response.recommId)")
for item in response.recomms {
print("ID: \(item.id), Values: \(item.values ?? [:])")
}
} catch {
print("Search error: \(error)")
}
Recommend Next Items
If you are implementing features like infinite scroll or pagination, you can use the RecommendNextItems
request to load recommendations progressively.
This means you can fetch the next set of recommended items without repeating the ones you have already displayed.
To use this functionality, you must provide the recommId
from the initial recommendation request.
For more details, see the Recommend Next Items documentation.
// Fetch initial recommendations
let initial = try await client.send(
RecommendItemsToUser(userId: "user-1", count: 5)
)
let recommId = initial.recommId
// Later (e.g. when scrolling)
let next = try await client.send(
RecommendNextItems(recommId: recommId, count: 5)
)
for item in next.recomms {
print("Next: \(item.id)")
}
Optional Parameters
Recommendation requests support various optional parameters to customize their behavior. For a comprehensive list, refer to the API Reference. Below is an example showcasing some commonly used parameters:
let request = RecommendItemsToUser(
userId: "user-13434",
count: 5,
// Scenarios help identify the context where recommendations are displayed
// and can be customized in the Admin UI at https://admin.recombee.com
scenario: "homepage",
// Include detailed properties of the recommended items in the response
returnProperties: true,
// Specify which properties to include (requires returnProperties = true)
includedProperties: ["title", "img_url", "url", "price"],
// Apply a ReQL filter to refine recommendations,
// e.g., "Recommend only items with a title that are in stock."
filter: "'category' == \"chairs\" and 'price' < 200"
// Note: You can define scenario-specific filters in the Admin UI.
// The filter defined here is combined with the Admin UI filter using logical AND.
)
Batch Requests
You may encounter a situation where you display recommendations in multiple places in your app.
In such cases, you can use the Batch
request to send multiple recommendation requests at once. This can help reduce the number of HTTP requests and improve performance.
For example, you can request the most popular items, as well as items related to a specific user or item, in a single Batch
:
/// A basic representation of a recommended item.
struct Item {
let id: String
let title: String
let images: [String]
let recommId: String
}
let batch = Batch(
requests: [
RecommendItemsToItem(
itemId: "item-356",
targetUserId: "user-13434",
count: 3,
scenario: "because-you-watched",
returnProperties: true,
includedProperties: ["title", "images"]
),
RecommendItemsToUser(
userId: "user-13434",
count: 3,
scenario: "new-releases",
returnProperties: true,
includedProperties: ["title", "images"]
),
RecommendItemsToUser(
userId: "user-13434",
count: 3,
scenario: "popular",
returnProperties: true,
includedProperties: ["title", "images"]
)
],
distinctRecomms: true
)
do {
let responses = try await client.send(batch)
let sections: [[Item]] = responses.map { wrapper in
if let response = try? wrapper.response?.decode(as: RecommendationResponse.self) {
return response.recomms.map { item in
Item(
id: item.id,
title: item.values?["title"] as? String ?? "",
images: item.values?["images"] as? [String] ?? [],
recommId: response.recommId
)
}
} else {
return []
}
}
print("Because You Watched: \(sections[0])")
print("New Releases: \(sections[1])")
print("Popular: \(sections[2])")
} catch {
print("Batch request failed: \(error)")
}
The optional parameter distinctRecomms
of the Batch
ensures that the recommended items are not repeated across the responses.
You can find more information about Batch requests in the API Reference.
Error Handling
The API client throws errors of type ClientError
when an operation fails. Each case of this enum represents a different failure scenario that may occur while communicating with the Recombee API.
These errors are part of the RecombeeClient
SDK and can be used in Swift's do-catch
error handling blocks.
Error | Cause |
---|---|
ClientError.timeout | The request exceeded the configured timeout interval. |
ClientError.responseError | The API returned a non-success HTTP status code (e.g. 400, 500). |
ClientError.networkError | A network-related issue occurred, such as a connection failure. |
ClientError.decodingError | The response could not be decoded, possibly due to mismatched types or invalid data. |
ClientError.unknownError | An unspecified or unrecognized error occurred. |
Example
do {
let response = try await client.send(RecommendItemsToUser(userId: "user-1", count: 5))
print("Recommended items: \(response.recomms.map(\.id))")
} catch let error as ClientError {
print("ClientError: \(error.errorDescription ?? "Unknown error")")
} catch {
print("Unexpected error: \(error.localizedDescription)")
}
We are doing our best to provide a reliable service, but sometimes things can go wrong. For this reason, we recommend that you always handle exceptions and provide fallbacks in your application.
For example, when requesting recommendations, a fallback could be to display a generic set of items or an error message to the user.