iOS SDK
The Monetai iOS SDK enables you to integrate dynamic pricing and personalized offers directly into your iOS app. This guide walks you through installation, initialization, event tracking, and implementing dynamic pricing with the SDK.
Prerequisites​
- iOS
13.0or higher - Xcode
12.0or higher
Additional Resources​
- GitHub Repository: https://github.com/hayanmind/monetai-ios
- Example Apps: Check out various integration examples in the
Examplesfolder of the GitHub repository- Swift Examples:
SwiftPackageManagerExample,CocoaPodsExample - Objective-C Example:
ObjectiveCExample
- Swift Examples:
Language Support​
The Monetai iOS SDK supports both Swift and Objective-C. Select the appropriate tab below based on your project's language.
SDK Setup​
This section covers how to install the Monetai SDK and configure it to collect the data needed for dynamic pricing.
Please make sure to follow all three steps to lay the foundation for all promotion features.
1. SDK Installation​
Add the Monetai iOS SDK to your project using Swift Package Manager or CocoaPods.
- Swift Package Manager
- CocoaPods
- In Xcode, go to File > Add Package Dependencies
- Enter the repository URL:
https://github.com/hayanmind/monetai-ios - Select the latest version and click Add Package
- Choose your target and click Add Package
Add the following to your Podfile:
pod 'MonetaiSDK'
Then run:
pod install
2. SDK Initialization​
Initialize the SDK when your app launches.
- Swift
- Objective-C
import MonetaiSDK
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Initialize Monetai SDK
Task {
do {
let result = try await MonetaiSDK.shared.initialize(
sdkKey: "YOUR_SDK_KEY", // SDK key issued from Monetai dashboard
userId: "USER_ID", // User ID of your app's user
useStoreKit2: true // Set based on the purchase logic implemented in your app
)
print("Monetai SDK initialization completed:", result)
} catch {
print("Monetai SDK initialization failed:", error)
}
}
return true
}
API Reference
Parameters
| Parameter | Type | Description |
|---|---|---|
| sdkKey | string | SDK key issued from Monetai (Settings > SDK Integration) |
| userId | string | User ID of your app's user (if not available, use a unique identifier such as email or device ID) |
| useStoreKit2 | boolean? | Whether to use StoreKit2 (set based on the purchase logic implemented in your app, default: false) |
Return Value
| Return Value | Type | Description |
|---|---|---|
| organizationId | number | Organization ID |
| platform | 'ios' | Platform info |
| version | string | SDK version |
| userId | string | Set user ID |
#import <MonetaiSDK/MonetaiSDK.h>
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Initialize Monetai SDK
[[MonetaiSDK shared] initializeWithSdkKey:@"YOUR_SDK_KEY"
userId:@"USER_ID"
useStoreKit2:YES
completion:^(InitializeResult * _Nullable result, NSError * _Nullable error) {
if (error) {
NSLog(@"Monetai SDK initialization failed: %@", error);
} else {
NSLog(@"Monetai SDK initialization completed: %@", result);
}
}];
return YES;
}
API Reference
Parameters
| Parameter | Type | Description |
|---|---|---|
| sdkKey | string | SDK key issued from Monetai (Settings > SDK Integration) |
| userId | string | User ID of your app's user |
| useStoreKit2 | boolean? | Whether to use StoreKit2 (set based on the purchase logic implemented in your app, default: false) |
Return Value
| Return Value | Type | Description |
|---|---|---|
| organizationId | number | Organization ID |
| platform | 'ios' | Platform info |
| version | string | SDK version |
| userId | string | Set user ID |
3. Logging User Events​
This is a critical step. Monetai's AI model relies entirely on the user events you log to analyze behavior and predict purchase intent. Without this data, the prediction feature will not function.
- Swift
- Objective-C
import MonetaiSDK
// Basic event logging
await MonetaiSDK.shared.logEvent(eventName: "app_in")
// Event logging with parameters
await MonetaiSDK.shared.logEvent(
eventName: "screen_in",
params: ["screen": "home"]
)
API Reference
Parameters
| Parameter | Type | Description |
|---|---|---|
| eventName | string | Event name |
| params | object? | Event parameters (optional) |
#import <MonetaiSDK/MonetaiSDK.h>
// Basic event logging
[[MonetaiSDK shared] logEventWithEventName:@"app_in" params:nil];
// Event logging with parameters
NSDictionary *params = @{
@"screen": @"home"
};
[[MonetaiSDK shared] logEventWithEventName:@"screen_in" params:params];
API Reference
Parameters
| Parameter | Type | Description |
|---|---|---|
| eventName | string | Event name |
| params | object? | Event parameters (optional) |
- Log all in-app events. Monetai will automatically select events most relevant to non-payer prediction for training.
- If no events are logged, instrument events on key features or buttons, especially those that occur before a purchase.
Events logged before the SDK is initialized are queued and sent automatically once initialization is complete.
Important: Even with the same event name, different parameters create different events that the AI model recognizes separately. Using too many diverse parameter values can reduce model accuracy.
Best Practices:
- Good:
["screen": "home"],["button": "upgrade"],["category": "premium"] - Avoid:
["timestamp": "2024-01-15T10:30:00Z"],["userId": "user123"],["sessionId": "abc123"]
Why? Parameters like timestamps, user IDs, or session IDs create unique events for each occurrence, making it difficult for the model to find patterns. Focus on parameters that represent user behavior categories rather than specific instances.
Implementing Dynamic Pricing​
With the essential setup complete, this section covers how to record product impressions and retrieve personalized offers.
The core workflow is: define aplacementfor each screen and log product views → callgetOffer()to retrieve personalized offers.
1. Logging Product Views​
This step is required. When a user views a product (pricing screen), call logViewProductItem() to record the impression. This data is essential for Monetai to optimize offer targeting — without it, offer personalization will not work correctly.
If your pricing screen displays multiple products, you must call logViewProductItem() for each product individually. Every product shown to the user needs its own log call.
All purchase screens​
Define a descriptive placement value for each screen where products are displayed (e.g., main_paywall, special_offer, bottom_banner). This data helps Monetai optimize pricing. When you later create a promotion for a screen, use the same placement value as the promotion's placement so that historical data is automatically linked. If you've already created a promotion in the dashboard, you can find its placement value in Dashboard → Promotions → Promotion Settings.
- Swift
- Objective-C
import MonetaiSDK
// Log when the user sees the pricing screen — call for each product
await MonetaiSDK.shared.logViewProductItem(
ViewProductItemParams(
placement: "main_paywall",
productId: "premium_monthly",
price: 9.99,
regularPrice: 9.99,
currencyCode: "USD"
)
)
#import <MonetaiSDK/MonetaiSDK.h>
// Log when the user sees the pricing screen — call for each product
ViewProductItemParams *params = [[ViewProductItemParams alloc] initWithPlacement:@"main_paywall"
productId:@"premium_monthly"
price:9.99
regularPrice:9.99
currencyCode:@"USD"
month:nil];
[[MonetaiSDK shared] logViewProductItemWithParams:params];
Pricing optimization screen​
For screens where getOffer() is also used to apply Monetai pricing optimization (see next section), use the same placement value for both logViewProductItem() and getOffer().
- Swift
- Objective-C
// Log when the user sees the pricing screen — call for each product
await MonetaiSDK.shared.logViewProductItem(
ViewProductItemParams(
placement: "special_offer",
productId: "premium_monthly",
price: 4.99,
regularPrice: 9.99,
currencyCode: "USD"
)
)
await MonetaiSDK.shared.logViewProductItem(
ViewProductItemParams(
placement: "special_offer",
productId: "premium_yearly",
price: 39.99,
regularPrice: 79.99,
currencyCode: "USD"
)
)
#import <MonetaiSDK/MonetaiSDK.h>
// Log when the user sees the pricing screen — call for each product
ViewProductItemParams *params1 = [[ViewProductItemParams alloc] initWithPlacement:@"special_offer"
productId:@"premium_monthly"
price:4.99
regularPrice:9.99
currencyCode:@"USD"
month:nil];
[[MonetaiSDK shared] logViewProductItemWithParams:params1];
ViewProductItemParams *params2 = [[ViewProductItemParams alloc] initWithPlacement:@"special_offer"
productId:@"premium_yearly"
price:39.99
regularPrice:79.99
currencyCode:@"USD"
month:nil];
[[MonetaiSDK shared] logViewProductItemWithParams:params2];
API Reference: logViewProductItem()
Parameters (ViewProductItemParams)
| Parameter | Type | Required | Description |
|---|---|---|---|
| placement | String | ✓ | Identifier for the screen or UI component where the product is displayed (e.g., main_paywall, special_offer, bottom_banner). If you've already created a promotion in the dashboard, you can find the placement value in Dashboard → Promotions → Promotion Settings. |
| productId | String | ✓ | Product ID (store product ID) |
| price | Double | ✓ | Displayed price (discounted price) |
| regularPrice | Double | ✓ | Regular price (before discount) |
| currencyCode | String | ✓ | Currency code (e.g., USD, KRW) |
| month | NSNumber? | - | Subscription period in months |
2. Getting Offers​
Call MonetaiSDK.shared.getOffer(placement:) to retrieve a personalized offer for the current user. If the user is eligible for a discount, the SDK returns an Offer object containing the discount details and product information. If not, it returns null.
- If an offer is returned: Apply the optimized discount rate and product info to your existing pricing or promotion screen.
- If
nullis returned: The user belongs to a group where dynamic pricing optimization is not applied. Use your app's existing default discount price.
Each getOffer() call may return a different optimized result for the same user, as the AI model continuously refines its recommendations. If getOffer() is called multiple times while a promotion is active, the discount shown to the user may change unexpectedly.
Example scenario:
- User opens the pricing screen →
getOffer()returns a 30% discount - User navigates away, then returns →
getOffer()is called again → returns a 50% discount - The user sees a different price for the same promotion, causing confusion
Best practice: Call getOffer() once and cache the result while the promotion is active. Do not re-fetch on every screen visit.
If your promotion page displays multiple products (e.g., a monthly plan and a yearly plan) and you have registered both in the agent, products will contain an individually optimized result for each product. For example, if you registered a 1-month and a 12-month product, the response will include optimized pricing for both.
- Swift
- Objective-C
import MonetaiSDK
func showPricingScreen() async {
do {
let offer = try await MonetaiSDK.shared.getOffer(placement: "special_offer")
if let offer = offer {
// Offer available — apply discount to your existing UI
// products contains an optimized result per registered product
print("Agent:", offer.agentName)
print("Products:", offer.products)
for product in offer.products {
print("SKU: \(product.sku), Discount: \(product.discountRate * 100)%")
}
} else {
// No offer — show your app's existing default discount price
showDefaultPrice()
}
} catch {
print("Failed to get offer:", error)
showDefaultPrice()
}
}
API Reference
Parameters
| Parameter | Type | Description |
|---|---|---|
| placement | String | Unique identifier for the screen where pricing optimization is applied. Use the same value defined in logViewProductItem(). If a promotion has already been created in the dashboard, you can find the placement value in Dashboard → Promotions → Promotion Settings. |
Return Value: Offer? (null when not eligible)
Offer Type
| Property | Type | Description |
|---|---|---|
| agentId | Int | Agent ID |
| agentName | String | Agent name |
| products | [OfferProduct] | List of offer products |
OfferProduct Type
| Property | Type | Description |
|---|---|---|
| name | String | Product name |
| sku | String | Product SKU (store product ID) |
| discountRate | Double | Discount rate (0-1 range, e.g. 0.5 = 50%) |
| isManual | Bool | Whether the discount is manually configured |
#import <MonetaiSDK/MonetaiSDK.h>
- (void)showPricingScreen {
[[MonetaiSDK shared] getOfferWithPlacement:@"special_offer"
completion:^(Offer * _Nullable offer, NSError * _Nullable error) {
if (error) {
NSLog(@"Failed to get offer: %@", error);
[self showDefaultPrice];
return;
}
if (offer) {
// Offer available — apply discount to your existing UI
NSLog(@"Agent: %@", offer.agentName);
for (OfferProduct *product in offer.products) {
NSLog(@"SKU: %@, Discount: %.0f%%", product.sku, product.discountRate * 100);
}
} else {
// No offer — show your app's existing default discount price
[self showDefaultPrice];
}
}];
}
API Reference
Parameters
| Parameter | Type | Description |
|---|---|---|
| placement | String | Unique identifier for the screen where pricing optimization is applied. Use the same value defined in logViewProductItem(). If a promotion has already been created in the dashboard, you can find the placement value in Dashboard → Promotions → Promotion Settings. |
Return Value: Offer? (null when not eligible)
Offer Type
| Property | Type | Description |
|---|---|---|
| agentId | Int | Agent ID |
| agentName | String | Agent name |
| products | [OfferProduct] | List of offer products |
OfferProduct Type
| Property | Type | Description |
|---|---|---|
| name | String | Product name |
| sku | String | Product SKU (store product ID) |
| discountRate | Double | Discount rate (0-1 range, e.g. 0.5 = 50%) |
| isManual | Bool | Whether the discount is manually configured |
Managing User State​
SDK Reset​
Initialize the SDK when the user logs out.
- Swift
- Objective-C
import MonetaiSDK
// When user logs out
func logoutUser() {
MonetaiSDK.shared.reset()
print("User logout completed")
}
#import <MonetaiSDK/MonetaiSDK.h>
// When user logs out
- (void)logoutUser {
[[MonetaiSDK shared] reset];
NSLog(@"User logout completed");
}
Support
If you run into any trouble during the integration, don't hesitate to contact us at support@monetai.io.
Next Steps​
With the SDK setup complete, you're ready to start a promotion: