Skip to main content
Altcraft Docs LogoAltcraft Docs Logo
User guide iconUser guide
Developer guide iconDeveloper guide
Admin guide iconAdmin guide
English
  • Русский
  • English
Login
    User API documentationAPI interactionMatching
      Profilesarrow
    • Import profileUpdate profileImport multiple profilesUpdate multiple profilesAdd multiple profilesAdd profile to databaseImport profile to RabbitMQGet profile dataUploading profiles to a fileDelete profileSubscription fields functional updateDatabase fields functional updateMerging multiple profilesUnsubscribe profile from resourceProfile splitting
        Subscriptionsarrow
      • Add or edit subscriptionGet all profile subscriptionsGet all subscriptions from multiple profilesGet profile subscriptionDelete profile subscriptionRestore deleted subscriptionSuspend all subscriptionsUnsuspend all suspended subscriptions
        Action historyarrow
      • Get profile action historyGet multiple profiles action history
        Profile relationsarrow
      • Attach relationDetach relationModify relation propertiesOverwrite relation propertiesGet profile relations infoGet profile relations info
      Get data for multiple profiles
      Databasesarrow
    • Get database statisticsUpdate statistics on databaseGet database listGet database informationGet database fieldsDatabase wipe
      Resourcesarrow
    • Get resource statisticsUpdate statistics on resourceGet resources listGet resource informationGet resource subscription fields
      Segmentsarrow
    • Create segmentGet statistics on resourceUpdate statistics on segmentAdd or remove profileGet profile data in a static segmentUpdate segmentGet segment informationGet segments listDelete segment
      Suppression listsarrow
    • Create suppression listUpdate suppression listGet suppression list infoGet the list of suppression listsDelete suppression listUpload suppression list data to file
        Suppression list actionsarrow
      • Check if email is suppressedAdd email to suppression listAdd multiple emails to suppression listRemove email from suppression listRemove all emails from suppression listCheck if domain is suppressedAdd domain to suppression listAdd multiple domains to suppression listRemove domain from suppression listRemove all domains from suppression listCheck if phone number is suppressedAdd phone number to suppression listAdd multiple phones to suppression listRemove phone number from suppression listRemove all phone numbers from suppression list
      Templates and fragmentsarrow
    • Get templates listGet template infoDelete templateAdd templateUpdate templateChannel object
      Campaignsarrow
    • Get campaign informationGet campaign listActivate campaignComplete campaignDeactivate campaignGet campaign status
      Mailingsarrow
    • Activate mailingDeactivate mailingGet mailing listGet mailing informationGet mailing logClone mailingDelete mailingGet mailing status
        Broadcast mailingsarrow
      • Get broadcasts listGet broadcast informationCreate broadcast mailingUpdate broadcast mailingLaunch a broadcast mailing
        Regular mailingsarrow
      • Get regular mailings listGet regular mailing informationCreate regular mailingUpdate regular mailingLaunch a regular mailing
        Trigger mailingsarrow
      • Get trigger mailings listGet trigger mailing informationCreate trigger mailingUpdate trigger mailingTrigger launch (API call)Profile import + trigger mailing launchTask for bulk trigger launchTask for bulk profiles import + trigger launchBulk trigger launchBulk profiles import + trigger mailing launchClone a trigger mailingData array
      Automation scenariosarrow
    • Engage profile in scenarioImport and engage profile in scenarioBatch import and engage profiles in a scenarioTask for batch import and engaging profiles in the scenarioGet scenarios listActivate scenarioDeactivate scenarioGet scenario informationChange scenario priority
      Loyalty Programsarrow
    • Get profile tier in a loyalty programExport points transactionsExpiring points for a periodGet profile account transactionsGet trigger promotions listAccrue points to a memberRedeem member pointsCommit temporary transactionPreliminary Order CalculationOrder ConfirmationRoll back temporary transactionCancel points transactionGet points account balanceRegister member in a loyalty programBatch adding participants to loyalty programTask for batch add participants to loyalty programRemove member from loyalty program
      Formsarrow
    • Get form informationGet form listExport form fill data by userExport form fill dataPublish formUnpublish formDelete form
      Promo codesarrow
    • Import promo codesGet promo code informationActivate promo codeUpdate promo codeAttach promo codeDetach promo codeGet all promo codes
      Goalsarrow
    • Goals and goal values registration
      Application push notificationsarrow
    • Processing and adding a subscriptionAdd app push events
      Marketarrow
      • Market objectsarrow
      • Order data objectProduct data objectSKU data objectCategories arrayCustom fields array
        Ordersarrow
      • Import order and item statusesGet orders listDelete orderGet order statusUpdate order line status
        Products and SKUarrow
      • Import products, SKUs and categoriesImport SKUs and categoriesGet products listGet SKUs listDelete productsDelete SKU
      Analytic reportsarrow
    • Get summary reportGet soft bounces reportGet undeliveries report
      Sendersarrow
    • Get senders list
        Virtual senders (Smart accounts only)arrow
      • Get virtual senders listGet virtual sender informationClone virtual senderCreate virtual senderUpdate virtual senderDelete virtual sender
      External datatables queriesarrow
      • Segmentation queriesarrow
      • Add segmentation queryUpdate segmentation queryGet segmentation query informationGet segmentation queries listDelete segmentation query
        Template queriesarrow
      • Add template queryUpdate template queryGet template query informationGet template queries listDelete template query
      Objectsarrow
    • AKMTA objectContent objectCustom channels rulesEmail rule objectFile objectProfile data objectSMS rule objectSender objectSender typesStart schedule objectSubscription objectTrigger types
      Miscellaneousarrow
    • Upload fileGet message web versionPush providersDeduplication of requestsHow to send API request with RabbitMQList of gender identificationsObtain valid values for fields: browsers, devices, tz, oses, languages
    Importing the API collection in PostmanList of API endpoints
      SDKarrow
      • mSDKarrow
        • Androidarrow
        • Quick startSDK functionalitySDK ConfigurationPublic SDK API
            Provider setuparrow
          • Firebase Cloud MessagingHuawei Mobile ServicesRuStore
          iOSarrow
        • Quick startSDK configurationSDK functionalityPublic SDK API
            Provider configurationarrow
          • Apple Push Notification ServiceFirebase Cloud MessagingHuawei Mobile Services
          React Native (Android/iOS)arrow
        • Quick StartSDK ConfigurationSDK FunctionalityPublic SDK APIProvider setup
          Flutter (Android/iOS)arrow
        • Quick StartSDK ConfigurationSDK FunctionalitySDK Public APIProvider Setup
        Working with role and JWT tokens
      Web Push SDK
  • SDK
  • mSDK
  • iOS
  • SDK functionality

SDK functionality

tip

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.

Important

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:

ValueMessage
configSetSDK configuration is installed.
sdkClearedSDK data has been cleared
initAwaitwaiting for SDK initialization to complete
userLogOutUser logged out. Anonymous session started
backgroundTaskRegisterSDK background task is registered
backgroundTaskCompletedSDK background task completed
configIsNotSetthe configuration is not set
appGroupIsNotSetApp Group name was not set.
notAuthenticatedErroruser is not authenticated
invalidUrlValueinvalid apiUrl value - empty or null.
invalidRTokenValueinvalid resource token value - resource token is empty.
fieldsIsObjectsinvalid values: not all values are primitives
permissionDeniednotification permission denied.
jwtIsNilJWT token is nil
authenticateSuccessfulsuccessful request: profile/authenticate
authenticateFailedfailed 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:

ValueMessage
pushProviderSetpush provider set:
pushReceivereceived Altcraft push notification.
pushIsPostedpush is posted.
pushTokenUpdateAwaitwaiting for push token update to complete
pushSubscribeRequestSuccessfulsuccessful request: push/subscribe
pushSubscribeRequestFailedfailed request: push/subscribe
pushSuspendRequestSuccessfulsuccessful request: push/suspend
pushSuspendRequestFailedfailed request: push/suspend
pushUnsubscribeRequestSuccessfulsuccessful request: push/unsubscribe
pushUnsubscribeRequestFailedfailed request: push/unsubscribe
tokenUpdateRequestSuccessfulsuccessful request: push/update
tokenUpdateRequestFailedfailed request: push/update
pushStatusRequestSuccessfulsuccessful request: push/status
pushStatusRequestFailedfailed request: push/status
unsuspendRequestSuccessfulsuccessful request: push/unsuspend
unsuspendRequestFailedfailed request: push/unsuspend
pushEventRequestSuccessfulsuccessful request: event/push
pushEventRequestFailedfailed request: event/push
invalidPushProvidersinvalid provider. Available - ios-apns, ios-firebase, ios-huawei.
invalidPushProviderinvalid provider.
errorHandleUserInfoinvalid userInfo format
uidIsNiluid in the push data is null, it is impossible to send a push event to the server.
errorMediaDownloadcould not download image data from URL.
errorMediaKeyMissing'media' key is missing or URL string is invalid.
errorButtonsKeyMissing'buttons' key is missing or is invalid.
invalidButtonIdentifierinvalid button identifier. See event value
outOfRangeForIdentifierout of range for identifier. See event value
unknownButtonIdentifierunknown button identifier. See event value
subscribeRequestDataIsNilsubscribe request data is nil
updateRequestDataIsNilupdate request data is nil
pushEventRequestDataIsNilpush event request data is nil
unsuspendRequestDataIsNilunsuspend request data is nil
pushStatusRequestDataIsNilpush status request data is nil
invalidSubRequestDatainvalid push subscribe request data
invalidPushEventRequestDatainvalid push event request data
pushConfigurationSaveFailedfailed to save the push configuration to the local database
pushConfigurationClearFailedfailed to clear the push configuration from the local database
apnsIsNotUpdatedforcing a push token update is not possible: the operation is not supported for APNs.
pushTokenIsNilcurrent push token is nil

Target:

ValueMessage
mobileRequestDataIsNilmobile event request data is nil
mobileEventRequestSuccessfulsuccessful request: event/post
mobileEventRequestFailedfailed request: event/post

Profile:

ValueMessage
profileUpdateRequestDataIsNilprofile update request data is nil
profileUpdateRequestSuccessfulsuccessful request: profile/update
profileUpdateRequestFailedfailed request: profile/update

In-App:

ValueMessage
errorInAppImageLoadfailed to load in-app image
invalidStaticFieldinvalid in-app static field
smidIsNilsmid in the in-app data is null, it is impossible to send a in-app event to the server.
inAppStatusRequestDataIsNilin-app status request data is nil
inAppEventRequestDataIsNilin-app event request data is nil
subscribeRequestDataIsNilin-app subscribe request data is nil
invalidSubRequestDatainvalid in-app subscribe request data
inAppSubscribeRequestSuccessfulsuccessful request: inapp/subscribe
inAppSubscribeRequestFailedfailed request: inapp/subscribe
inAppUnsubscribeRequestSuccessfulsuccessful request: inapp/unsubscribe
inAppUnsubscribeRequestFailedfailed request: inapp/unsubscribe
inAppStatusRequestSuccessfulsuccessful request: inapp/status
inAppStatusRequestFailedfailed request: inapp/status
inAppEventRequestSuccessfulsuccessful request: inapp/event
inAppEventRequestFailedfailed request: inapp/event
inAppPlacementsRequestSuccessfulsuccessful request: inapp/placements
inAppPlacementsRequestFailedfailed request: inapp/placements
inAppStaticErrorLoaderror loading in-app notification static resources
inAppContentErrorLoaderror loading in-app notification content
maxPlacementsInvalidInvalid in-app configuration: maxPlacements must be >= 1
requestIntervalInvalidInvalid in-app configuration: placementsRequestInterval must be > 0
placementsLimitExceededin-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 create LogIn and LogOut transitions;
  • func actionField() — creates an ActionFieldBuilder for building action field operations (set, unset, incr, add, delete, upsert) on profile fields inside profileFields.

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 = nil is 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;
  • error and error_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 NSNumber equivalents)
    • 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.

Note

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
)
Note

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 subscribed to suspended;
  • changes the status in the subscriptions of the profile the current JWT points to from suspended to subscribed (if the profile the JWT points to exists and contains subscriptions);
  • returns ResponseModel.ResponseWithHttpCode<ResponseModel.ResponseWithProfile>?, where response.profile is the current profile the JWT points to (if the profile does not exist, nil is 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_1 pointing 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_2 pointing 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_1 pointing 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 to subscribed;
  • 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())
Important

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())
Important

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())
Important

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 a UNNotificationRequest from 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"]
)
Goal achieved event from a tracking pixel with UTM parameters

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"
)
)
UTM panel with campaign, source, medium, content and term fields

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"]
)
Profile additional fields tab with the utm field filled

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 NSNumber equivalents)
  • Float
  • Double
  • nil
Note

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 NSNumber equivalents)
    • Float
    • Double
    • nil
  • Objects: [String: Any?]
  • Lists: [Any?]
  • Arrays of maps: [[String: Any?]]
Note

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 subscription
  • SmsSubscription — an SMS subscription
  • PushSubscription — a push subscription
  • CcDataSubscription — a subscription in Telegram, Whatsapp, Viber, Notify.
Note

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):

FieldTypeRequiredDescription
resource_idIntYesIdentifier of the subscription resource/source
statusString?NoSubscription status (for example, active/suspended)
priorityInt?NoDelivery priority for this subscription
custom_fields[String: JSONValue]?NoCustom fields (key-value) for advanced segmentation
cats[String]?NoSubscription categories
channelStringYesChannel type; fixed by the implementation.


Subscription variants:

EmailSubscription (channel = "email")

Main fields

FieldTypeRequiredDescription
resourceIdIntYesAltcraft resource ID
emailStringYesThe recipient's email address

Additional fields

FieldTypeRequiredDescription
statusString?NoSubscription status
priorityInt?NoSubscription priority
customFields[String: JSONValue]?NoStandard and custom subscription fields
cats[String]?NoSubscription categories

SmsSubscription (channel = "sms")

Main fields

FieldTypeRequiredDescription
resourceIdIntYesAltcraft resource ID
phoneStringYesPhone number in international format

Additional fields

FieldTypeRequiredDescription
statusString?NoSubscription status
priorityInt?NoSubscription priority
customFields[String: JSONValue]?NoStandard and custom subscription fields
cats[String]?NoSubscription categories

PushSubscription (channel = "push")

Main fields

FieldTypeRequiredDescription
resourceIdIntYesAltcraft resource ID
providerStringYesProvider (for example, "ios-apns")
subscriptionIdStringYesUnique subscription identifier at the provider

Additional fields

FieldTypeRequiredDescription
statusString?NoSubscription status
priorityInt?NoSubscription priority
customFields[String: JSONValue]?NoStandard and custom subscription fields
cats[String]?NoSubscription categories

CcDataSubscription (channel ∈ {"telegram_bot","whatsapp","viber","notify"})

Main fields

FieldTypeRequiredDescription
resourceIdIntYesAltcraft resource ID
channelStringYesOne of: "telegram_bot", "whatsapp", "viber", "notify"
ccData[String: JSONValue]YesChannel-specific data (for example, chat ID, phone number, tokens)

Additional fields

FieldTypeRequiredDescription
statusString?NoSubscription status
priorityInt?NoSubscription priority
customFields[String: JSONValue]?NoStandard and custom subscription fields
cats[String]?NoSubscription categories

Profile: updating profile fields​


Important

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 NSNumber equivalents)
    • Float
    • Double
    • nil
  • Objects: [String: Any?]
  • Lists: [Any?]
  • Arrays of maps: [[String: Any?]]
Note

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 an openPage trigger (of the default type);
  • func trigger() — triggers an In-App notification by name (of the custom type);
  • 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.

Important

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:

TypeDescription
fullscreenA fullscreen In-App notification
floating_barA floating bar (behavior is the same as fullscreen)
slideupA 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
customA custom display (behavior is the same as fullscreen)
modalA 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 subscribed subscription status for In-App notifications.
Last updated on Nov 5, 2026
Previous
SDK configuration
Next
Public SDK API
  • Core: authentication
    • Clearing SDK data
  • Core: SDK events
    • Subscribing to events
    • Unsubscribing from events
    • List of all SDK events
  • Push: managing subscription statuses
    • Changing the subscription status
    • Requesting the subscription status
  • Push: managing push tokens
    • Provider registration example
  • Push: passing push notifications to the SDK
    • Receiving notifications in the app
    • Receiving a foreground notification in the app (optional)
    • Receiving a notification click event in the app (optional)
    • Push events: delivery and opening
  • Goals (target)
    • Implementations of the Subscription protocol
  • Profile: updating profile fields
  • In-App notifications
    • In-App notification display types
    • In-App notification display restrictions
© 2015 - 2026 Altcraft, LLC. All rights reserved.