SDK functionality
You must configure the SDK to work with your app beforehand. Detailed instructions are available here
The SDK is split into modules: core (authentication, events), push, target (goals), profile, and in-app. Each module is connected as a separate dependency and is accessed through its own property of the AltcraftSDK.shared object — AltcraftSDK.shared.push, AltcraftSDK.shared.target, AltcraftSDK.shared.profile, AltcraftSDK.shared.inApp.
Core: authentication
AltcraftSDK
└─ static let shared: AltcraftSDK
// Access to user authentication
└─ let authFunctions: AuthAPI
// Authenticate the current SDK user
├─ func authenticate(): Void
// Log out of the profile (return to the anonymous session)
└─ func logOut(): Void
Authentication functions:
func authenticate()— authenticates the current user: sends a request to the server with the current authentication data (JWT token or rToken) and links the device to the user profile. After successful authentication, the user gets access to personalized In-App notifications.func logOut()— ends the current authentication session and switches the device to anonymous mode. In anonymous mode, personalized In-App notifications and subscription management are not available.
Setting the JWT provider is done with the AltcraftSDK.shared.setJWTProvider(provider:) function (see SDK setup). To work without JWT, use the rToken from the configuration.
Call authenticate() only when the user is actually signing in to the app and is known to the client (for example, after successful authorization via a login form, OAuth, or another authentication mechanism of your app). The same applies to logOut(): only on a real user logout.
Usage example:
AltcraftSDK.shared.authFunctions.authenticate()
Clearing SDK data
AltcraftSDK
// Full cleanup of SDK data (cache, DB, settings), then calls completion
└── func clear(
completion: (() -> Void)? = nil
): Void
The function performs a full cleanup of SDK data: cache, database, and local settings. The optional completion parameter is called after the cleanup finishes.
Core: SDK events
// SDK events API
AltcraftSDK
└── let eventSDKFunctions: SDKEvents
// Subscribe to SDK events (replaces the existing subscriber)
├── func subscribe(
│ callback: @escaping (Event) -> Void
│ ): Void
// Unsubscribe from events
└── func unsubscribe(): Void
There can be only one active subscriber to SDK events in the app.
SDK event types:
- Event — a general event (information, successful requests);
- ErrorEvent — an error event;
- RetryEvent — an error event for a request for which the SDK provides an automatic retry.
Each event contains the fields:
- function — the name of the function that raised the event;
- event — the SDK event type (
SDKEvent, see the table below for the list); - message — the event message;
- value — additional data (
[String: Any]?) added to some events; - date — the event time.
Subscribing to events
func subscribe(callback: @escaping (Event) -> Void): Void
The function subscribes the app to SDK events. When an SDK event occurs, it calls the passed callback and passes an Event instance (or one of its subclasses) to it. The callback is always called on the main thread.
Usage example:
AltcraftSDK.shared.eventSDKFunctions.subscribe { event in
// Handle the event
}
SDK event classes
open class Event: NSObject {
public let id = UUID()
public let function: String
public let event: SDKEvent?
public let message: String?
public let value: [String: Any]?
public let date: Date
}
// Error without automatic retry
open class ErrorEvent: Event {}
// Request error for which an automatic retry is provided
public final class RetryEvent: ErrorEvent {}
Unsubscribing from events
func unsubscribe(): Void
Cancels the delivery of SDK events. The subscriber remains assigned, but events are no longer delivered.
Usage example:
AltcraftSDK.shared.eventSDKFunctions.unsubscribe()
List of all SDK events
List of events by module
SDK events are available as enum values: CoreEvents (core), PushModuleEvents, TargetModuleEvents, ProfileModuleEvents, InAppModuleEvents. Each element is an enum value with a string message (message).
Core:
| Value | Message |
|---|---|
configSet | SDK configuration is installed. |
sdkCleared | SDK data has been cleared |
initAwait | waiting for SDK initialization to complete |
userLogOut | User logged out. Anonymous session started |
backgroundTaskRegister | SDK background task is registered |
backgroundTaskCompleted | SDK background task completed |
configIsNotSet | the configuration is not set |
appGroupIsNotSet | App Group name was not set. |
notAuthenticatedError | user is not authenticated |
invalidUrlValue | invalid apiUrl value - empty or null. |
invalidRTokenValue | invalid resource token value - resource token is empty. |
fieldsIsObjects | invalid values: not all values are primitives |
permissionDenied | notification permission denied. |
jwtIsNil | JWT token is nil |
authenticateSuccessful | successful request: profile/authenticate |
authenticateFailed | failed request: profile/authenticate |
The CoreEvents enum also contains internal events (CoreData errors, JWT parsing errors, environment unavailability, etc.) that are not included in the table above and are not part of the public API. Internal events are also present in PushModuleEvents and InAppModuleEvents — the tables below list only the public API events.
Push:
| Value | Message |
|---|---|
pushProviderSet | push provider set: |
pushReceive | received Altcraft push notification. |
pushIsPosted | push is posted. |
pushTokenUpdateAwait | waiting for push token update to complete |
pushSubscribeRequestSuccessful | successful request: push/subscribe |
pushSubscribeRequestFailed | failed request: push/subscribe |
pushSuspendRequestSuccessful | successful request: push/suspend |
pushSuspendRequestFailed | failed request: push/suspend |
pushUnsubscribeRequestSuccessful | successful request: push/unsubscribe |
pushUnsubscribeRequestFailed | failed request: push/unsubscribe |
tokenUpdateRequestSuccessful | successful request: push/update |
tokenUpdateRequestFailed | failed request: push/update |
pushStatusRequestSuccessful | successful request: push/status |
pushStatusRequestFailed | failed request: push/status |
unsuspendRequestSuccessful | successful request: push/unsuspend |
unsuspendRequestFailed | failed request: push/unsuspend |
pushEventRequestSuccessful | successful request: event/push |
pushEventRequestFailed | failed request: event/push |
invalidPushProviders | invalid provider. Available - ios-apns, ios-firebase, ios-huawei. |
invalidPushProvider | invalid provider. |
errorHandleUserInfo | invalid userInfo format |
uidIsNil | uid in the push data is null, it is impossible to send a push event to the server. |
errorMediaDownload | could not download image data from URL. |
errorMediaKeyMissing | 'media' key is missing or URL string is invalid. |
errorButtonsKeyMissing | 'buttons' key is missing or is invalid. |
invalidButtonIdentifier | invalid button identifier. See event value |
outOfRangeForIdentifier | out of range for identifier. See event value |
unknownButtonIdentifier | unknown button identifier. See event value |
subscribeRequestDataIsNil | subscribe request data is nil |
updateRequestDataIsNil | update request data is nil |
pushEventRequestDataIsNil | push event request data is nil |
unsuspendRequestDataIsNil | unsuspend request data is nil |
pushStatusRequestDataIsNil | push status request data is nil |
invalidSubRequestData | invalid push subscribe request data |
invalidPushEventRequestData | invalid push event request data |
pushConfigurationSaveFailed | failed to save the push configuration to the local database |
pushConfigurationClearFailed | failed to clear the push configuration from the local database |
apnsIsNotUpdated | forcing a push token update is not possible: the operation is not supported for APNs. |
pushTokenIsNil | current push token is nil |
Target:
| Value | Message |
|---|---|
mobileRequestDataIsNil | mobile event request data is nil |
mobileEventRequestSuccessful | successful request: event/post |
mobileEventRequestFailed | failed request: event/post |
Profile:
| Value | Message |
|---|---|
profileUpdateRequestDataIsNil | profile update request data is nil |
profileUpdateRequestSuccessful | successful request: profile/update |
profileUpdateRequestFailed | failed request: profile/update |
In-App:
| Value | Message |
|---|---|
errorInAppImageLoad | failed to load in-app image |
invalidStaticField | invalid in-app static field |
smidIsNil | smid in the in-app data is null, it is impossible to send a in-app event to the server. |
inAppStatusRequestDataIsNil | in-app status request data is nil |
inAppEventRequestDataIsNil | in-app event request data is nil |
subscribeRequestDataIsNil | in-app subscribe request data is nil |
invalidSubRequestData | invalid in-app subscribe request data |
inAppSubscribeRequestSuccessful | successful request: inapp/subscribe |
inAppSubscribeRequestFailed | failed request: inapp/subscribe |
inAppUnsubscribeRequestSuccessful | successful request: inapp/unsubscribe |
inAppUnsubscribeRequestFailed | failed request: inapp/unsubscribe |
inAppStatusRequestSuccessful | successful request: inapp/status |
inAppStatusRequestFailed | failed request: inapp/status |
inAppEventRequestSuccessful | successful request: inapp/event |
inAppEventRequestFailed | failed request: inapp/event |
inAppPlacementsRequestSuccessful | successful request: inapp/placements |
inAppPlacementsRequestFailed | failed request: inapp/placements |
inAppStaticErrorLoad | error loading in-app notification static resources |
inAppContentErrorLoad | error loading in-app notification content |
maxPlacementsInvalid | Invalid in-app configuration: maxPlacements must be >= 1 |
requestIntervalInvalid | Invalid in-app configuration: placementsRequestInterval must be > 0 |
placementsLimitExceeded | in-app placements limit exceeded |
Push: managing subscription statuses
Changing the subscription status
AltcraftSDK
└─ static let shared: AltcraftSDK
└─ var push: Push
└─ var subscription: SubscriptionAPI
// Subscribe (status = SUBSCRIBED)
├─ func subscribe(
│ sync: Bool = true,
│ profileFields: [String: Any?]? = nil,
│ customFields: [String: Any?]? = nil,
│ cats: [CategoryData]? = nil,
│ replace: Bool? = nil,
│ skipTriggers: Bool? = nil
│ ): Void
// Suspend (status = SUSPENDED)
├─ func suspend(
│ sync: Bool = true,
│ profileFields: [String: Any?]? = nil,
│ customFields: [String: Any?]? = nil,
│ cats: [CategoryData]? = nil,
│ replace: Bool? = nil,
│ skipTriggers: Bool? = nil
│ ): Void
// Unsubscribe (status = UNSUBSCRIBED)
├─ func unsubscribe(
│ sync: Bool = true,
│ profileFields: [String: Any?]? = nil,
│ customFields: [String: Any?]? = nil,
│ cats: [CategoryData]? = nil,
│ replace: Bool? = nil,
│ skipTriggers: Bool? = nil
│ ): Void
// Switch subscriptions between profiles (LogIn/LogOut)
├─ func unSuspend(
│ completion: @escaping @Sendable (
│ ResponseModel.ResponseWithHttpCode<ResponseModel.ResponseWithProfile>?
│ ) -> Void
│ ): Void
// Building action field operations on profile fields
└─ func actionField(key: String) -> ActionFieldBuilder
Subscription status change functions:
func subscribe()— subscribes to push notifications;func suspend()— suspends the push notification subscription (notifications are not delivered, but no unsubscribe event is created in the user profile);func unsubscribe()— cancels the push notification subscription;func unSuspend()— used to createLogInandLogOuttransitions;func actionField()— creates anActionFieldBuilderfor building action field operations (set,unset,incr,add,delete,upsert) on profile fields insideprofileFields.
The status change functions share the same signature with the following parameters:
sync: Bool
Default: true
Required: No
Description: A flag that sets whether the request is executed synchronously.
Successful request:
When a request of this group of functions succeeds, a pushSubscribeRequestSuccessful, pushSuspendRequestSuccessful or pushUnsubscribeRequestSuccessful event is created containing the response data in event.value:
If sync == true
event.value
├─ error: 0
├─ error_text: ""
├─ http_code: 200
└─ 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: "mob"
│ ├─ _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 } ]
For a synchronous request, the following values are available in the event.value event value:
-
error – the internal server error code (0 if there are no errors);
-
error_text – the error text (an empty string if there are no errors);
-
http_code – the transport response code;
-
profile – the profile data if the request is successful:
- profile information (ProfileData)
- subscription (SubscriptionData)
- subscription categories (CategoryData)
- if the request failed, only
profile = nilis returned
Data structures
public struct ProfileData: Codable {
public let id: String?
public let status: String?
public let acid: String?
public let isTest: Bool?
public let subscription: SubscriptionData?
}
public struct SubscriptionData: Codable {
public let subscriptionId: String?
public let hashId: String?
public let provider: String?
public let status: String?
public let fields: [String: JSONValue]?
public let cats: [CategoryData]?
}
public struct CategoryData: Codable {
public var name: String?
public var title: String?
public var steady: Bool?
public var active: Bool?
}
If sync == false
event.value
├─ error: Int?
├─ error_text: String?
├─ http_code: Int
└─ profile: ProfileData? = nil
For an asynchronous request, profile in the event.value event value is always nil.
Failed request:
If a request of this group of functions fails, an error-type event is created:
pushSubscribeRequestFailed— subscribing to notifications;pushSuspendRequestFailed— suspending the subscription;pushUnsubscribeRequestFailed— unsubscribing.
Event contents:
- only
http_code, if the Altcraft server was unavailable; erroranderror_text, if the server returned an error.
Getting event values
AltcraftSDK.shared.eventSDKFunctions.subscribe { event in
let sdkEvent = event.event
if sdkEvent == PushModuleEvents.pushSubscribeRequestSuccessful ||
sdkEvent == PushModuleEvents.pushSubscribeRequestFailed
{
let value = event.value
let error = value?["error"] as? Int
let errorText = value?["error_text"] as? String
let httpCode = value?["http_code"] as? Int
let profile = value?["profile"] as? ProfileData
let subscription = profile?.subscription
}
}
profileFields:[String: Any?]?
Default: nil
Required: No
Description: A dictionary containing profile fields.
The parameter can take both system fields (for example, _fname — first name or _lname — last name) and optional ones (created manually in the platform interface in advance). Allowed structures (JSON-compatible):
- Scalar values:
- String
- Bool
- Int
- Int64 / UInt64 (or
NSNumberequivalents) - Float
- Double
nil
- Objects:
[String: Any?] - Lists:
[Any?] - Arrays of maps:
[[String: Any?]]
If an invalid optional field is passed, the request will fail:
http_code: 400
error: 400
error_text: Platform profile processing error: with field "field_name": Incorrect field
For action field operations on profile fields, use actionField():
AltcraftSDK.shared.push.subscription.subscribe(
profileFields: AltcraftSDK.shared.push.subscription.actionField("orders_count").incr(1)
)
customFields:[String: Any?]?
Default: nil
Required: No
Description: A dictionary containing subscription fields.
The parameter can take both system fields (for example, _device_model — the device model or _os — the operating system) and optional ones (created manually in the platform interface in advance). Allowed value types (JSON-compatible, scalars only):
- String
- Bool
- Int
- Float
- Double
nil
If an invalid optional field is passed, the request will fail:
http_code: 400
error: 400
error_text: Platform profile processing error: field "field_name" is not valid: failed convert custom field
Nested objects, arrays, and collections are not allowed.
Most of the system subscription fields are collected automatically by the SDK and added to push requests. These system fields include: "_os", "_os_tz", "_os_language", "_device_type", "_device_model", "_device_name", "_os_ver", "_ad_track", "_ad_id".
cats:[CategoryData]?
Default: nil
Required: No
Description: Subscription categories.
The category structure:
public struct CategoryData: Codable {
public var name: String?
public var title: String?
public var steady: Bool?
public var active: Bool?
}
When sending a push request with categories, use only the name (category name) and active (category activity status) fields; other fields are not used in request processing. The title and steady fields are filled in when subscription information is received.
Request example:
let cats: [CategoryData] = [CategoryData(name: "football", active: true)]
The categories used in the request must be created in advance and added to the resource in the Altcraft platform. If the request uses a category that is not added to the resource, the request will return with an error:
http_code: 400
error: 400
error_text: Platform profile processing error: field "subscriptions.cats" is not valid: category not found in resource
replace:Bool?
Default: nil
Required: No
Description: When the flag is enabled, all subscriptions of other profiles with the same push token in the current database are moved to the unsubscribed status after a successful request.
skipTriggers:Bool?
Default: nil
Required: No
Description: When the flag is enabled, the profile containing this subscription is ignored in the triggers of mailings and scenarios.
Request implementation examples
Example of a push notification subscription request
Minimal working setup:
AltcraftSDK.shared.push.subscription.subscribe()
Passing all available parameters:
AltcraftSDK.shared.push.subscription.subscribe(
sync: true,
profileFields: ["_fname": "Andrey", "_lname": "Pogodin"],
customFields: ["developer": true],
cats: [CategoryData(name: "developer_news", active: true)],
replace: false,
skipTriggers: false
)
For subscribe, suspend and unsubscribe, the SDK automatically retries the request if the response http code is in the range 500..599. The request is not retried if the response code is outside this range.
The unSuspend() function
The unSuspend() function is designed to create LogIn and LogOut transitions. It works as follows:
- searches for subscriptions with the same push token as the current one that do not belong to the profile the current JWT token points to;
- changes the status of the found subscriptions from
subscribedtosuspended; - changes the status in the subscriptions of the profile the current JWT points to from
suspendedtosubscribed(if the profile the JWT points to exists and contains subscriptions); - returns
ResponseModel.ResponseWithHttpCode<ResponseModel.ResponseWithProfile>?, whereresponse.profileis the current profile the JWT points to (if the profile does not exist,nilis returned).
Usage example:
AltcraftSDK.shared.push.subscription.unSuspend { response in
// handle the response
}
Recommended implementation of LogIn and LogOut transitions
The LogIn transition:
- An anonymous user signs in to the app. This user is assigned
JWT_1pointing to the database #1Anonymous; - A push notification subscription is made, and the profile is created in the database #1Anonymous;
- The user registers and is assigned
JWT_2pointing to the database #2Registered; - The
unSuspend()function is called — the anonymous user's subscription in the database #1Anonymous is suspended; - The profile in the database #2Registered is searched to restore the subscription;
- Since no subscription with such a push token exists in the database #2Registered, the
unSuspend()function will return a profile without a subscription; - After that, a
subscribe()request can be made, which will create a new profile in the #2Registered database.
The LogOut transition:
- The user has logged out of the profile on the app side (
LogOut); - The user is assigned
JWT_1pointing to the database #1Anonymous; - The
unSuspend()function is called, which suspends the subscription in the database #2Registered and changes the subscription status in the #1Anonymous database tosubscribed; - The request returns a non-empty profile — the subscription already exists, no new one is needed.
Implementation example:
func logIn() {
JWTManager.shared.setRegJWT()
// JWT is set for an authorized user
AltcraftSDK.shared.push.subscription.unSuspend { result in
if result?.httpCode == 200, result?.response?.profile?.subscription == nil {
AltcraftSDK.shared.push.subscription.subscribe(
// Specify the required parameters
)
}
}
}
func logOut() {
JWTManager.shared.setAnonJWT()
// JWT is set for an anonymous user
AltcraftSDK.shared.push.subscription.unSuspend { result in
if result?.httpCode == 200, result?.response?.profile?.subscription == nil {
AltcraftSDK.shared.push.subscription.subscribe(
// Specify the required parameters
)
}
}
}
Requesting the subscription status
AltcraftSDK
└── static let shared: AltcraftSDK
└── var push: Push
└── var subscription: SubscriptionAPI
// Status of the profile's latest subscription
├── func latest(
│ completion: @escaping @Sendable (
│ ResponseModel.ResponseWithHttpCode<ResponseModel.ResponseWithProfile>?
│ ) -> Void
│ ): Void
// Status of the subscription for the current push token/provider
├── func current(
│ completion: @escaping @Sendable (
│ ResponseModel.ResponseWithHttpCode<ResponseModel.ResponseWithProfile>?
│ ) -> Void
│ ): Void
// Status of the latest subscription for the specified provider (if nil — the current one is used)
└── func latestForProvider(
provider: String? = nil,
completion: @escaping @Sendable (
ResponseModel.ResponseWithHttpCode<ResponseModel.ResponseWithProfile>?
) -> Void
): Void
Subscription status request functions:
func latest()— the status of the profile's latest subscription;func current()— the status of the subscription for the current push token and provider;func latestForProvider()— the status of the latest subscription for the specified provider. If the provider is not specified (provider = nil), the provider of the current push token is used.
func latest(completion: @escaping @Sendable (ResponseModel.ResponseWithHttpCode<ResponseModel.ResponseWithProfile>?) -> Void): Void
The function returns the status of the profile's latest subscription. The completion receives a ResponseModel.ResponseWithHttpCode<ResponseModel.ResponseWithProfile>? object containing response?.profile?.subscription — the latest subscription created in the profile. If no such subscription exists, nil is passed.
Usage example:
AltcraftSDK.shared.push.subscription.latest { response in
// handle the response
}
func current(completion: @escaping @Sendable (ResponseModel.ResponseWithHttpCode<ResponseModel.ResponseWithProfile>?) -> Void): Void
The function returns the status of the subscription for the current push token and provider. The completion receives a ResponseModel.ResponseWithHttpCode<ResponseModel.ResponseWithProfile>? object containing response?.profile?.subscription — the subscription found by the current push token and provider. If no such subscription exists, nil is passed.
Usage example:
AltcraftSDK.shared.push.subscription.current { response in
// handle the response
}
func latestForProvider(provider: String? = nil, completion: @escaping @Sendable (ResponseModel.ResponseWithHttpCode<ResponseModel.ResponseWithProfile>?) -> Void): Void
The function returns the status of the latest subscription for a provider. The completion receives a ResponseModel.ResponseWithHttpCode<ResponseModel.ResponseWithProfile>? object containing response?.profile?.subscription — the latest subscription created with the specified push notification provider. If the provider is not specified (provider = nil), the provider of the current push token is used. If no such subscription exists, nil is passed.
Usage example:
AltcraftSDK.shared.push.subscription.latestForProvider(provider: nil) { response in
// handle the response
}
Below is an example of extracting profile, subscription, and category data from the response of the status functions. This approach applies to all status functions:
Data from the status functions
AltcraftSDK.shared.push.subscription.current { response in
// HTTP code
let httpCode = response?.httpCode
// Response
let resp = response?.response
let error = resp?.error
let errorText = resp?.errorText
// Profile
let profile = resp?.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
}
If the request completes successfully, a pushStatusRequestSuccessful event is created. In case of an error — pushStatusRequestFailed.
Push: managing push tokens
AltcraftSDK
└── static let shared: AltcraftSDK
└── var push: Push
└── var token: TokenAPI
// Save the token manually
├── func setToken(
│ provider: String,
│ pushToken: Any?
│ ): Void
// Get the current device token data
├── func getToken(
│ completion: (@Sendable (TokenData?) -> Void)? = nil
│ ): Void
// Set the Apple Push Notification service provider (nil — remove)
├── func setAPNSTokenProvider(
│ _ provider: APNSInterface?
│ ): Void
// Set the Firebase Cloud Messaging provider (nil — remove)
├── func setFCMTokenProvider(
│ _ provider: FCMInterface?
│ ): Void
// Set the Huawei Mobile Services provider (nil — remove)
├── func setHMSTokenProvider(
│ _ provider: HMSInterface?
│ ): Void
// Delete the push token of the specified provider
├── func deleteToken(
│ provider: String,
│ completion: (@Sendable () -> Void)? = nil
│ ): Void
// Force a token update (delete → update)
├── func forcedTokenUpdate(
│ completion: (@Sendable () -> Void)? = nil
│ ): Void
// Change the provider priority list and initiate a token update
└── func changeProviderPriority(
_ list: [String]
): Void
Functions for working with the provider token in the SDK:
func setToken()— manually sets the device push token and provider in the local storage;func getToken()— gets the current push token;func setAPNSTokenProvider()— sets and removes the Apple Push Notification service provider;func setFCMTokenProvider()— sets and removes the Firebase Cloud Messaging provider;func setHMSTokenProvider()— sets and removes the Huawei Mobile Services provider;func changeProviderPriority()— dynamically changes the provider order with a push token update of the subscription;func deleteToken()— deletes the push token of the specified provider;func forcedTokenUpdate()— deletes the current push token and then updates it.
func setToken(provider: String, pushToken: Any?): Void
The function is designed to manually set the device push token and provider. It is used as a simplified way of passing a push token to the SDK without implementing the provider protocols.
Using this function to pass the token is not recommended. The recommended approach for passing a push token to the SDK is implementing FCMInterface, HMSInterface, or APNSInterface.
Usage example:
AltcraftSDK.shared.push.token.setToken(provider: "ios-apns", pushToken: "your token")
func getToken(completion: (@Sendable (TokenData?) -> Void)? = nil): Void
The function passes a TokenData(provider: String, token: String) object containing the current device push token and its provider to the completion. If the push token is unavailable, nil is passed to the completion.
Usage example:
AltcraftSDK.shared.push.token.getToken { data in
let provider = data?.provider
let token = data?.token
}
func setFCMTokenProvider(_ provider: FCMInterface?): Void
The function sets or removes the Firebase Cloud Messaging token provider. To disable the provider, pass nil.
Usage example:
AltcraftSDK.shared.push.token.setFCMTokenProvider(FCMProvider())
Call setFCMTokenProvider() in AppDelegate.application(_:didFinishLaunchingWithOptions:) before calling AltcraftSDK.shared.initialization(). This guarantees that the provider is registered at the start of the app process, regardless of the lifecycle state of other components and whether the app is running in the foreground or background.
func setHMSTokenProvider(_ provider: HMSInterface?): Void
The function sets or removes the Huawei Mobile Services token provider. To disable the provider, pass nil.
AltcraftSDK.shared.push.token.setHMSTokenProvider(HMSProvider())
Call setHMSTokenProvider() in AppDelegate.application(_:didFinishLaunchingWithOptions:) before calling AltcraftSDK.shared.initialization(). This guarantees that the provider is registered at the start of the app process, regardless of the lifecycle state of other components and whether the app is running in the foreground or background.
func setAPNSTokenProvider(_ provider: APNSInterface?): Void
The function sets or removes the Apple Push Notification service token provider. To disable the provider, pass nil.
AltcraftSDK.shared.push.token.setAPNSTokenProvider(APNSProvider())
Call setAPNSTokenProvider() in AppDelegate.application(_:didFinishLaunchingWithOptions:) before calling AltcraftSDK.shared.initialization(). This guarantees that the provider is registered at the start of the app process, regardless of the lifecycle state of other components and whether the app is running in the foreground or background.
func changeProviderPriority(_ list: [String]): Void
The function allows you to dynamically change the push provider with a subscription token update. To do this, pass a new array with a different provider order. For example: [PushConstants.ProviderName.firebase, PushConstants.ProviderName.apns, PushConstants.ProviderName.huawei].
Usage example:
AltcraftSDK.shared.push.token.changeProviderPriority([
PushConstants.ProviderName.firebase,
PushConstants.ProviderName.apns,
PushConstants.ProviderName.huawei
])
func deleteToken(provider: String, completion: (@Sendable () -> Void)? = nil): Void
The function deletes the push token of the specified provider. The token is invalidated and removed from the local cache on the device and from the push provider's server. After deletion, a new token can be requested. For the APNs provider, deletion is not supported — the apnsIsNotUpdated error is recorded.
Usage example:
AltcraftSDK.shared.push.token.deleteToken(provider: "ios-firebase") {
// the token is deleted
}
func forcedTokenUpdate(completion: (@Sendable () -> Void)? = nil): Void
The function deletes the current push token and then updates it. For APNs, the operation is not supported — the apnsIsNotUpdated error is recorded.
Usage example:
AltcraftSDK.shared.push.token.forcedTokenUpdate {
// the token is updated
}
Provider registration example
We do not recommend using the setToken function to set the push token. Instead, configure the token retrieval functions for each provider you use. Below is an example implementation of this approach:
Recommended way to register providers in AppDelegate
class AppDelegate: UIResponder, UIApplicationDelegate {
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.push.token.setAPNSTokenProvider(APNSProvider())
// FCM provider
AltcraftSDK.shared.push.token.setFCMTokenProvider(FCMProvider())
// HMS provider
AltcraftSDK.shared.push.token.setHMSTokenProvider(HMSProvider())
AltcraftSDK.shared.push.notificationManager.registerForPushNotifications(for: application)
let config = AltcraftConfiguration.Builder(
apiUrl: "your api url"
).build()
AltcraftSDK.shared.initialization(configuration: config)
return true
}
}
Push: passing push notifications to the SDK
// Used inside a Notification Service Extension (NSE) — a facade for handling
// Altcraft push notifications, detecting Altcraft notifications, and registering goals
// without depending on UIApplication
AltcraftNSE
// Shared (singleton) instance for centralized NSE logic
├─ static let shared: AltcraftNSE
// Check whether the notification belongs to Altcraft
├─ func isAltcraftPush(
│ _ request: UNNotificationRequest
│ ) -> Bool
// Handle an incoming Altcraft notification: pass the modified content to the contentHandler
├─ func handleNotificationRequest(
│ request: UNNotificationRequest,
│ contentHandler: @escaping (UNNotificationContent) -> Void
│ ): Void
// Called when the NSE time expires
├─ func serviceExtensionTimeWillExpire(): Void
// Set up the App Group and initialize the shared data container
├─ func setAppGroup(groupName: String?): Void
// Register a JWT provider
└─ func setJWTProvider(provider: JWTInterface): Void
Functions of the AltcraftNSE class:
func isAltcraftPush()— checks the notification source;func handleNotificationRequest()— receives aUNNotificationRequestfrom the Notification Service Extension for further processing on the SDK side;func serviceExtensionTimeWillExpire()— called when the Notification Service Extension time expires (~30 seconds).
func isAltcraftPush(_ request: UNNotificationRequest) -> Bool
An SDK function that checks whether the notification source is Altcraft by the marker in userInfo.
Usage example:
let isAltcraft = AltcraftNSE.shared.isAltcraftPush(request)
func handleNotificationRequest(request: UNNotificationRequest, contentHandler: @escaping (UNNotificationContent) -> Void): Void
An SDK function that receives a UNNotificationRequest from the Notification Service Extension to process it on the SDK side and then display the notification.
Usage example:
if AltcraftNSE.shared.isAltcraftPush(request) {
AltcraftNSE.shared.handleNotificationRequest(request: request) { content in
contentHandler(content)
}
}
func serviceExtensionTimeWillExpire()
The function called by the system when the Notification Service Extension time expires (~30 seconds).
Usage example:
AltcraftNSE.shared.serviceExtensionTimeWillExpire()
func setAppGroup(groupName: String?): Void
The function sets the AppGroup identifier (a mandatory setup). In the NSE, it is called before processing notifications.
Usage example:
AltcraftNSE.shared.setAppGroup(groupName: "group.your.app.id")
func setJWTProvider(provider: JWTInterface): Void
The function sets the JWT provider:
AltcraftNSE.shared.setJWTProvider(provider: jwtProvider)
Receiving notifications in the app
By default, the SDK handles incoming push notifications: NotificationManager becomes the delegate of the notification center, displays notifications, and performs the standard click handling logic.
If the app needs access to the notification content in the foreground (for example, for analytics or a custom UI) or to the notification data on click, use NotificationManager.
Notification center events (published by the SDK in NotificationCenter):
.altcraftPushWillPresent— the notification is displayed in the foreground,userInfo: ["notification": UNNotification];.altcraftPushDidReceive— the user tapped the notification or performed an action,userInfo: ["response": UNNotificationResponse].
Delegation modes for handing processing over to the app:
customPushProcessing—true— handling and choosing how to display the notification in the foreground is passed to the app;false— the SDK uses the standard display logic;customClickProcessing—true— notification click handling is passed entirely to the app;false— the SDK uses the standard click handling logic.
Receiving a foreground notification in the app (optional)
The setup described below is required only if you need access to the notification content in the foreground or want to control the display yourself (show/hide the notification, change the presentation options).
// Access to the SDK push notification manager
let manager = AltcraftSDK.shared.push.notificationManager
// Controls push notification handling in the foreground.
// true — handling and choosing how to display the notification is passed to the app.
// false — the SDK uses the standard notification display logic.
manager.customPushProcessing = false
// Callback for handling push notifications in the foreground.
// Called when a notification arrives while the app is active.
// complete(...) must be called only when customPushProcessing = true.
manager.onForegroundNotification = { notification, complete in
// Custom notification handling logic
// Important: call complete(...) only if manager.customPushProcessing = true
if #available(iOS 14.0, *) {
complete([.banner, .badge, .sound])
} else {
complete([.alert, .badge, .sound])
}
// or [] to not display the notification
}
If customPushProcessing = false, the SDK applies the standard notification presentation options, and the callback (if set) is called only for additional app logic. If customPushProcessing = true, the app must call complete(...) itself, otherwise the notification may not be displayed in the foreground.
Receiving a notification click event in the app (optional)
The setup described below is required only if the app needs access to the notification data on click, requires its own logic for handling transitions or actions, or needs to fully intercept click handling on the app side.
let manager = AltcraftSDK.shared.push.notificationManager
// Controls notification click handling.
// true — click handling is passed entirely to the app.
// false — the SDK uses the standard click handling logic.
manager.customClickProcessing = true
// Notification click handling callback.
// Called when the notification or an action is tapped.
// complete() must be called when customClickProcessing = true.
manager.onNotificationClick = { response, complete in
// Notification data
let userInfo = response.notification.request.content.userInfo
// Custom click handling logic
print("push click")
// Finish handling
complete()
}
If customClickProcessing = false, the SDK handles the notification click itself, sends the corresponding events, and finishes the processing. In this case, the onNotificationClick callback (if set) is called only for additional app logic.
If customClickProcessing = true, the app must call complete(). Without calling complete(), iOS will consider the click handling incomplete, which may lead to incorrect app behavior.
Push events: delivery and opening
AltcraftSDK
└── static let shared: AltcraftSDK
└── var push: Push
└── var pushEvents: EventAPI
// Report the delivery of a push notification
├── func deliveryEvent(
│ from request: UNNotificationRequest
│ ): Void
// Report the opening of a push notification
└── func openEvent(
from request: UNNotificationRequest
): Void
Push notification event registration functions:
func deliveryEvent()— reports the delivery of a push notification to the device. With standard SDK handling, it is registered automatically;func openEvent()— reports that the user opened the push notification. If you handle clicks yourself (customClickProcessing = true), the open event must be registered manually.
Usage example:
AltcraftSDK.shared.push.pushEvents.openEvent(from: request)
Goals (target)
The target module registers goals (mobile events) — events on the Altcraft platform: installs, purchases, subscriptions, and others, to which pixels, segments, and scenarios are linked on the platform.
AltcraftSDK
└── static let shared: AltcraftSDK
└── var target: Target
// Send a goal (a target event) to the server
└── func sendTarget(
sid: String,
altcraftClientID: 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
): Void
Use case: passing advertising campaign information
Information about the app's advertising campaign that led to the install can be passed to the platform as the values of the profileFields/customFields parameters of the subscribe function, as well as the utm or payload parameters of the sendTarget() function. Having received the UTM tag in the app as a string, call the sendTarget() function:
Passing via payload
AltcraftSDK.shared.target.sendTarget(
sid: "your sid",
eventName: "app_install",
payload: ["utm": "your utm tag"]
)
Passing to the UTM fields
AltcraftSDK.shared.target.sendTarget(
sid: "your sid",
eventName: "app_install",
utm: UTM(
campaign: "your campaign utm",
content: "your content utm",
keyword: "your keyword utm",
medium: "your medium utm",
source: "your source utm",
temp: "your temp utm"
)
)

Passing to a custom profile field
// passing the utm tag to a profile field
// profile fields must be added to the platform in advance
AltcraftSDK.shared.push.subscription.subscribe(
profileFields: ["utm": "your utm tag"]
)

The data passed in any of these ways can be used to create a segment on the platform.
Note that on iOS, the app must use AppsFlyer, otherwise the UTM tag will not be passed to the app.
To register a goal, use the sendTarget() function. It has the following parameters:
sid: String
Required: Yes
Description: The string identifier of the pixel the goals are linked to.
altcraftClientID: String
Default: ""
Required: No
Description: The Altcraft client identifier.
eventName: String
Required: Yes
Description: The goal name (mobile event).
sendMessageId: String?
Required: No
Description: The SMID identifier of the sent message (if the goal is related to a specific mailing).
payload: [String: Any?]?
Required: No
Description: The goal data — a map with string keys, for which only scalar data types are allowed:
- String
- Bool
- Int
- Int64 / UInt64 (or
NSNumberequivalents) - Float
- Double
nil
Non-serializable objects (for example, a Date without conversion, custom classes) will cause an encoding error.
matching: [String: Any?]?
Required: No
Description: A map into which values with matching types and identifiers can be passed.
matchingType: String?
Required: No
Description: The matching type.
profileFields: [String: Any?]?
Required: No
Description: Profile fields — a map with string keys and values (JSON-compatible types):
- Scalar values:
- String
- Bool
- Int
- Int64 / UInt64 (or
NSNumberequivalents) - Float
- Double
nil
- Objects:
[String: Any?] - Lists:
[Any?] - Arrays of maps:
[[String: Any?]]
The parameter is used only with JWT authorization.
utm: UTM?
Required: No
Description: UTM tags. Added using the UTM struct, where each UTM type is a separate property of the struct.
public struct UTM: Codable {
public let campaign: String?
public let content: String?
public let keyword: String?
public let medium: String?
public let source: String?
public let temp: String?
}
subscription: (any Subscription)?
Required: No
Description: The parameter for adding a subscription for the selected channel.
The parameter values are implementations of the Subscription protocol:
EmailSubscription— an email subscriptionSmsSubscription— an SMS subscriptionPushSubscription— a push subscriptionCcDataSubscription— a subscription in Telegram, Whatsapp, Viber, Notify.
Used only with JWT authorization.
Implementations of the Subscription protocol
The common model: Subscription
Purpose — the base protocol for all subscription types.
Serialization is polymorphic; the discriminator field is channel.
Common fields (for all implementations):
| Field | Type | Required | Description |
|---|---|---|---|
resource_id | Int | Yes | Identifier of the subscription resource/source |
status | String? | No | Subscription status (for example, active/suspended) |
priority | Int? | No | Delivery priority for this subscription |
custom_fields | [String: JSONValue]? | No | Custom fields (key-value) for advanced segmentation |
cats | [String]? | No | Subscription categories |
channel | String | Yes | Channel type; fixed by the implementation. |
Subscription variants:
EmailSubscription (channel = "email")
Main fields
| Field | Type | Required | Description |
|---|---|---|---|
resourceId | Int | Yes | Altcraft resource ID |
email | String | Yes | The recipient's email address |
Additional fields
| Field | Type | Required | Description |
|---|---|---|---|
status | String? | No | Subscription status |
priority | Int? | No | Subscription priority |
customFields | [String: JSONValue]? | No | Standard and custom subscription fields |
cats | [String]? | No | Subscription categories |
SmsSubscription (channel = "sms")
Main fields
| Field | Type | Required | Description |
|---|---|---|---|
resourceId | Int | Yes | Altcraft resource ID |
phone | String | Yes | Phone number in international format |
Additional fields
| Field | Type | Required | Description |
|---|---|---|---|
status | String? | No | Subscription status |
priority | Int? | No | Subscription priority |
customFields | [String: JSONValue]? | No | Standard and custom subscription fields |
cats | [String]? | No | Subscription categories |
PushSubscription (channel = "push")
Main fields
| Field | Type | Required | Description |
|---|---|---|---|
resourceId | Int | Yes | Altcraft resource ID |
provider | String | Yes | Provider (for example, "ios-apns") |
subscriptionId | String | Yes | Unique subscription identifier at the provider |
Additional fields
| Field | Type | Required | Description |
|---|---|---|---|
status | String? | No | Subscription status |
priority | Int? | No | Subscription priority |
customFields | [String: JSONValue]? | No | Standard and custom subscription fields |
cats | [String]? | No | Subscription categories |
CcDataSubscription (channel ∈ {"telegram_bot","whatsapp","viber","notify"})
Main fields
| Field | Type | Required | Description |
|---|---|---|---|
resourceId | Int | Yes | Altcraft resource ID |
channel | String | Yes | One of: "telegram_bot", "whatsapp", "viber", "notify" |
ccData | [String: JSONValue] | Yes | Channel-specific data (for example, chat ID, phone number, tokens) |
Additional fields
| Field | Type | Required | Description |
|---|---|---|---|
status | String? | No | Subscription status |
priority | Int? | No | Subscription priority |
customFields | [String: JSONValue]? | No | Standard and custom subscription fields |
cats | [String]? | No | Subscription categories |
Profile: updating profile fields
Updating profile fields with the updateProfileFields() function works only with JWT authorization of the SDK API requests.
AltcraftSDK
└── static let shared: AltcraftSDK
└── var profile: Profile
// Updates the Altcraft profile fields
└── var update: UpdateAPI
└── func updateProfileFields(
profileFields: [String: Any?]? = nil,
skipTriggers: Bool? = nil
): Void
To update profile fields, use the updateProfileFields() function. It has the following parameters:
profileFields: [String: Any?]?
Required: No
Description: Profile fields — a map containing the values for the fields to be changed (JSON-compatible types):
- Scalar values:
- String
- Bool
- Int
- Int64 / UInt64 (or
NSNumberequivalents) - Float
- Double
nil
- Objects:
[String: Any?] - Lists:
[Any?] - Arrays of maps:
[[String: Any?]]
For the update to succeed, the fields must be added to the subscriber profile in advance.
skipTriggers:Bool?
Default: nil
Required: No
Description: When the flag is enabled, the profile containing this subscription is ignored in the triggers of mailings and scenarios.
Usage example:
AltcraftSDK.shared.profile.update.updateProfileFields(
profileFields: ["_fname": "Andrey"]
)
In-App notifications
AltcraftSDK
└── static let shared: AltcraftSDK
└── var inApp: InApp
// Subscribe to the app lifecycle for automatic In-App display
├── func registerLifecycleTracking(): Void
// Set the current screen marker (used when filtering In-App notifications)
├── func setScreen(screen: String): Void
// Trigger an In-App notification by name
├── func trigger(name: String): Void
// Request the available In-App placements
├── func getPlacements(): Void
// Configure the In-App notification animation
├── func animation(_ block: @escaping @MainActor (InAppAnimator) -> Void): Void
// Manage In-App notification subscriptions
└── var subscription: SubscribeAPI
// Subscribe to In-App notifications (status = SUBSCRIBED)
├── func subscribe(
│ sync: Bool = true,
│ profileFields: [String: Any?]? = nil,
│ customFields: [String: Any?]? = nil,
│ cats: [CategoryData]? = nil,
│ replace: Bool? = nil,
│ skipTriggers: Bool? = nil
│ ): Void
// Unsubscribe from In-App notifications (status = UNSUBSCRIBED)
├── func unSubscribe(
│ sync: Bool = true,
│ profileFields: [String: Any?]? = nil,
│ customFields: [String: Any?]? = nil,
│ cats: [CategoryData]? = nil,
│ replace: Bool? = nil,
│ skipTriggers: Bool? = nil
│ ): Void
// In-App notification subscription status
└── func getSubscriptionStatus(
completion: @escaping @Sendable (
ResponseModel.ResponseWithHttpCode<ResponseModel.ResponseWithProfile>?
) -> Void
): Void
Functions for working with In-App notifications:
func registerLifecycleTracking()— registers app lifecycle observers for automatic In-App notification display;func setScreen()— sets the current screen marker, used when filtering In-App notifications. When the screen changes, the SDK automatically generates anopenPagetrigger (of thedefaulttype);func trigger()— triggers an In-App notification by name (of thecustomtype);func getPlacements()— requests the available In-App placements from the server;func animation()— configures the In-App notification display animation;func subscription.subscribe()— subscribes to In-App notifications;func subscription.unSubscribe()— unsubscribes from In-App notifications;func subscription.getSubscriptionStatus()— returns the In-App notification subscription status.
func registerLifecycleTracking()
The function registers app lifecycle observers for automatic In-App notification display. After registration, the SDK tracks the UIApplication.didBecomeActiveNotification event and generates an openApp trigger (of the default type) once when the app first enters the foreground.
Call registerLifecycleTracking() as early as possible at app startup — in AppDelegate.application(_:didFinishLaunchingWithOptions:). This is necessary so that the lifecycle observers have time to register before the app first enters the foreground. If the call is delayed, In-App notifications that should have been shown at app startup may be missed.
Usage example:
AltcraftSDK.shared.inApp.registerLifecycleTracking()
func setScreen(screen: String)
The function sets the current screen marker. The marker value is used by the Altcraft platform when filtering In-App notifications — it allows showing notifications only on specific screens of the app.
When the screen changes, the SDK automatically generates an openPage trigger (of the default type). Call this function when navigating to a new screen so that the SDK always knows which screen the user is on.
Usage example:
AltcraftSDK.shared.inApp.setScreen(screen: "home_screen")
func trigger(name: String)
The function allows you to manually launch the display of an In-App notification by its name. It generates a trigger of the custom type with the specified name. It is used when a notification needs to be shown in response to a user action or an event in the app.
Usage example:
AltcraftSDK.shared.inApp.trigger(name: "my_custom_trigger")
func getPlacements()
The function requests the available In-App placements from the Altcraft server. The request result can be obtained through SDK events.
If the inAppAutoRequest = true parameter is set in the SDK configuration, placements are requested automatically at initialization and then at the placementsRequestInterval interval. Before an automatic request, the SDK checks the time of the last successful request: if the configured interval has not elapsed yet, the automatic request is not performed. A manual getPlacements() call is not limited by the interval. Without this parameter, requests are made only on an explicit getPlacements() call or when triggers fire.
Usage example:
AltcraftSDK.shared.inApp.getPlacements()
func animation(_ block: @escaping @MainActor (InAppAnimator) -> Void)
The function allows you to configure a custom animation for displaying an In-App notification. It takes a closure with an InAppAnimator parameter that provides access to the UIView and companyId after the static resources are loaded.
The InAppAnimator protocol:
public protocol InAppAnimator {
// Identifier of the campaign associated with the animator
var companyId: Int { get }
// Applies changes to the view without animation
@MainActor
func prepare(_ block: (UIView) -> Void)
// Runs a UIKit animation for the In-App view
@MainActor
func animate(
duration: TimeInterval,
delay: TimeInterval,
options: UIView.AnimationOptions,
animations: @escaping (UIView) -> Void,
completion: ((Bool) -> Void)?
)
}
Usage example:
AltcraftSDK.shared.inApp.animation { animator in
animator.animate(
duration: 0.3,
delay: 0,
options: .curveEaseInOut,
animations: { view in
view.alpha = 1.0
},
completion: nil
)
}
func subscription.subscribe(sync: Bool, ...)
The function subscribes to In-App notifications. After a successful call, the user profile will be subscribed to receiving In-App notifications from the Altcraft platform.
The function parameters are the same as the parameters of subscribe():
sync— the flag that sets whether the request is executed synchronously;profileFields— profile fields;customFields— subscription fields;cats— subscription categories;replace— when enabled, replaces the existing subscription;skipTriggers— when enabled, the profile is ignored in the triggers of mailings and scenarios.
The parameters are configured exactly the same way as in subscribe().
Usage example:
AltcraftSDK.shared.inApp.subscription.subscribe()
func subscription.unSubscribe(sync: Bool, ...)
The function cancels the subscription to In-App notifications. After a successful call, the user profile will be unsubscribed from receiving In-App notifications.
The function parameters are the same as the parameters of unsubscribe().
Usage example:
AltcraftSDK.shared.inApp.subscription.unSubscribe()
func subscription.getSubscriptionStatus(completion: @escaping @Sendable (ResponseModel.ResponseWithHttpCode<ResponseModel.ResponseWithProfile>?) -> Void)
The function returns the current In-App notification subscription status. The completion receives a ResponseModel.ResponseWithHttpCode<ResponseModel.ResponseWithProfile>? object containing response?.profile?.subscription — the profile's current In-App notification subscription. If the request fails, nil is passed. The absence of a subscription is determined by the value response?.profile?.subscription == nil.
Usage example:
AltcraftSDK.shared.inApp.subscription.getSubscriptionStatus { response in
let httpCode = response?.httpCode
let resp = response?.response
let profile = resp?.profile
let subscription = profile?.subscription
}
In-App notification display types
The SDK supports the following In-App notification display types:
| Type | Description |
|---|---|
fullscreen | A fullscreen In-App notification |
floating_bar | A floating bar (behavior is the same as fullscreen) |
slideup | A panel sliding out from the top or bottom of the screen. The SDK expects size and position data from JavaScript and then applies the native container. If JavaScript does not respond within 1 second, the notification is displayed as fullscreen |
custom | A custom display (behavior is the same as fullscreen) |
modal | A modal window (behavior is the same as fullscreen) |
In-App notification display restrictions
- In-App notifications are not displayed in landscape screen orientation;
- When the screen is rotated, an open In-App notification is closed;
- In-App notification displays are serialized — only one notification can be shown at a time;
- Non-anonymous In-App campaigns require the
subscribedsubscription status for In-App notifications.