Swift SDK
Как использовать AACsearch в iOS, macOS и visionOS — установка пакета, поиск товаров, управление индексами.
Swift SDK для AACsearch
Библиотека aacsearch-swift позволяет добавить поиск товаров в ваше iOS, macOS или visionOS-приложение. Полностью написана на Swift с поддержкой async/await.
Установка
Требуется Swift 5.9, iOS 15+, macOS 12+, visionOS 1+.
Swift Package Manager
В Xcode:
- File → Add Packages
- Введите URL:
https://github.com/aacsearch/aacsearch-swift-sdk - Выберите версию (1.0.0+)
- Добавьте в ваш проект
Или в Package.swift:
dependencies: [
.package(url: "https://github.com/aacsearch/aacsearch-swift-sdk", from: "1.0.0")
]Поиск товаров
Используйте AacsearchClient для выполнения поисковых запросов.
import Aacsearch
// Создать клиент
let client = AacsearchClient(apiKey: "ss_search_your_key_here")
// Простой поиск
let results = try await client.search(
indexSlug: "products",
query: "nike shoes",
queryBy: "name,description",
perPage: 20
)
print("Найдено товаров: \(results.found)")
for hit in results.hits {
if let title = hit.document["name"] as? String {
print(" - \(title)")
}
}Поиск с фильтрами и сортировкой
let results = try await client.search(
indexSlug: "products",
query: "shoes",
queryBy: "name,brand",
filterBy: "price:[50..200] && availability:=in_stock", // Цена и наличие
sortBy: "price:asc", // Дешевле в начале
facetBy: "brand,category", // Получить статистику
page: 1,
perPage: 20
)
// Вывести доступные бренды из фасетов
for facet in results.facetCounts ?? [] {
print("Бренд: \(facet.fieldName)")
for count in facet.counts {
print(" \(count.value): \(count.count) товаров")
}
}Несколько поисков в одном запросе
Выполните несколько поисков одновременно (например, основной результат + подсказки):
let multiResults = try await client.multiSearch(
searches: [
// Основной поиск
MultiSearchQuery(
q: "nike",
queryBy: "name,description",
perPage: 20,
facetBy: "brand,category"
),
// Быстрые подсказки
MultiSearchQuery(
q: "nike",
queryBy: "name",
perPage: 5,
includeFields: "id,name"
),
]
)
let mainResults = multiResults.results[0]
let suggestions = multiResults.results[1]
print("Основных результатов: \(mainResults.found)")
print("Подсказок: \(suggestions.found)")Управление индексом (серверная сторона)
Если используете администратор ский ключ (aa_admin_*), можете управлять индексом:
// Создать индекс
let index = try await client.createIndex(
slug: "products",
displayName: "Products",
fields: [
IndexFieldDefinition(name: "name", type: "string"),
IndexFieldDefinition(name: "price", type: "float", facet: true),
IndexFieldDefinition(name: "brand", type: "string", facet: true),
]
)
// Добавить товар
try await client.upsertDocument(
indexSlug: "products",
documentId: "doc_001",
document: [
"name": "Nike Air Max",
"price": 129.99,
"brand": "Nike",
]
)
// Пакетное добавление товаров
try await client.batchUpsertDocuments(
indexSlug: "products",
documents: [
("doc_002", ["name": "Adidas Boost", "price": 149.99, "brand": "Adidas"]),
("doc_003", ["name": "Puma RS-X", "price": 99.99, "brand": "Puma"]),
]
)Синонимы и курации
// Добавить синонимы
try await client.upsertSynonyms(
indexSlug: "products",
synonyms: [
Synonym(root: "shoe", replacements: ["sneaker", "trainer", "кроссовка"]),
Synonym(root: "shirt", replacements: ["t-shirt", "top"]),
]
)
// Закрепить товар в результатах
try await client.upsertCurations(
indexSlug: "products",
curations: [
Curation(query: "best shoes", pinnedIds: ["doc_bestseller_001"]),
]
)Обработка ошибок
do {
let results = try await client.search(
indexSlug: "products",
query: "shoes"
)
} catch let error as AacsearchError {
switch error.code {
case "unauthorized":
print("Ошибка: неверный API-ключ")
case "rate_limit_exceeded":
print("Превышен лимит запросов, повторите позже")
case "index_not_found":
print("Индекс не найден")
default:
print("Ошибка: \(error.message)")
}
} catch {
print("Неожиданная ошибка: \(error)")
}Асинхронное программирование
SDK полностью поддерживает Swift async/await:
// В SwiftUI View
@State private var results: SearchResults?
@State private var isLoading = false
@State private var error: Error?
var body: some View {
VStack {
if isLoading {
ProgressView()
} else if let error = error {
Text("Ошибка: \(error.localizedDescription)")
} else if let results = results {
List(results.hits, id: \.document) { hit in
Text(hit.document["name"] as? String ?? "")
}
}
}
.task {
await performSearch()
}
}
private func performSearch() async {
isLoading = true
do {
results = try await client.search(
indexSlug: "products",
query: "shoes"
)
} catch {
self.error = error
}
isLoading = false
}Безопасность ключей
- Ключи поиска (
ss_search_*) — безопасны для использования в приложении - Административные ключи (
aa_admin_*) — используйте только на сервере, не встраивайте в приложение - Для управления индексом на стороне сервера создавайте бэкенд API
- Отозвите скомпрометированный ключ в панели управления AACsearch
Ruby SDK
Установка и использование гема aacsearch-ruby для поиска, управления индексами, синонимами, курированием и аналитикой.
Рецепты
Готовые "копировать-вставить" рецепты для самых частых паттернов AACsearch SDK — автокомплит, фасетный поиск, листинги товаров, трекинг кликов, scoped токены, мульти-аренда, мульти-локали и graceful failure.