Интеграция для iOS

Как интегрировать SDK в ваше iOS-приложение.

Особенности SDK

  • Не добавляет транзитивные зависимости.

  • Не требует обязательных дополнительных разрешений приложения.

    Единственное опциональное разрешение, которое может понадобиться — если хотите, чтобы для определения страны устройства SDK мог использовать данные GPS, у приложения должен быть доступ к геолокации. Если доступа нет, вместо GPS SDK будет использовать таймзону.

Требования

  • iOS 15+

SDK собран с использованием Xcode 26.5 и Swift 6.3. Если в вашем проекте используется другая версия Xcode или Swift, проверьте интеграцию на тестовой сборке.

Состав сборки

В поставку iOS SDK входит:

  • SPURLSession-1.1.0.xcframework — фреймворк Servicepipe SDK;

  • integration_guide.md — краткая инструкция по подключению.

SPURLSession-1.1.0.xcframework содержит сборки для:

  • реальных iOS-устройств: ios-arm64;

  • iOS Simulator: ios-arm64_x86_64-simulator.

Интеграция

1. Добавьте фреймворк в проект

Перетащите SPURLSession-1.1.0.xcframework в навигатор Xcode.

В настройках target откройте: GeneralFrameworks, Libraries, and Embedded Content. Убедитесь, что фреймворк добавлен в список, и выставьте для него режим: Embed & Sign. Режим нужен, чтобы Xcode встроил фреймворк в приложение и подписал его вместе с app bundle. Без этого приложение может не запуститься на устройстве или не пройти проверку подписи.

2. Подключите SDK в коде

В файлах, где выполняются защищаемые сетевые запросы (то есть запросы к ресурсу, который защищает Servicepipe), импортируйте SDK:

import SPURLSessionFramework

3. Замените URLSession на SPURLSession

В защищаемых сетевых взаимодействиях замените использование URLSession на SPURLSession.

Например, измените вызовы вида:

let (data, _) = try await URLSession(
    configuration: URLSessionConfiguration.default
).data(for: request)

На вызовы вида:

let (data, _) = try await SPURLSession(
    configuration: URLSessionConfiguration.default
).data(for: request)

SPURLSession — это сетевой клиент Servicepipe SDK с интерфейсом, идентичным URLSession. Он поддерживает dataTask, uploadTask, downloadTask, async-запросы и работу с delegate. Особенность в том, что помимо функционала URLSession он может обрабатывать служебную логику Servicepipe:

  • добавляет к запросам служебные cookies Servicepipe;

  • считывает и сохраняет Set-Cookie, которые передала в ответе система защиты;

  • если система защиты выдала CAPTCHA или JS-челлендж, обрабатывает этот сценарий и отображает проверку внутри приложения;

  • (если вы это включили) отправляет приложению события CAPTCHA: одно, когда CAPTCHA-проверка началась, второе — когда пользователь успешно её прошёл;

  • определяет страну устройства и локальные признаки VPN, а также передаёт эти данные вашему приложению локально (приложение должно вызывать API SDK) или добавляет их к запросу в виде HTTP-заголовков (передачу заголовков вы настраиваете сами в ходе интеграции SDK).

Логика обработки запроса и ответа в приложении при этом остаётся такой же, как при использовании URLSession.

4. Настройте отображение антибот-проверок

SDK может отображать CAPTCHA и JS-челлендж в двух режимах:

  • fullScreen — на весь экран.

  • windowed — в окне поверх приложения.

По умолчанию используется windowed со следующими параметрами:

width: 360
height: 640
cornerRadius: 48
backgroundColor: UIColor.black.withAlphaComponent(0.3)

Вы можете поменять настройки через setCaptchaPresentationMode.

Чтобы отображать проверки на весь экран, задайте:

SPURLSession.setCaptchaPresentationMode(
    captchaPresentationMode: .fullScreen
)

Чтобы отображать проверки в окне с заданными параметрами:

let captchaPresentationMode = CaptchaPresentationMode.windowed(
    width: 320,
    height: 560,
    cornerRadius: 24,
    backgroundColor: UIColor.black.withAlphaComponent(0.4)
)


SPURLSession.setCaptchaPresentationMode(
    captchaPresentationMode: captchaPresentationMode
)

Доступные режимы описаны в CaptchaPresentationMode:

public enum CaptchaPresentationMode {
    case fullScreen
    case windowed(
        width: CGFloat = 360,
        height: CGFloat = 640,
        cornerRadius: CGFloat = 48,
        backgroundColor: UIColor = UIColor.black.withAlphaComponent(0.3)
    )
}

Также можно кастомизировать CAPTCHA (делается вне вашего приложения):

  • установить другой вид CAPTCHA — по умолчанию используется с поворотом картинки, но можем поставить вместо другие: где нужно вводить символы либо ставить галочку в чекбокс;

  • использовать в CAPTCHA присланные вами картинки;

  • сделать страницу CAPTCHA в вашем корпоративном стиле.

Как это сделать, описано в статьях 403 и CAPTCHA с вашим дизайном и CAPTCHA с вашими картинками.

5. (Опционально) настройте отслеживание состояния CAPTCHA

Если приложению нужно знать, что пользователь начал проходить CAPTCHA или успешно её прошёл, подпишитесь на события CAPTCHA:

let session = SPURLSession(
    configuration: URLSessionConfiguration.default,
    delegate: delegate,
    delegateQueue: nil
)

session.setDidCaptchaStatusChanged { status in
    print("CAPTCHA STATUS: \(status.status) IP: \(status.ip) ID: \(status.requestId)")
}

SDK отправляет событие, когда CAPTCHA-проверка началась, и ещё одно, если она успешно пройдена. В событии передаются статус, IP и ID запроса.

6. (Опционально) настройте получение страны и VPN-признаков

SDK может определить страну, где находится устройство, и локальные признаки VPN. Эти данные ваше приложение может получить через API SDK либо их можно передать на ваш сервер в HTTP-заголовках.

Получить данные в приложении

Чтобы получить страну устройства, вызовите:

let countryCodes = await SPURLSession.countryCodes()

SDK вернёт массив CountryCode. Каждый элемент содержит код страны (ISO 3166-1 alpha-2) и источник, по которому SDK его определил. Например: countryCode: "ru", source: .GPS или countryCode: "de", source: .TIMEZONE.

Чтобы SDK использовал GPS для определения страны, у приложения должен быть доступ к геолокации. Если его нет, страна будет определяться только по таймзоне.

Чтобы получить признаки VPN, вызовите:

let vpnSigns = SPURLSession.vpnSigns()

SDK вернёт список найденных VPN-признаков. Для каждого признака доступны описание, тип и уровень уверенности.

Передать данные на сервер

SDK может добавлять к запросам приложения HTTP-заголовки с информацией о стране устройства и VPN-признаках. Чтобы включить эту механику, используйте:

SPURLSession.setSendVpnHeaders(vpnHeadersEnabled: true)

После этого SDK будет добавлять к запросам HTTP-заголовки x-cybert-mobile-country-code и x-cybert-mobile-vpn-signs, например:

x-cybert-mobile-country-code: ru
x-cybert-mobile-vpn-signs: direct_sign_1,indirect_sign_1
x-cybert-mobile-vpn-signs отправляется, только если SDK нашёл признаки VPN. Если признаков нет, заголовка не будет.

7. Добавьте feature toggle

Наш SDK тщательно протестирован, но на первое время всё равно рекомендуем включать его через feature toggle. Так вы сможете сначала включить SDK для части пользователей и убедиться, что всё работает штатно, а если возникнут проблемы — быстро отключить его без выпуска новой версии приложения.

Это обычная практика для мобильных приложений, когда в них добавляют новый сетевой компонент. Пример ниже показывает общий принцип подключения через feature toggle.

YourFeatureFlags.servicepipeIntegrationEnabled() — условный пример: такого API нет в Servicepipe SDK. Замените этот вызов на ваш механизм remote config, feature flags или A/B-тестирования.

// Пример: замените на ваш механизм feature toggle / remote config / A/B testing.
let servicepipeIntegrationEnabled = YourFeatureFlags.servicepipeIntegrationEnabled()
let (data, response) = if servicepipeIntegrationEnabled {
    try await SPURLSession(
        configuration: URLSessionConfiguration.default,
        delegate: delegate,
        delegateQueue: nil
    ).data(for: request)
} else {
    try await URLSession(
        configuration: URLSessionConfiguration.default,
        delegate: delegate,
        delegateQueue: nil
    ).data(for: request)
}

8. Протестируйте интеграцию

После подключения SDK проверьте, что приложение работает как раньше:

  1. Запустите приложение с подключённым SDK.

  2. Пройдите основные сценарии, где приложение обращается к API: например, авторизацию, загрузку данных, отправку формы или оформление заказа.

  3. Убедитесь, что запросы выполняются успешно, ответы API обрабатываются как раньше и пользовательские сценарии завершаются без ошибок.

  4. Если включили передачу информации о стране устройства или VPN:

    • напрямую приложению, через API SDK — проверьте на тестовой сборке, что приложение получило нужные данные;

    • на сервер, в HTTP-заголовках — сначала проверьте на тестовой сборке, что запросы содержат x-cybert-mobile-country-code, затем включите VPN и проверьте, что появился x-cybert-mobile-vpn-signs.

Затем проверьте, что SDK корректно обрабатывает CAPTCHA. Для этого выполните из приложения запрос к тестовому URL с помощью SPURLSession:

https://servicepipe.ru/F2xN8dM3sPqK6aZt

Если SDK подключён корректно, приложение отобразит CAPTCHA внутри WKWebView. Если пройти её успешно, тестовый URL вернёт ответ 404. При повторных запросах CAPTCHA уже не будет показываться, потому что SDK получит «разрешающую» cookie от системы защиты и будет добавлять её в запросы. Когда срок жизни этой cookie истечёт либо хранилище cookies будет очищено путём переустановки приложения, URL снова будет выдавать CAPTCHA.

9. Интеграция завершена

Поздравляем, вы подключили Servicepipe iOS SDK! Теперь он помогает защищать ваше приложение от эксплуатации автоматизациями.