Подробная инстуркция по конфигурации и настройке SDK от Travelpayouts для iOS.
Конфигурация - самый важный этап при работе с данным SDK, который позволяет:
- Задать значение важных констант (Ключи API, различные ссылки и т.д.);
- Персонализировать внешний вид экранов;
- Настроить показ рекламы внутри SDK;
- Настроить отправку аналитики на ваши ресурсы.
Обратите внимание! Перед конфигурацией нужно подключить SDK к вашему проекту.
Подключение SDK к вашему проекту
Для подключения SDK к вашему проекту необходимо модифицировать ваш Podfile следующим образом:
- Включите сборку зависимостей в отдельные фреймворки:
use_frameworks!
- В коде постобработчика задайте настройку BUILD_LIBRARY_FOR_DISTRIBUTION = YES, для зависимостей:
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '14.0'
config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'
end
end
end
Подключение модулей
- Авиабилеты: pod 'WLSDK/Flights'
- Бронирование отелей: pod 'WLSDK/Hotels'
- Модуль с информацией и настройками: pod 'WLSDK/Information'
Пример Podfile
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '14.0'
target 'MyApplication' do
pod 'WLSDK/Hotels', '1.2.0'
pod 'WLSDK/Flights', '1.2.0'
end
# Various post-install hooks
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '14.0'
config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'
end
end
end
Конфигурация SDK
Первым шагом нужно создать модель, которая будет передавать SDK параметры внешнего вида. Подробнее о данном этапе расписано в разделе Конфигурация внешнего вида.
После создания модели AppearanceConfiguration можно приступать к заполнению конфигурации SDK. Для этого необходимо создать новый экземпляр Configuration и заполнить его.
Пример заполнения:
```
let configuration = Configuration(
appearance: Appearance(),
constants: Configuration.Constants(
marker: "<marker>",
clientDeviceHost: "<client_device_host>",
apiKey: "<api_key>",
appStoreId: "<appstore_id>",
privacyUrl: LocalizedUrlContainer(
fallback: "https://www.google.com",
storage: [
"en": "https://www.google.com",
"ru": "https://www.google.ru",
]
),
feedbackEmail: "test@test.com",
sharingData: SharingData(
sharingLink: "https://www.google.ru"
)
)
)
```
Параметры:
-
marker – укажите ваш партнёрский маркер. Его можно скопировать на странице White Label App в личном кабинете Travelpayouts:
- clientDeviceHost – идентификатор СlientDeviceHost;
-
apiKey – укажите ваш API токен. Его также можно найти на странице White Label App в личном кабинете Travelpayouts:
- appStoreId – ID вашего приложения в AppStore;
-
privacyUrl – ссылка на политику конфиденциальности, при этом:
- fallback – эта ссылка будет открываться по умолчанию, если не указана отдельная ссылка на язык, выбранный пользователем в приложении;
- storage – здесь указываются ссылки на политики конфиденциальности на разных языках.
- feedbackEmail – электронная почта для обратной связи;
- sharingLink – ссылка, которая будет копироваться при нажатии на кнопку «Поделиться».
При необходимости вы можете произвести конфигурацию опциональных компонентов:
- Конфигурация показа рекламы внутри экранов SDK
- Конфигурация аналитики
- Замена текстовых строк на экранах
- Замена изображений на экранах
После заполнения конфигурации ее можно применить вызовом метода Configuration/setup(with:). Пример:
```
Configuration.setup(with: configuration)
```
Важно: Конфигурацию SDK необходимо производить непосредственно на старте приложения, с самым высоким приоритетом!
Экран поиска авиабилетов
Для получения экрана поиска авиабилетов воспользуйтесь следующим выражением:
```
import WLFlights
...
let viewController = WLFlights.ScreenProvider.shared.flightsViewController
```
Полученный объект UIViewController можно показать любым удобным для вас способом.
Обратите внимание! Стоит учитывыть, что данный экран содержит внутри себя UINavigationController.
Создание собственного экрана поиска авиабилетов
Вы можете самостоятельно написать свой собственный стартовый экран поиска авиабилетов. Для этого в SDK предусмотрен функционал для вызова экрана результатов поиска, а также экранов для выбора параметров поиска. Все дополнительные экраны можно вызвать через WLFlightsUnlimited.ScreenProvider.shared.
Экраны для выбора параметров поиска
Чтобы запустить поиск авиабилетов, в первую очередь нужно получить все необходимые параметры. Для этого мы предоставили доступ к следующим экранам:
- Экран FlightsLocations. Для получения воспользуйтесь следующим выражением:
import WLFlightsUnlimited
...
let screenProvider = WLFlightsUnlimited.ScreenProvider.shared
var originLocationsSelection: FlightsLocationsSelection?
...
let controller = screenProvider.flightsLocationsViewController(
type: .origin // Тип вызываемого экрана (.origin или .destination)
) { [weak self] selection in
guard let self else { return }
originLocationsSelection = selection // Сохранение выбранного значения
}
Через замыкание onFinish экран передаст вам выбранное пользователем значение типа FlightsLocationsSelection.
Чтобы отобразить выбранное значение на стартовом экране, воспользуйтесь свойствами name, cityName и countryName или же свойствами title и attibutedTitle c отформатированными и локализованными значениями.
Также необходимо создать аналогичный экран с типом .destination для выбора параметра места прибытия.
- Экран FlightsCalendar
Для получения экрана FlightsCalendar воспользуйтесь следующим выражением:
import WLFlightsUnlimited
...
let screenProvider = WLFlightsUnlimited.ScreenProvider.shared
var calendarSelection: FlightsCalendarSelection?
...
let controller = screenProvider.flightsCalendarViewController(
currentSelection: calendarSelection, // Текущее выбранное значение
originLocationsSelection: originLocationsSelection, // Текущее выбранное место отправления
destinationLocationsSelection: destinationLocationsSelection // Текущее выбранное место прибытия
) { [weak self] selection in
guard let self else { return }
calendarSelection = selection // Сохранение выбранного значения
}
Через замыкание onFinish экран передаст вам выбранное юзером значение типа FlightsCalendarSelection.
Чтобы отобразить выбранное значение на стартовом экране, воспользуйтесь свойствами departureDate, returnDate или же методом title, который вернет отформатированное локализованное значение.
- Экран FlightsPassengers
Для получения экрана FlightsPassengers воспользуйтесь следующим выражением:
import WLFlightsUnlimited
...
let screenProvider = WLFlightsUnlimited.ScreenProvider.shared
var passengersSelection: FlightsPassengersSelection = .default // Вы можете задать значение по умолчанию
...
let controller = screenProvider.flightsPassengersViewController(
currentSelection: passengersSelection // Текущее выбранное значение
) { [weak self] selection in
guard let self else { return }
if let selection {
passengersSelection = selection // Сохранение выбранного значения
}
}
Через замыкание onFinish экран передаст вам выбранное юзером значение типа FlightsPassengersSelection.
Для того, чтобы отобразить выбранное значение на стартовом экране, воспользуйтесь свойствами adultsCount, childrenCount, childrenAges или же свойством title с отформатированным и локализованным значением.
Экран результатов поиска
Когда все параметры поиска готовы, можно переходить к созданию экрана результатов поиска:
import WLFlightsUnlimited
...
let screenProvider = WLFlightsUnlimited.ScreenProvider.shared
var originLocationsSelection: FlightsLocationsSelection?
var destinationLocationsSelection: FlightsLocationsSelection?
var calendarSelection: FlightsCalendarSelection?
var guestsSelection: FlightsGuestsSelection = .default // Вы можете задать значение по умолчанию
...
guard
let originLocationsSelection,
let destinationLocationsSelection,
let calendarSelection,
originLocationsSelection != destinationLocationsSelection // Место отправления и место прибытия не должны быть одинаковыми
else { return }
let controller = screenProvider.flightsResultsViewController(
parameters: .init(
originSelection: originLocationsSelection, // Выбранное место отправления
destinationSelection: destinationLocationsSelection, // Выбранное место прибытия
calendarSelection: calendarSelection, // Выбранные даты
guestsSelection: guestsSelection // Выбранные пассажиры
)
)
Важная информация по отображению созданных контроллеров
Все перечисленные контроллеры содержат внутри себя UINavigationController. Поэтому мы настоятельно рекомендуем показывать эти экраны модально через метод present.
Для экранов выбора параметров поиска предусмотрен специальный "grabber" для закрытия, поэтому не рекомендуется использовать полноэкранный modalPresentationStyle, так как пользователь не сможет закрыть экран.
На экране результатов поиска предусмотрена кнопка для его закрытия, поэтому для удобства пользователя рекомендуется использовать modalPresentationStyle с параметром .fullScreen.
Экран поиска отелей
Для получения экрана поиска отелей воспользуйтесь следующим выражением
```
import WLHotels
...
let viewController = WLHotels.ScreenProvider.shared.hotelsViewController
```
Полученный объект UIViewController можно показать любым удобным для вас способом.
Обратите внимание! Стоит учитывыть, что данный экран содержит внутри себя UINavigationController.
Создание собственного экрана поиска отелей
Вы можете самостоятельно написать свой собственный стартовый экран поиска отелей. Для этого в SDK предусмотрен функционал для вызова экрана результатов поиска, а также экранов для выбора параметров поиска. Все дополнительные экраны можно вызвать через WLHotelsUnlimited.ScreenProvider.shared.
Экраны для выбора параметров поиска
Чтобы запустить поиск отелей, в первую очередь нужно получить все необходимые параметры. Для этого мы предоставили доступ к следующим экранам:
- Экран HotelsLocations. Для получения воспользуйтесь следующим выражением:
import WLHotelsUnlimited
...
let screenProvider = WLHotelsUnlimited.ScreenProvider.shared
var originLocationsSelection: HotelsLocationsSelection?
...
let controller = screenProvider.hotelsLocationsViewController() { [weak self] selection in
guard let self else { return }
locationsSelection = selection // Сохранение выбранного значения
}
Через замыкание onFinish экран передаст вам выбранное юзером значение типа HotelsLocationsSelection.
Чтобы отобразить выбранное значение на стартовом экране, воспользуйтесь свойством title, который вернет отформатированное значение.
- Экран HotelsCalendar. Для получения воспользуйтесь следующим выражением:
import WLHotelsUnlimited
...
let screenProvider = WLHotelsUnlimited.ScreenProvider.shared
var calendarSelection: HotelsCalendarSelection?
...
let controller = screenProvider.hotelsCalendarViewController(
currentSelection: calendarSelection, // Текущее выбранное значение
) { [weak self] selection in
guard let self else { return }
calendarSelection = selection // Сохранение выбранного значения
}
Через замыкание onFinish экран передаст вам выбранное юзером значение типа HotelsCalendarSelection.
Чтобы отобразить выбранное значение на стартовом экране, воспользуйтесь свойством range или же методом title, который вернет отформатированное локализованное значение.
- Экран HotelsGuests. Для получения воспользуйтесь следующим выражением:
import WLHotelsUnlimited
...
let screenProvider = WLHotelsUnlimited.ScreenProvider.shared
var guestsSelection: HotelsGuestsSelection = .default // Вы можете задать значение по умолчанию
...
let controller = screenProvider.hotelsGuestsViewController(
currentSelection: guestsSelection // Текущее выбранное значение
) { [weak self] selection in
guard let self else { return }
if let selection {
guestsSelection = selection // Сохранение выбранного значения
}
}
Через замыкание onFinish экран передаст вам выбранное юзером значение типа HotelsGuestsSelection.
Чтобы отобразить выбранное значение на стартовом экране, воспользуйтесь свойствами adultsCount, childrenCount, infantsCount, tripClass или же свойством title с отформатированным и локализованным значением.
Экран результатов поиска
Когда все параметры поиска готовы, можно переходить к созданию экрана результатов поиска:
import WLHotelsUnlimited
...
let screenProvider = WLHotelsUnlimited.ScreenProvider.shared
private var locationsSelection: HotelsLocationsSelection?
private var calendarSelection: HotelsCalendarSelection?
private var guestsSelection: HotelsGuestsSelection = .default
...
guard
let locationsSelection,
let calendarSelection
else { return }
let controller = WLHotelsUnlimited.ScreenProvider.shared.hotelsResultsViewController(
parameters: .init(
locationsSelection: locationsSelection, // Выбранное место
calendarSelection: calendarSelection, // Выбранные даты
guestsSelection: guestsSelection // Выбранные гости
)
)
Важная информация по отображению созданных контроллеров
Все перечисленные контроллеры содержат внутри себя UINavigationController. Поэтому мы настоятельно рекомендуем показывать данные экраны модально с помощью метода present.
Для экранов выбора параметров поиска предусмотрен специальный "grabber" для закрытия, поэтому не рекомендуется использовать полноэкранный modalPresentationStyle, так как пользователь не сможет закрыть экран.
На экране результатов поиска предусмотрена кнопка для его закрытия, поэтому для удобства пользователя рекомендуется использовать modalPresentationStyle с параметром .fullScreen.
Экран информации
Для показа данного экрана необходимо создать и заполнить объект конфигурации InformationScreenConfiguration:
```
let informationScreenConfiguration = InformationScreenConfiguration(
optionalItemsToDisplay: [.favorites] // опциональные элементы, которые нужно показать на этом экране
aboutAppInformation: AboutAppInformation(
description: LocalizedStringContainer(
fallback: "Application description",
storage: [
"ru": "Описание приложения"
]
),
developer: LocalizedStringContainer(
fallback: NSLocalizedString("developer_info", comment: ""), // Вариант с использованием NSLocalizedString
storage: [:]
),
partnerUrl: LocalizedUrlContainer(
fallback: "https://google.com",
storage: [
"ru": "https://yandex.ru"
]
)
)
)
```
Параметры
- optionalItemsToDisplay –- массив опциональных элементов интерфейса, которые необходимо показать на экране.
- aboutAppInformation — конфигурация, содержащая информацию о разработчике, описание приложения и партнерскую ссылку.
Для получения экрана информации воспользуйтесь следующим выражением:
```
import WLInformation
...
let viewController = WLInformation.ScreenProvider.shared.informationViewController(
informationScreenConfiguration: informationScreenConfiguration
)
```
Полученный объект UIViewController можно показать любым удобным для вас способом.
Обратите внимание! Стоит учитывыть, что данный экран содержит внутри себя UINavigationController.
Конфигурация аналитики
Для подключения аналитики необходимо создать объект реализующий протокол AnalyticsProvider.
Пример объекта:
```
swift
final class MyAnalyticsProvider: AnalyticsProvider {
// MARK: - Internal methods
func log(event: String, with parameters: [String: Any]?) {
// Логика отправки события в вашу систему аналитики
}
}
```
Далее необходимо создать объект Configuration/Analytics-swift.struct и передать его в конструктор конфигурации Configuration/init(appearance:constants:advertising:analytics:).
Пример конфигурации
```
let configuration = Configuration(
appearance: Appearance(),
constants: Configuration.Constants(
marker: "<marker>",
clientDeviceHost: "<client_device_host>",
apiKey: "<api_key>",
appStoreId: "<appstore_id>",
privacyUrl: LocalizedUrlContainer(
fallback: "https://www.google.com",
storage: [
"en": "https://www.google.com",
"ru": "https://www.google.ru",
]
),
feedbackEmail: "test@test.com",
sharingData: SharingData(
sharingLink: "https://www.google.ru"
)
),
advertising: nil,
analytics: .init(
analyticsProvider: MyAnalyticsProvider()
)
)
```
Замена текстовых строк на экранах
В SDK присутствует возможность заменять текстовые строки на экранах. Замена осуществляется при помощи механизма Configuration/localization-swift.property внутри конфигурации Configuration.
По умолчанию, параметр Configuration/localization-swift.property не содержит каких-либо открытых интерфейсов. Но они добавляются при подключении модулей WLFlights и/или WLHotels и/или WLInformation.
WLFlights
После добавления этого модуля станет доступным перечисление:
```
public enum WLFlights.LocalizationTable: String, Hashable, CaseIterable {
case flightBooking
case flightDetails
case flightProposals
case flightsAirports
case flightsCalendar
case flightsCommon
case flightsFavorites
case flightsFilters
case flightsFiltersAgents
case flightsFiltersAirlines
case flightsFiltersAirports
case flightsFiltersSorting
case flightsFiltersTransfersAirports
case flightsLayoverInfo
case flightsPassengers
case flightsPlurals
case flightsPriceCharts
case flightsResults
case flightsSearch
case flightsTransferTags
}
```
И дополнительный метод у Configuration/localization-swift.property:
```
public extension Configuration.Localization {
func register(
bundle: Bundle,
flightsTable table: WLFlights.LocalizationTable,
overriddenTableName: String? = nil
)
}
```
Параметры
- bundle – bundle, в котором располагается строковая таблица, которую необходимо зарегистрировать.
- flightsTable – один из вариантов WLFlights.LocalizationTable, таблица из модуля WLFlights, в которой нужно заменить строки.
- overriddenTableName – название строковой таблицы внутри бандла bundle.
Пример замены можно посмотреть ниже.
WLHotels
После добавления этого модуля станет доступным перечисление:
```
public enum WLHotels.LocalizationTable: String, Hashable, CaseIterable {
case hotelBooking
case hotelDetails
case hotelPropertyTypes
case hotelProposalOptions
case hotelRooms
case hotelRoomsFilters
case hotelsCalendar
case hotelsFavorites
case hotelsFilterSearch
case hotelsFilters
case hotelsGuestsSelection
case hotelsLocations
case hotelsMap
case hotelsMapLocationPicker
case hotelsPhotosPreview
case hotelsPlurals
case hotelsResults
case hotelsReviews
case hotelsSearch
case hotelsSorting
}
```
И дополнительный метод у Configuration/localization-swift.property:
```
public extension Configuration.Localization {
func register(
bundle: Bundle,
hotelsTable table: WLHotels.LocalizationTable,
overriddenTableName: String? = nil
)
}
```
Параметры
- term bundle – bundle, в котором располагается строковая таблица, которую необходимо зарегистрировать.
- term hotelsTable – один из вариантов WLHotels.LocalizationTable, таблица из модуля WLHotels, в которой нужно заменить строки.
- term overriddenTableName – название строковой таблицы внутри бандла bundle.
Пример замены можно посмотреть ниже.
WLInformation
После добавления этого модуля станет доступным перечисление:
```
public enum WLInformation.LocalizationTable: String, Hashable, CaseIterable {
case informationAboutApp
case informationConfidentiality
case informationCountryPicker
case informationCurrencyPicker
case informationDefaultCurrency
case informationFavourites
case informationMain
case informationPriceDisplay
case informationRegionalSettings
}
```
И дополнительный метод у Configuration/localization-swift.property:
```
public extension Configuration.Localization {
func register(
bundle: Bundle,
informationTable table: WLInformation.LocalizationTable,
overriddenTableName: String? = nil
)
}
```
Параметры
- term bundle – bundle, в котором располагается строковая таблица, которую необходимо зарегистрировать.
- term informationTable – один из вариантов WLInformation.LocalizationTable, таблица из модуля`WLInformation, в которой нужно заменить строки.
- term overriddenTableName – название строковой таблицы внутри бандла bundle.
Пример замены можно посмотреть ниже.
Пример замены
Обратите внимание! Код описанный ниже использует доступ к конфигурации через Configuration/current. Это допустимо только после вызова Configuration/setup(with:.
1. Добавьте новую строковую таблицу в проект и назовите её MyFlightsSearchStrings.strings.
2. Пропишите в ней ключ, который нужно заменить:
```
"departure_airport_placeholder" = "Аэропорт вылета";
```
3. Зарегистрируйте созданную таблицу в Configuration/localization-swift.property:
```
import WLConfig
import WLFlights // Подключаем модуль поиска билетов
...
Configuration.current.localization.register(
bundle: .main, // Бандл в котором располагается MyFlightsSearchStrings
flightsTable: .flightsSearch, // Таблица SDK ключи которой мы хотим заменить
overriddenTableName: "MyFlightsSearchStrings" // Название таблицы
)
```
Замена строк в других модулях (Отели, Информация) происходит аналогично.
Замена изображений на экранах
В SDK присутствует возможность заменять изображения на некоторых экранах. Замена осуществляется при помощи механизма Configuration/imagesProvider-swift.property внутри конфигурации Configuration.
По умолчанию, параметр Configuration/imagesProvider-swift.property не содержит каких-либо открытых интерфейсов. Но они добавляются при подключении модулей WLFlights и/или WLHotels.
WLFlights
После добавления этого модуля станет доступным следующее перечисление:
```
public enum FlightsImageSink: ImageSink {
/// Фон экрана поиска авиабилетов
case searchScreenBackground
}
```
И дополнительный метод у Configuration/imagesProvider-swift.property:
```
public extension Configuration.ImagesProvider {
func register(
source: ImageSource,
forFlightsSink sink: FlightsImageSink
)
}
```
Параметры
- term source — (Configuration/ImagesProvider-swift.class/ImageSource) источник изображения, которое необходимо поставить на то или иное место в SDK.
- term sink — приемник изображения в модуле WLFlights.
WLHotels
По аналогии с модулем поиска авиабилетов, после добавления модуля WLHotels станет доступным следующее перечисление:
```
public enum HotelsImageSink: ImageSink {
/// Фон экрана поиска отелей
case searchScreenBackground
}
```
И дополнительный метод у Configuration/imagesProvider-swift.property:
```
public extension Configuration.ImagesProvider {
func register(
source: ImageSource,
forHotelsSink sink: HotelsImageSink
)
}
```
Параметры
- source — (Configuration/ImagesProvider-swift.class/ImageSource) источник изображения, которое необходимо поставить на то или иное место в SDK.
- sink — Приемник изображения в модуле WLHotels.
Пример замены изображений
Обратите внимание! Код описанный ниже использует доступ к конфигурации через Configuration/current. Это допустимо только после вызова Configuration/setup(with:).
```
import WLConfig
import WLFlights // Подключаем модуль поиска авиабилетов
import WLHotels // Подключаем модуль поиска отелей
...
Configuration.current.imagesProvider.register(
source: .local(
bundle: .main, // Бандл в котором располагается ресурс my_plane_image
key: "my_plane_image", // Ключ ресурса
configuration: nil // Конфигурация UIImage
),
forFlightsSink: .searchScreenBackground
)
Configuration.current.imagesProvider.register(
source: .local(
bundle: .main, // Бандл в котором располагается ресурс my_hotel_image
key: "my_hotel_image", // Ключ ресурса
configuration: nil // Конфигурация UIImage
),
forHotelsSink: .searchScreenBackground
)
```
Конфигурация показа рекламы внутри экранов SDK
Для подключения рекламы:
1. Создайте объект, реализующий протокол AdvertisingProvider.
Пример объекта:
```
final class MyAdvertisingProvider: AdvertisingProvider {
// MARK: - Private properties
private var bannerCompletions = [UIView: AdvertisingProviderBannerCompletion]()
// MARK: - Internal methods
func bannerView(for placement: String, complition: @escaping AdvertisingProviderBannerCompletion) {
// Логика получения и показа `UIView` баннерной рекламы с ID плейсмента `placement`.
// В `complition` передается `UIView` c баннерной рекламой или ошибка c типом `Error`.
}
func showInterstitial(for placement: String, in context: UIViewController)
// Логика получения и показа полноэкранной рекламы с ID плейсмента `placement` на экране `context`.
}
}
```
Обратите внимание! ID плейсментов, которые передаются в методы AdvertisingProvider берутся из параметра Configuration/Advertising-swift.struct конфигурации Configuration.
2. Создайте объект Configuration/Advertising-swift.struct и передайте его в конструктор конфигурации Configuration/init(appearance:constants:advertising:analytics:)
Пример конфигурации
```
let configuration = Configuration(
appearance: Appearance(),
constants: Configuration.Constants(
marker: "<marker>",
clientDeviceHost: "<client_device_host>",
apiKey: "<api_key>",
appStoreId: "<appstore_id>",
privacyUrl: LocalizedUrlContainer(
fallback: "https://www.google.com",
storage: [
"en": "https://www.google.com",
"ru": "https://www.google.ru",
]
),
feedbackEmail: "test@test.com",
sharingData: SharingData(
sharingLink: "https://www.google.ru"
)
),
advertising: Configuration.Advertising(
advertisingProvider: MyAdvertisingProvider(),
placements: .init(
flights: .init(
searchInterstitial: "FLIGHTS_FULLSCREEN_PLACEMENT_ID",
searchReslutsBanner: "FLIGHTS_BANNER_PLACEMENT_ID"
),
hotels: .init(
searchInterstitial: "HOTELS_FULLSCREEN_PLACEMENT_ID",
searchReslutsBanner: "HOTELS_BANNER_PLACEMENT_ID"
)
)
)
)
```
Конфигурация внешнего вида
Для настройки визуальной составляющей необходимо создать модель, которая будет передавать в SDK параметры внешнего вида.
Для этого создайте модель (класс или структуру) и подпишите её под протокол AppearanceConfiguration. XCode автоматически предложит вам добавить все необходимые поля.
Пример минимальной реализации модели:
```
struct Appearance: AppearanceConfiguration {
// MARK: - Internal properties
var baseColorVariant: ColorVariant? {
.hex("#7648C5")
}
var iconStyle: IconStyle {
.tint
}
var cornerStyle: CornerStyle {
.default
}
var palette: ColorPalette {
.lab
}
}
```
ColorPalette
Позволяет задать алгоритм для генерации цветовой палитры приложения. Можно использовать следующие варианты:
- hex — цветогенерация на основе цветового пространства HSV.
- lab — цветогенерация на основе цветового пространства Lab.
ColorVariant
Позволяет выбрать вариант задания цвета. Доступны следующие форматы:
- color — цвет в формате UIColor.
- hex — цвет в формате HEX.
IconStyle
Позволяет выбрать стиль отображения иконок внутри приложения. Доступны следующие варианты:
- filled — иконки с заливкой.
- lined — линейный стиль иконок.
- tint — тональный стиль иконок.
CornerStyle
Позволяет задать тип сгруглённости элементов. Можно использовать следующие варианты:
- default — стандартное скругление.
- round — сильное скругление.
- sharp — малое скругление.
Переопределение цвета
Чтобы переопределить цвета, используемые в SDK:
- Cоздайте модель, подписанную под протокол ColorSet.
- Переопределите необходимые цвета путём добавления соответствующих свойств с типом Color (список всех доступных для переопределения цветов можно посмотреть внутри протокола).
- В модель, реализующую протокол BaseVersionAppearanceConfiguration, добавьте свойство overriddenColors c типом ColorSet?. В качестве значения подставьте модель, созданную на первом шаге.
Пример добавления переопределённых цветов:
struct OverridenColors: ColorSet {
// MARK: - Internal properties
var overlay: Color {
.custom(UIColor.red)
}
}
struct Appearance: BaseVersionAppearanceConfiguration {
// MARK: - Internal properties
...
var overriddenColors: ColorSet? {
OverridenColors()
}
}
Переопределение иконок
Для того чтобы заменить иконки, вам нужно использовать протокол UnlimitedVersionAppearanceConfiguration вместо BaseVersionAppearanceConfiguration. Этот протокол содержит все те же самые свойства, а также дополнительное - overriddenIcons.
Чтобы переопределить иконки:
- Cоздайте модель, подписанную под протокол IconSet.
- В этой модели переопределите необходимые иконки, добавив соответствующие свойства с типом UIImage? Список всех доступных для переопределения иконок можно посмотреть внутри протокола IconSet.
- Добавьте свойство overriddenIcons c типом IconSet? в модель, реализующую протокол UnlimitedVersionAppearanceConfiguration, необходимо добавить свойство. В качестве значения подставьте модель, созданную на первом шаге.
Пример добавления переопределённых иконок:
struct OverridenIcons: IconSet {
// MARK: - Internal properties
var icTune: UIImage? {
UIImage.checkmark
}
}
struct Appearance: UnlimitedVersionAppearanceConfiguration {
// MARK: - Internal properties
...
var overriddenIcons: IconSet? {
OverridenIcons()
}
}