Функционал SDK
Предварительно вам необходимо настроить SDK для работы с вашим приложением. Подробная инструкция находится здесь
Работа со статусами подписки
Изменение статуса подписки
AltcraftSDK
// Singleton, the entry point to the SDK
└── static let shared: AltcraftSDK
// Push subscription managment
└── pushSubscriptionFunctions: PublicPushSubscriptionFunctions
// Subscribe (status = SUBSCRIBED)
├── pushSubscribe(
│ sync: Bool = true,
│ profileFields: [String: Any?]? = nil,
│ customFields: [String: Any?]? = nil,
│ cats: [CategoryData]? = nil,
│ replace: Bool? = nil,
│ skipTriggers: Bool? = nil
│ ): Void
// Unsubscribe (status = UNSUBSCRIBED)
├── pushUnSubscribe(
│ sync: Bool = true,
│ profileFields: [String: Any?]? = nil,
│ customFields: [String: Any?]? = nil,
│ cats: [CategoryData]? = nil,
│ replace: Bool? = nil,
│ skipTriggers: Bool? = nil
│ ): Void
// Suspend (status = SUSPENDED)
└── pushSuspend(
sync: Bool = true,
profileFields: [String: Any?]? = nil,
customFields: [String: Any?]? = nil,
cats: [CategoryData]? = nil,
replace: Bool? = nil,
skipTriggers: Bool? = nil
): Void
Функции изменения статуса подписки:
func pushSubscribe()— выполняет подписку на push-уведомления;func pushUnSubscribe()— отменяет подписку на push-уведомления;func pushSuspend()— приостанавливает подписку на push-уведомления (уведомления не приходят, но при этом не создается событие отписки в профиле пользователя);func unSuspendPushSubscription()— используется для созданияLogIn-,LogOut-переходов.
Функции этой группы имеют одинаковую сигнатуру, содержащую следующие параметры:
sync: Bool
По умолчанию: true
Обязательный: Нет
Описание: Флаг, устанавливающий синхронность выполнения запроса.
Успешное выполнение запроса:
В случае успешного выполнения запроса данной группы функций будет создано событие с кодом 230, содержащее значение event.value, определяемое в зависимости от флага синхронизации:
Если sync == true
ResponseWithHttpCode
├─ httpCode: 200
└─ response
├─ error: 0
├─ errorText: ""
└─ profile
├─ id: "your id"
├─ status: "subscribed"
├─ isTest: false
└─ subscription
├─ subscriptionId: "your subscriptionId"
├─ hashId: "c52b28d2"
├─ provider: "ios-apns"
├─ status: "subscribed"
├─ fields
│ ├─ _os_ver: {"raw":"18.6.2","ver":"[\"18.0\", \"6.0\", \"2.0\"]"}
│ ├─ _device_type: "Mobile"
│ ├─ _ad_track: false
│ ├─ _device_name: "iPhone"
│ ├─ _os_language: "en"
│ ├─ _os_tz: "+0300"
│ ├─ _os: "IOS"
│ └─ _device_model: "iPhone14,7"
└─ cats
└─ [ { name: "developer_news", title: "dev_news", steady: false, active: false } ]
При синхронном запросе в значении события event.value по ключу "response_with_http_code" доступны:
-
httpCode – транспортный код ответа;
-
Response – public struct, содержащий:
-
error: Int?— внутренний код ошибки сервера (0, если ошибок нет), -
errorText: String?— текст ошибки (пустая строка, если ошибок нет), -
profile: ProfileData?— данные профиля, если запрос успешный:- информация о профиле (ProfileData)
- подписка (SubscriptionData)
- категории подписки (CategoryData)
- если запрос завершился с ошибкой, то вернется только
profile = nil
-
Структуры данных
public struct Response {
let error: Int? // internal error code
let errorText: String? // error text
let profile: ProfileData?
}
public struct ProfileData {
let subscription: SubscriptionData?
let cats: [CategoryData]?
}
public struct SubscriptionData {
// Subscription Data
}
public struct CategoryData {
// Subscription Category Data
}
Если sync == false
ResponseWithHttpCode
├─ httpCode: Int?
└─ response: Response?
├─ error: Int?
├─ errorText: String?
└─ profile: ProfileData? = nil
При асинхронном запросе в значении события event.value по ключу "response_with_http_code" доступны:
-
httpCode – транспортный код ответа;
-
Response – public struct, содержащий:
error: Int?— внутренний код ошибки сервера (0, если ошибок нет),errorText: String?— текст ошибки (пустая строка, если ошибок нет),profile: ProfileData?— данные профиля, для асинхронного запроса всегда равенnil.
Выполнение запроса с ошибкой:
Если запрос данной группы функций завершился ошибкой, будет создано событие со следующими кодами:
- 430 – ошибка без автоматического повтора на стороне SDK;
- 530 – ошибка с автоматическим повтором на стороне SDK.
Содержимое события:
- только
httpCode, если сервер Altcraft был недоступен; errorиerrorText, если сервер вернул ошибку.
Получение значений событий push
AltcraftSDK.shared.eventSDKFunctions.subscribe { event in
if event.eventCode == 230 {
if let responseWithHttp = event.value?["response_with_http_code"] as? ResponseWithHttp {
// HTTP code
let httpCode = responseWithHttp.httpCode
// Response
let response = responseWithHttp.response
let error = response?.error
let errorText = response?.errorText
// Profile
let profile = response?.profile
let profileId = profile?.id
let profileStatus = profile?.status
let profileIsTest = profile?.isTest
// Subscription
let subscription = profile?.subscription
let subscriptionId = subscription?.subscriptionId
let hashId = subscription?.hashId
let provider = subscription?.provider
let subscriptionStatus = subscription?.status
// Fields (dictionary [String: JSONValue])
let fields = subscription?.fields
// Cats (array of CategoryData)
let cats = subscription?.cats
// CategoryData (every element of cats array)
let firstCat = cats?.first
let catName = firstCat?.name
let catTitle = firstCat?.title
let catSteady = firstCat?.steady
let catActive = firstCat?.active
}
}
}
Поля fields, содержащиеся в subscription могут содержать ваши пользовательские поля подписки. Они имеют тип [String: JSONValue]?. public enum JSONValue содержит вспомогательные функции позволяющие упростить получение значений fields:
public var stringValue: String? {
if case let .string(value) = self { return value }
return nil
}
/// Returns the numeric value if case is `.number`, otherwise `nil`.
public var numberValue: Double? {
if case let .number(value) = self { return value }
return nil
}
/// Returns the bool value if case is `.bool`, otherwise `nil`.
public var boolValue: Bool? {
if case let .bool(value) = self { return value }
return nil
}
/// Returns the object dictionary if case is `.object`, otherwise `nil`.
public var objectValue: [String: JSONValue]? {
if case let .object(value) = self { return value }
return nil
}
/// Returns the array if case is `.array`, otherwise `nil`.
public var arrayValue: [JSONValue]? {
if case let .array(value) = self { return value }
return nil
}
Пример получения значения поля field "_device_name":
AltcraftSDK.shared.eventSDKFunctions.subscribe { event ->
if event.eventCode == 230 {
if let responseWithHttp = event.value?["response_with_http_code"] as? ResponseWithHttp {
let response = responseWithHttp.response
let profile = response?.profile
let subscription = profile?.subscription
// extract fields?["_device_name"] as a string value
if let deviceName = subscription?.fields?["_device_name"]?.stringValue {
print(deviceName)
}
}
}
}
profileFields:[String: Any?]?
По умолчанию: nil
Обязательный: Нет
Описание: Словарь, содержащий поля профиля.
Параметр может принимать как системные поля (например, _fname — имя или _lname — фамилия), так и опциональные (заранее создаются вручную в интерфейсе платформы). Допустимые типы значений (JSON-совместимые):
- String
- Bool
- Числа
nil- Объекты
[String: Any] - Массивы
Если передано невалидное опциональное поле, запрос завершится с ошибкой:
SDK error: 430
http code: 400
error: 400
errorText: Platform profile processing error: with field "название_поля": Incorrect field
customFields:[String: Any?]?
По умолчанию: nil
Обязательный: Нет
Описание: Словарь, содержащий поля подписки.
Параметр может принимать как системные поля (например, _device_model — модель устройства или _os — операционная система), так и опциональные (заранее создаются вручную в интерфейсе платформы). Допустимые типы значений:
- String
- Bool
- Int
- Float
- Double
nil
Если передано невалидное опциональное поле, запрос завершится с ошибкой:
SDK error: 430
http code: 400
error: 400
errorText: Platform profile processing error: field "название_поля" is not valid: failed convert custom field
Вложенные объекты, массивы и коллекции не допускаются.
Большая часть системных полей подписки автоматически собирается SDK и добавляется к push-запросам. К таким системным полям относятся: "_os", "_os_tz", "_os_language", "_device_type", "_device_model", "_device_name", "_os_ver", "_ad_track", "_ad_id".
cats:[CategoryData]?
По умолчанию: nil
Обязательный: Нет
Описание: Категории подписок.
Структура категории:
public struct CategoryData: Codable {
public var name: String?
public var title: String?
public var steady: Bool?
public var active: Bool?
}
При отправке push-запроса с указанием категорий используйте только поля name (название категории) и active (статус активности категории), другие поля не используется в обработке запроса. Поля title и steady заполняются при получении информации о подписке.
Пример запроса:
let cats: [CategoryData] = [CategoryData(name: "football", title: nil, steady: nil, active: true)]
Пример ответа:
[ { name: "developer_news", title: "dev_news", steady: false, active: false } ]
Категории используемые в запросе должны быть предварительно созданы и добавлены к ресурсу в платформе Altcraft. Если в запросе будет использовано поле, которое не добавлено в ресурс — запрос вернется с ошибкой:
SDK error: 430
http code: 400
error: 400
errorText: Platform profile processing error: field "subscriptions.cats" is not valid: category not found in resource
replace:Bool?
По умолчанию: nil
Обязательный: Нет
Описание: При активации флага все подписки других профилей с тем же push-токеном в текущей базе данных переводятся в статус unsubscribed после успешного запроса.
skipTriggers:Bool?
По умолчанию: nil
Обязательный: Нет
Описание: При активации флага профиль, содержащий данную подписку, будет игнорироваться в триггерах кампаний и сценариев.
Примеры реализации запроса
Пример выполнения запроса подписки на push-уведомления
Минимальная рабочая настройка:
AltcraftSDK.shared.pushSubscriptionFunctions.pushSubscribe()
Передача всех доступных параметров:
AltcraftSDK.shared.pushSubscriptionFunctions.pushSubscribe(
sync: true,
profileFields: ["_fname":"Andrey", "_lname":"Pogodin"],
customFields: ["developer":true],
cats: [CategoryData(name: "developer_news", active: true)],
replace: false,
skipTriggers: false
)
Для pushSubscribe, pushSuspend, pushUnSubscribe предусмотрен автоматический повтор запроса со стороны SDK если http-код ответа находится в диапазоне 500..599. Запрос не повторяется, если код ответа в этот диапазон не входит.
Функция unSuspendPushSubscription()
Функция func unSuspendPushSubscription() предназначена для создания LogIn-, LogOut-переходов. Она работает следующим образом:
- проводит поиск подписок с тем же push-токеном, что и текущий, не относящихся к профилю, на который указывает текущий JWT-токен;
- меняет статус для найденных подписок с
subscribedнаsuspended; - меняет статус в подписках профиля, на который указывает текущий JWT, с
suspendedнаsubscribed(если профиль на который указывает JWT существует и в нем содержатся подписки); - возвращает public struct
ResponseWithHttpCode?, в которомresponse.profile— текущий профиль, на который указывает JWT (если профиля не существует, то вместоresponse.profileвернетсяnil).
Пример использования:
AltcraftSDK.shared.pushSubscriptionFunctions.unSuspendPushSubscription(completion: @escaping (ResponseWithHttp?) -> Void)
Рекомендуемая реализация LogIn-, LogOut-переходов
LogIn-переход:
- Анонимный пользователь входит в приложение. Данному пользователю присвоен
JWT_1, указывающий на базу данных #1Anonymous; - Выполнена подписка на push-уведомления, профиль создан в базе данных #1Anonymous;
- Пользователь регистрируется, ему присваивается
JWT_2, указывающий на базу данных #2Registered; - Вызывается функция
unSuspendPushSubscription()— подписка анонимного пользователя в базе данных #1Anonymous приостанавливается; - Выполняется поиск профиля в базе данных #2Registered для восстановления подписки;
- Так как подписки с таким push-токеном в базе данных #2Registered не существует, функция
unSuspendPushSubscription()вернетnil; - После получения значения
nilможно выполнить запрос на подпискуpushSubscribe(), который создаст новый профиль в базе #2Registered.
LogOut-переход:
- Пользователь выполнил выход из профиля на стороне приложения (
LogOut); - Пользователю присваивается
JTW_1, указывающий на базу данных #1Anonymous; - Вызывается функция
unSuspendPushSubscription(), которая приостановит подписку базе данных в #2Registered и сменит статус подписки в базе #1Anonymous наsubscribed; - Запрос вернет
#1Anonymous != nil— подписка уже существует, новая не требуется.
Пример реализации:
func logIn() {
JWTManager.shared.setRegJWT()
// JWT is set for an authorized user
AltcraftSDK.shared.pushSubscriptionFunctions.unSuspendPushSubscription { result in
if result?.httpCode == 200, result?.response?.profile?.subscription == nil {
AltcraftSDK.shared.pushSubscriptionFunctions.pushSubscribe(
// specify the required parameters
)
}
}
}
func logOut() {
JWTManager.shared.setAnonJWT()
// JWT is set for an anonymous user
AltcraftSDK.shared.pushSubscriptionFunctions.unSuspendPushSubscription { result in
if result?.httpCode == 200, result?.response?.profile?.subscription == nil {
AltcraftSDK.shared.pushSubscriptionFunctions.pushSubscribe(
// specify the required parameters
)
}
}
}
Запрос статуса подписки
AltcraftSDK
// Singleton, the entry point to the SDK
└── static let shared: AltcraftSDK
// Subscription managment
└── pushSubscriptionFunctions: PublicPushSubscriptionFunctions
// Last profile subscription status
├── getStatusOfLatestSubscription(
│ completion: @escaping (ResponseWithHttp?) -> Void
│ ): Void
// Subscription status corresponding to the current token/provider
├── getStatusForCurrentSubscription(
│ completion: @escaping (ResponseWithHttp?) -> Void
│ ): Void
// Status of the latest subscription for the provider (if nil — the current one is used)
└── getStatusOfLatestSubscriptionForProvider(
provider: String? = nil,
completion: @escaping (ResponseWithHttp?) -> Void
): Void
Функции запроса статуса подписки:
func getStatusOfLatestSubscription()— статус последней подписки профиля;func getStatusOfLatestSubscriptionForProvider()— статус подписки для текущего токена/провайдера;func getStatusForCurrentSubscription()— статус последней подписки по провайдеру. Если указанnil, то используется текущий.
public func getStatusOfLatestSubscription(completion: @escaping (ResponseWithHttp?) -> Void): Void
Функция получения статуса последней подписки профиля. В completion передаётся объект ResponseWithHttp?, содержащий response?.profile?.subscription — последнюю созданную подписку в профиле. Если такой подписки не существует, будет передан nil.
Пример использования:
AltcraftSDK.shared.pushSubscriptionFunctions.getStatusOfLatestSubscription(completion: @escaping (ResponseWithHttp?) -> Void)
public func getStatusForCurrentSubscription(completion: @escaping (ResponseWithHttp?) -> Void): Void
Функция получения статуса подписки для текущего токена/провайдера. В completion передаётся объект ResponseWithHttp?, содержащий response?.profile?.subscription — подписку, найденную по текущему push-токену и провайдеру. Если такой подписки не существует, будет передан nil.
Пример использования:
AltcraftSDK.shared.pushSubscriptionFunctions.getStatusForCurrentSubscription(completion: @escaping (ResponseWithHttp?) -> Void)
public func getStatusOfLatestSubscriptionForProvider(provider: String? = nil, completion: @escaping (ResponseWithHttp?) -> Void): Void
Функция получения статуса последней подписки по провайдеру. В completion передаётся объект ResponseWithHttp?, содержащий response?.profile?.subscription — последнюю созданную подписку с указанным провайдером push-уведом лений. Если провайдер не указан, используется провайдер текущего токена. Если такой подписки не существует, будет передан nil.
Пример использования:
AltcraftSDK.shared.pushSubscriptionFunctions.getStatusOfLatestSubscriptionForProvider(provider: String? = nil, completion: @escaping (ResponseWithHttp?) -> Void)
Ниже представлен пример извлечения данных о профиле, подписке и категориях из ответа функций получения статуса. Данный подход актуален для всех функций получения статуса:
Данные из функций получения статуса
AltcraftSDK.shared.pushSubscriptionFunctions.getStatusForCurrentSubscription{ responseWithHttp in
// HTTP code
let httpCode = responseWithHttp?.httpCode
// Response
let response = responseWithHttp?.response
let error = response?.error
let errorText = response?.errorText
// Profile
let profile = response?.profile
let profileId = profile?.id
let profileStatus = profile?.status
let profileIsTest = profile?.isTest
// Subscription
let subscription = profile?.subscription
let subscriptionId = subscription?.subscriptionId
let hashId = subscription?.hashId
let provider = subscription?.provider
let subscriptionStatus = subscription?.status
// Fields (dictionary [String: JSONValue])
let fields = subscription?.fields
// Cats (array of CategoryData)
let cats = subscription?.cats
// CategoryData (every element of cats array)
let firstCat = cats?.first
let catName = firstCat?.name
let catTitle = firstCat?.title
let catSteady = firstCat?.steady
let catActive = firstCat?.active
}
В случае успешно выполненного запроса будет создано событие с кодом 234. В случае ошибки — событие с кодом 434.
Управление push-токенами провайдеров
AltcraftSDK
// Singleton, the entry point to the SDK
└── static let shared: AltcraftSDK
// Managing push tokens and providers (FCM / HMS / APNs)
└── pushTokenFunctions: PublicPushTokenFunctions
// Manually save the token (String for FCM/HMS, Data for APNs)
├── setPushToken(
│ provider: String,
│ pushToken: Any?
│ ): Void
// Asynchronously retrieve the current push token (completion is optional)
├── getPushToken(
│ completion: ((TokenData?) -> Void)? = nil
│ ): Void
// Set the Firebase Cloud Messaging provider (nil — remove)
├── setFCMTokenProvider(
│ _ provider: FCMInterface?
│ ): Void
// Set the Huawei Mobile Services provider (nil — remove)
├── setHMSTokenProvider(
│ _ provider: HMSInterface?
│ ): Void
// Set the Apple Push Notification service provider (nil — remove)
├── setAPNSTokenProvider(
│ _ provider: APNSInterface?
│ ): Void
// Apply a new provider priority list and initiate token update
├── changePushProviderPriorityList(
│ _ list: [String]
│ ): Void
// Delete the push token of the specified provider and call completion
├── deleteDeviceToken(
│ provider: String,
│ completion: @escaping () -> Void
│ ): Void
// Force token update
└── forcedTokenUpdate(
completion: (() -> Void)? = nil
): Void
Функции для работы с токеном провайдера в SDK:
func setPushToken()— ручная установка push-токена устройства и провайдера вUserDefaults;func getPushToken()— получение текущего push-токена;func setAPNSTokenProvider()— установка и снятие push-токена APNs;func setFCMTokenProvider()— установка и снятие push-токена FCM;func setHMSTokenProvider()— установка и снятие push-токена HSM;func changePushProviderPriorityList()— функция, позволяющая выполнить динамическую смену провайдера с обновлением push-токена подписки;func deleteDeviceToken()— удаление push-токена указанного провайдера;func forcedTokenUpdate()— удаление текущего push-токена с последующим обновлением.
public func setPushToken(provider: String, pushToken: Any?): Void
Функция предназначена для ручной установки push-токена устройства и провайдера в UserDefaults. Используется как упрощенный вариант передачи push-токена в SDK без реализации протоколов провайдеров.
Не рекомендуется использовать эту функцию для передачи токена. Рекомендуемый подход передачи push-токена в SDK — реализация FCMInterface, HMSInterface или APNSInterface.
Пример использования:
AltcraftSDK.shared.pushTokenFunction.setPushToken(provider: String, pushToken: Any?)
public func getPushToken(completion: ((TokenData?) -> Void)? = nil): Void
Функция передает в completion объект TokenData(provider: String, token: String), содержащий текущий push-токен устройства и его провайдера. Если push-токен недоступен, в completion будет передано nil.
Пример использования:
AltcraftSDK.shared.pushTokenFunction.getPushToken(completion: ((TokenData?) -> Void)? = nil)
Пример запроса получения данных push-токена:
AltcraftSDK.shared.pushTokenFunction.getPushToken{ data in
let provider = data?.provider
let token = data?.token
}
public func setFCMTokenProvider(_ provider: FCMInterface?): Void
Функция устанавливает или снимает push-токен провайдера Firebase Cloud Messaging. Чтобы отключить провайдера, передайте nil.
Пример использования:
AltcraftSDK.shared.pushTokenFunction.setFCMTokenProvider(_ provider: FCMInterface?)
Вызывайте setFCMTokenProvider() в AppDelegate.application(_:didFinishLaunchingWithOptions:) до вызова AltcraftSDK.initialization(). Это гарантирует регистрацию на старте процесса приложения, независимо от состояния жизненного цикла других компонентов и того, запущено приложение в foreground или background.
public func setHMSTokenProvider(_ provider: HMSInterface?): Void
Функция устанавливает или снимает push-токен провайдера Huawei Mobile Services. Чтобы отключить провайдера, передайте nil.
AltcraftSDK.shared.pushTokenFunction.setHMSTokenProvider(_ provider: HMSInterface?)
Вызывайте setHMSTokenProvider() в AppDelegate.application(_:didFinishLaunchingWithOptions:) до вызова AltcraftSDK.initialization(). Это гарантирует регистрацию на старте процесса приложения, независимо от состояния жизненного цикла других компонентов и того, запущено приложение в foreground или background.
public func setAPNSTokenProvider(_ provider: APNSInterface?): Void
Функция устанавливает или снимает push-токен провайдера Apple Push Notification service. Чтобы отключить провайдера, передайте nil.
AltcraftSDK.shared.pushTokenFunction.setHMSTokenProvider(_ provider: APNSInterface?)
Вызывайте setAPNSTokenProvider() в AppDelegate.application(_:didFinishLaunchingWithOptions:) до вызова AltcraftSDK.initialization(). Это гарантирует регистрацию на старте процесса приложения, независимо от состояния жизненного цикла других компонентов и того, запущено приложение в foreground или background.
public func changePushProviderPriorityList(_ list: [String]): Void
Функция, позволяющая выполнить динамическую смену push-провайдера с обновлением токена подписки. Для этого необходимо передать новый массив с другим порядком провайдеров. Например: [Constants.ProviderName.firebase, Constants.ProviderName.apns, Constants.ProviderName.huawei].
Пример использования:
AltcraftSDK.shared.pushTokenFunction.changePushProviderPriorityList(_ list: [String])
public func deleteDeviceToken(provider: String, completion: @escaping () -> Void): Void
Функция удаления push-токена для указанного провайдера. Токен инвалидируется и удаляется из локального кеша на устройстве и с сервера push-провайдера. После удаления можно запросить новый токен.
Пример использования:
AltcraftSDK.shared.pushTokenFunction.deleteDeviceToken(provider: String, completion: @escaping () -> Void)
public func forcedTokenUpdate(completion: (() -> Void)? = nil): Void
Функция удаления текущего push-токена с его последующим обновлением.
Пример использования:
AltcraftSDK.shared.pushTokenFunction.forcedTokenUpdate(completion: (() -> Void)? = nil)
Пример регистрации провайдеров
Мы не рекомендуем использовать функцию setPushToken для установки push-токена. Вместо этого отдельно настройте функции получения токена для каждого используемого провайдера. Ниже указан пример реализации этого метода:
Рекомендованный способ регистрации провайдеров в AppDelegate
class AppDelegate: UIResponder, UIApplicationDelegate, MessagingDelegate, UNUserNotificationCenterDelegate {
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
let appGroup = "your appGroup id"
AltcraftSDK.shared.setAppGroup(groupName: appGroup)
AltcraftSDK.shared.backgroundTasks.registerBackgroundTask()
AltcraftSDK.shared.setJWTProvider(provider: JWTProvider())
//apns provider
AltcraftSDK.shared.pushTokenFunction.setAPNSTokenProvider(APNSProvider())
//fcm provider
AltcraftSDK.shared.pushTokenFunction.setFCMTokenProvider(FCMProvider())
//hms provider
AltcraftSDK.shared.pushTokenFunction.setHMSTokenProvider(HMSProvider())
AltcraftSDK.shared.notificationManager.registerForPushNotifications(for: application)
let config = AltcraftConfiguration.Builder().setApiUrl("your api url").build()
AltcraftSDK.shared.initialization(configuration: config)
//other functions
return true
}
}
Передача push-уведомлений в SDK
SDK содержит класс AltcraftNSE, который предназначен для использования внутри Notification Service Extension.
Он содержит функции для обработки входящие push-уведомления (UNNotificationRequest) и обеспечивает регистрацию мобильных событий в NSE.
// Used inside Notification Service Extension (NSE) — facade for handling Altcraft push notifications,
// detecting Altcraft-specific requests, and registering mobile events without direct dependency on UIApplication
AltcraftNSE
// Shared singleton instance for centralized NSE logic
├─ public static let shared: AltcraftNSE
// Provides access to mobile event registration API
├─ public let mobileEventFunctions: PublicMobileEventFunctions
// Check whether the notification request belongs to Altcraft
├─ public func isAltcraftPush(_ request: UNNotificationRequest) -> Bool
// Handle an incoming Altcraft notification request and deliver the modified content
├─ public func handleNotificationRequest(
│ request: UNNotificationRequest,
│ contentHandler: @escaping (UNNotificationContent) -> Void
│ ): Void
// Called when NSE is about to time out — returns the best available notification content
├─ public func serviceExtensionTimeWillExpire(): Void
// Set the App Group identifier and initialize Core Data in the shared container
├─ public func setAppGroup(groupName: String): Void
// Register a JWT provider for secure token management in Altcraft SDK
└─ public func setJWTProvider(provider: JWTInterface): Void
Функции класса AltcraftNSE:
func isAltcraftPush()— функция проверки источника уведомления;func handleNotificationRequest()— функция, принимающаяUNNotificationRequestиз Notification Service Extension для его дальнейшей обработки на с тороне SDK;func serviceExtensionTimeWillExpire()— функция, вызывающаяся по истечении времени работы Notification Service Extension (~30 секунд).
public func isAltcraftPush(_ request: UNNotificationRequest) -> Bool
Функция SDK, проверяющая, является ли источником уведомления Altcraft по маркеру в userInfo.
Пример использования:
AltcraftNSE.shared.isAltcraftPush(_ request: UNNotificationRequest) -> Bool
public func handleNotificationRequest(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void): Void
Функция SDK, принимающая UNNotificationRequest из Notification Service Extension для его обработки на стороне SDK и дальнейшего показа уведомления.
Пример использования:
AltcraftNSE.shared.handleNotificationRequest(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void)
public func serviceExtensionTimeWillExpire()
Функция, которая вызывается системой по истечении времени работы Notification Service Extension (~30 секунд).
Пример использования:
AltcraftNSE.shared.serviceExtensionTimeWillExpire()
public func setAppGroup(groupName: String): Void
Функция для добавления идентификатора AppGroup (обязательная установка).
Пример использования:
AltcraftNSE.shared.setAppGroup(groupName: "group.your.app.id")
public func setJWTProvider(provider: JWTInterface): Void
Функция для установки JWT-провайдера:
AltcraftNSE.shared.setJWTProvider(provider: jwtProvider)
Мобильные события
// Функции объекта PublicMobileEventFunctions
AltcraftSDK.shared
└── let mobileEventFunctions: PublicMobileEventFunctions
// Отправить мобильное событие (mobile event) на сервер
└── func mobileEvent(
sid: String,
eventName: String,
sendMessageId: String? = nil,
payload: [String: Any?]? = nil,
matching: [String: Any?]? = nil,
matchingType: String? = nil,
profileFields: [String: Any?]? = nil,
subscription: (any Subscription)? = nil
utm: UTM? = nil
)
Для регистрации мобильного события используйте функцию mobileEvent() из PublicMobileEventFunctions. Она имеет следующие параметры:
sid: String
Обяз ательный: Да
Описание: Строковый идентификатор пикселя, к которому привязываются мобильные события.
eventName: String
Обязательный: Да
Описание: Имя мобильного события.
sendMessageId: String?
Обязательный: Нет
Описание: SMID-идентификатор отправленного сообщения (если событие связано с конкретной рассылкой).
payload: [String: Any?]?
Обязательный: Нет
Описание: Данные события — карта со строковыми ключами и значениями, для которых допускаются только скалярные типы данных:
StringBoolIntInt64/UInt64(илиNSNumberэквиваленты)FloatDoublenil/NSNull
Несериализуемые объекты (например, Date без преобразования, кастомные классы) приведут к ошибке кодирования.
matching: [String: Any?]?
Обязательный: Нет
Описание: Карта, в которую можно передавать значения с типами и идентификаторами матчинга (например, ["email" : "user@example.com"]).
matchingType: String?
Обязательный: Нет
Описание: Тип матчинга.
profileFields: [String: Any?]?
Обязательный: Нет
Описание: Поля профиля — карта со строковыми ключами и значениями (JSON-совместимые типы):
- Скалярные значения:
StringBoolIntInt64/UInt64(или эквивалентыNSNumber)FloatDoublenil/NSNull
- Объекты:
[String: Any?] - Списки:
[Any?] - Массивы карт:
[[String: Any?]]
Параметр profileFields используется только при работе с JWT-авторизацией.
utm: UTM?
Обязательный: Нет
Описание: UTM-метки. Добавляются с помощью struct UTM, где каждый вид UTM — свойство структуры.
public struct UTM{
/// UTM Campaign
public var campaign: String?
/// UTM Content
public var content: String?
/// UTM Keyword/Term
public var keyword: String?
/// UTM Medium
public var medium: String?
/// UTM Source
public var source: String?
/// UTM Temp
}
subscription: (any Subscription)?
Обязательный: Нет
Описание: Добавляемая к профилю подписка одного из типов: EmailSubscription, SmsSubscription, PushSubscription, CcDataSubscription.
Используется только при работе с JWT-авторизацией.
Реализации интерфейса Subscription
Назначение — общий протокол для всех типов подписок.
Сериализация — через Codable, поле-дискриминатор — channel.
Общие поля (для всех реализаций):
| Поле | Тип | Обязательный | Описание |
|---|---|---|---|
resource_id | Int | Да | Идентификатор ресурса/источника подписки |
status | String? | Нет | Статус подписки (например, активна/приостановлена) |
priority | Int? | Нет | Приоритет доставки для данной подписки |
custom_fields | [String: JSONValue]? | Нет | Пользовательские поля (ключ-значение) для расширенной сегментации |
cats | [String]? | Нет | Категории подписки |
channel | String | Да | Тип канала; фиксируется реализацией. |
JSONValue — сериализуемый тип/перечень JSON-значений в вашем SDK. Все значения должны быть совместимы с JSON.
Варианты подписки:
EmailSubscription (channel = "email")
Основные поля
| Поле | Тип | Обязательный | Описание |
|---|---|---|---|
resourceId | Int | Да | ID ресурса Altcraft |
email | String | Да | Адрес электронной почты получателя |
Дополнительные поля
| Поле | Тип | Обязательный | Описание |
|---|---|---|---|
status | String? | Нет | Статус подписки |
priority | Int? | Нет | Приоритет подписки |
customFields | [String: JSONValue]? | Нет | Стандартные и кастомные поля подписки |
cats | [String]? | Нет | Категории подписки |
SmsSubscription (channel = "sms")
Основные поля
| Поле | Тип | Обязательный | Описание |
|---|---|---|---|
resourceId | Int | Да | ID ресурса Altcraft |
phone | String | Да | Номер телефона в международном формате |
Дополнительные поля
| Поле | Тип | Обязательный | Описание |
|---|---|---|---|
status | String? | Нет | Статус подписки |
priority | Int? | Нет | Приоритет подписки |
customFields | [String: JSONValue]? | Нет | Стандартные и кастомные поля подписки |
cats | [String]? | Нет | Категории подписки |
PushSubscription (channel = "push")
Основные поля
| Поле | Тип | Обязательный | Описание |
|---|---|---|---|
resourceId | Int | Да | ID ресурса Altcraft |
provider | String | Да | Провайдер (например, "ios-apns") |
subscriptionId | String | Да | Уникальный идентификатор подписки у провайдера |
Дополнительные поля
| Поле | Тип | Обязательный | Описание |
|---|---|---|---|
status | String? | Нет | Статус подписки |
priority | Int? | Нет | Приоритет подписки |
customFields | [String: JSONValue]? | Нет | Стандартные и кастомные поля подписки |
cats | [String]? | Нет | Категории подписки |
CcDataSubscription (channel ∈ {"telegram_bot","whatsapp","viber","notify"})
Основные поля
| Поле | Тип | Обязательный | Описание |
|---|---|---|---|
resourceId | Int | Да | ID ресурса Altcraft |
channel | String | Да | Один из: "telegram_bot", "whatsapp", "viber", "notify" |
ccData | [String: JSONValue] | Да | Канал-специфичные данные (например, chat ID, номер, токены) |
Дополнительные поля
| Поле | Тип | Обязательный | Описание |
|---|---|---|---|
status | String? | Нет | Статус подписки |
priority | Int? | Нет | Приоритет подписки |
customFields | [String: JSONValue]? | Нет | Стандартные и кастомные поля подписки |
cats | [String]? | Нет | Категории подписки |
Получение событий SDK в приложении
// Функции объекта Events
AltcraftSDK
// Singleton, точка входа в SDK
└── static let shared: AltcraftSDK
// Поток событий SDK (один активный подписчик)
└── eventSDKFunctions: SDKEvents
// Подписка на события SDK (заменяет существующего подписчика)
├── subscribe(
│ callback: @escaping (Event) -> Void
│ ): Void
// Отписка от событий (callback остается назначенным, доставка прекращается)
└── unsubscribe(): Void
В приложении может быть только один активный подписчик на события SDK.
Подписка на события
public func subscribe(callback: @escaping (Event) -> Void): Void
Функция используется для того, чтобы подписаться и получать события SDK в приложении. При возникновении события SDK она вызывает callback и передаёт в него экземпляр класса Event (или его наследника).
Пример использования:
AltcraftSDK.shared.eventSDKFunctions.subscribe { event in
// событие
}
Все события, передаваемые SDK, являются экземплярами Event или его наследников:
- Event — общее событие (информация, успешные запросы);
- Error — событие об ошибке;
- RetryError — событие об ошибке при выполнения запроса для которого предусмотрен автоматический повтор выполнения на стороне SDK.
Каждое событие содержит поля:
- function — имя функции, вызывавшей событие;
- eventCode — внутренний код события SDK (список событий SDK представлен в пункте "События SDK");
- eventMessage — сообщение события;
- eventValue — произвольные данные [String: Any?]? которые добавляются к некоторым событиям как полезная нагрузка;
- date — время события.
Классы событий SDK
open class Event: Hashable {
public let id = UUID()
public let function: String
public let message: String?
public let eventCode: Int?
public let value: [String: Any?]?
public let date: Date
}
open class ErrorEvent: Event {
public override init(
function: String,
message: String? = nil,
eventCode: Int? = nil,
value: [String: Any?]? = nil,
date: Date = Date()
) {
super.init(
function: function,
message: message,
eventCode: eventCode,
value: value,
date: date
)
}
}
public class RetryEvent: ErrorEvent {
public override init(
function: String,
message: String? = nil,
eventCode: Int? = 0,
value: [String: Any?]? = nil,
date: Date = Date()
) {
super.init(
function: function,
message: message,
eventCode: eventCode,
value: value,
date: date
)
}
}
Пример содержания события успешной подписки на push-уведомления
├─ function: processResponse
├─ eventCode: 230
├─ message: "successful request: push/subscribe"
├─ value
│ ├─ http code: 200
│ └─ response
│ ├─ error: 0
│ ├─ errorText: ""
│ └─ profile
│ ├─ id: // ID профиля
│ ├─ status: subscribed
│ ├─ isTest: false
│ └─ subscription
│ ├─ subscriptionId: // push-токен подписки
│ ├─ hashId: // хэш ID
│ ├─ provider: "ios-apns"
│ ├─ status: subscribed
│ ├─ fields
│ │ ├─ _ad_id: // google service ad id
│ │ ├─ _ad_track: false
│ │ ├─ _app_id: "AltcraftMobile"
│ │ ├─ _app_iid: "1.0.0"
│ │ ├─ _app_ver: {"raw":"1.0.0","ver":[1,0]}
│ │ ├─ _device_model: "iPhone14,7"
│ │ ├─ _device_name: "iPhone"
│ │ ├─ _device_type: "mob"
│ │ ├─ _os: "Android"
│ │ ├─ _os_language: "ru"
│ │ ├─ _os_tz: "+0300"
│ │ └─ _os_ver: {"raw":"18.6.2","ver":"[\"18.0\", \"6.0\", \"2.0\"]"}
│ └─ cats
│ └─ [ { name: "cats_1", title: "cats_1", steady: false, active: false } ]
└─ date: Tue Aug 12 15:49:20 GMT+03:00 2025
Отписка от событий
public func unsubscribe(): Void
При помощи данной функции можно отписаться от событий SDK. Она отменяет передачу событий SDK, при этом callback остаётся назначенным, но доставка событий прекращается.
Пример использования:
AltcraftSDK.shared.eventSDKFunctions.unsubscribe()
Список всех событий SDK
Список событий
| Код | Описание |
|---|---|
| 200 | SDK configuration is installed |
| 201 | push provider set |
| 203 | received Altcraft push notification |
| 204 | push is posted |
| 205 | SDK data has been cleared |
| 206 | SDK background task is registered |
| 207 | SDK background task completed |
| 230 | subscribe request succeeded |
| 231 | token update request succeeded |
| 232 | unsuspend request succeeded |
| 233 | status request succeeded |
| 234 | push event delivered successfully |
| 235 | mobile event delivered successfully |
| 401 | the configuration is not set |
| 402 | userTag is null. It is impossible to identify the user |
| 403 | error in CoreData. Re-initialize the SDK |
| 404 | failed to load model from framework |
| 405 | App Group name was not set |
| 406 | forcing a push token update is not possible: the operation is not supported for APNs |
| 407 | the CoreData entity name is not valid |
| 408 | entity not found by ID |
| 422 | unsuspend request data is nil |
| 423 | profile request data is nil |
| 430 | subscribe request failed |
| 431 | token update request failed |
| 432 | unsuspend request failed |
| 433 | status request failed |
| 434 | push event delivery failed |
| 435 | mobile event delivery failed |
| 450 | invalid userInfo format |
| 451 | uid in the push data is null; it is impossible to send a push event to the server |
| 452 | could not download image data from URL |
| 453 | 'media' key is missing or URL string is invalid |
| 454 | 'buttons' key is missing or is invalid |
| 455 | invalid button identifier (see event value) |
| 456 | out of range for identifier (see event value) |
| 457 | unknown button identifier (see event value) |
| 471 | invalid apiUrl value — empty or null |
| 472 | invalid resource token value — resource token is empty |
| 473 | invalid provider. Available — ios-apns, ios-firebase, ios-huawei |
| 474 | non-JSON object has been provided |
| 475 | invalid values: not all values are primitives |
| 476 | unsupported subscription type. Available: EmailSubscription, SmsSubscription, PushSubscription, CcDataSubscription |
| 501 | config data is nil |
| 502 | current token is nil |
| 503 | userTag is null. It is impossible to identify the user |
| 504 | notification permission denied |
| 505 | SDK background task expired |
| 520 | subscribe request data is nil |
| 521 | update request data is nil |
| 524 | push event request data is nil |
| 525 | mobile event request data is nil |
| 529 | common data is nil |
| 530 | subscribe request failed (retryable) |
| 531 | token update request failed (retryable) |
| 534 | push event delivery failed (retryable) |
| 535 | mobile event delivery failed (retryable) |
| 540 | JWT token is nil |
| 541 | JWT parsing error |
| 542 | invalid matching |
| 543 | auth data is nil |
| 561 | failed to create request |
| 562 | failed processing the response |
| 571 | invalid request URL |
| 572 | invalid response format |
| 573 | invalid push subscribe request data |
| 574 | invalid push event request data |