본문으로 건너뛰기
📌 8월 넷째주 릴리즈 노트: 프로모션 UI 템플릿 출시! 간단하게 페이월을 만들고 캠페인을 즉시 시작할 수 있어요. 자세히 보기
버전: Legacy

iOS SDK

Monetai iOS SDK는 앱 내에서 구매자를 예측하여 프로모션을 효과적으로 구현할 수 있도록 돕습니다. 이 가이드는 SDK 설치부터 초기화, 주요 기능 사용법까지 전 과정을 안내합니다.

사전 요구사항

  • iOS 13.0 이상
  • Xcode 12.0 이상

📚 추가 자료

  • GitHub 저장소: https://github.com/hayanmind/monetai-ios
  • 예제 앱: GitHub 저장소의 Examples 폴더에서 다양한 통합 예제를 확인하세요
    • Swift 예제: SimpleApp, SwiftPackageManagerExample, CocoaPodsExample
    • Objective-C 예제: SimpleAppObjectiveC

🔧 언어 지원

Monetai iOS SDK는 SwiftObjective-C 모두를 지원합니다. 아래 코드 예제에서 프로젝트의 언어에 맞는 탭을 선택하여 사용하세요.


필수 SDK 연동

📌 이 섹션에서는 Monetai SDK를 설치하고, 구매 예측에 필요한 데이터를 수집하도록 구성하는 필수 단계들을 안내합니다.
모든 프로모션 기능을 원활하게 사용하려면, 아래의 세 가지 필수 단계를 반드시 진행해 주세요.

1. SDK 설치

Swift Package Manager 또는 CocoaPods를 사용하여 프로젝트에 Monetai iOS SDK를 추가합니다.

  1. Xcode에서 File > Add Package Dependencies로 이동
  2. 저장소 URL 입력: https://github.com/hayanmind/monetai-ios
  3. 최신 버전을 선택하고 Add Package 클릭
  4. 타겟을 선택하고 Add Package 클릭

2. SDK 초기화

앱이 시작될 때 SDK를 초기화합니다.

import MonetaiSDK

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

// Monetai SDK 초기화
Task {
do {
let result = try await MonetaiSDK.shared.initialize(
sdkKey: "YOUR_SDK_KEY", // Monetai 대시보드에서 발급받은 SDK 키
userId: "USER_ID", // 앱 사용자의 사용자 ID
useStoreKit2: true // 앱에서 구현한 구매 로직에 따라 StoreKit2 사용 여부 설정
)

print("Monetai SDK 초기화 완료:", result)
} catch {
print("Monetai SDK 초기화 실패:", error)
}
}

return true
}

API 참조

매개변수

매개변수타입설명
sdkKeystringMonetai에서 발급받은 SDK 키 (Settings > SDK Integration)
userIdstring앱 사용자의 사용자 ID (없을 경우 이메일, 디바이스 ID 등 고유 식별값 활용)
useStoreKit2boolean?StoreKit2 사용 여부 (앱에서 구현한 구매 로직에 따라 설정, 기본값: false)

반환값

반환값타입설명
organizationIdnumber조직 ID
platform'ios'플랫폼 정보
versionstringSDK 버전
userIdstring설정된 사용자 ID
groupABTestGroup | nullA/B 테스트 그룹

ABTestGroup 타입

설명
monetai자동 프로모션이 있는 실험 그룹
baseline프로모션이 없는 대조 그룹
unknown캠페인에 포함되지 않은 사용자
null현재 캠페인이 없을 때

3. 사용자 이벤트 기록

정확한 AI 모델 빌딩을 위한 핵심 단계입니다. Monetai의 AI 모델은 앱에서 보내는 사용자 이벤트를 기반으로 행동을 분석하고, 구매 여부를 예측합니다. 이 데이터가 없으면 구매 예측 기능이 동작하지 않으므로, 반드시 필요한 과정입니다.

import MonetaiSDK

// 기본 이벤트 로깅
await MonetaiSDK.shared.logEvent(eventName: "app_in")

// 매개변수가 있는 이벤트 로깅
await MonetaiSDK.shared.logEvent(
eventName: "screen_in",
params: ["screen": "home"]
)

API 참조

매개변수

매개변수타입설명
eventNamestring이벤트 이름
paramsobject?이벤트 매개변수 (선택사항)
이벤트 로깅 Tips
  • 앱에서 수집하는 모든 이벤트를 로깅하면, Monetai가 비구매자 예측에 상관성이 높은 이벤트를 자동으로 선별하여 학습에 활용합니다.
  • 수집중인 이벤트가 없는 경우 앱의 주요 기능이나 버튼, 특히 구매 이전에 발생하는 행동들에 이벤트를 심는 것을 권장합니다.
초기화 전 이벤트 처리

초기화가 완료되기 전에 발생한 이벤트는 큐(Queue)에 저장되었다가, 초기화가 완료된 후 자동으로 전송됩니다.

파라미터 사용 가이드라인

중요: 같은 이벤트 이름이라도 파라미터가 다르면 AI 모델이 별개의 이벤트로 인식합니다. 파라미터 값이 너무 다양하면 모델의 정확도가 떨어질 수 있습니다.

모범 사례:

  • 좋음: ["screen": "home"], ["button": "upgrade"], ["category": "premium"]
  • 피하기: ["timestamp": "2024-01-15T10:30:00Z"], ["userId": "user123"], ["sessionId": "abc123"]

이유: 시간, 사용자 ID, 세션 ID와 같은 파라미터는 매번 고유한 이벤트를 생성하여 모델이 패턴을 찾기 어렵게 만듭니다. 구체적인 인스턴스보다는 사용자 행동 카테고리를 나타내는 파라미터에 집중하세요.


프로모션 기능 구현

📌 필수 연동이 완료되었다면, 이제 프로모션 로직을 구현할 차례입니다.
구매 예측을 요청하고 그 결과를 활용하여 사용자에게 맞춤 프로모션 UI를 보여주는 방법을 확인해 보세요.

1. 구매 예측하기

사용자가 상품을 구매할지 예측하려면, 앱 내 핵심적인 구매 결정 순간predict() 함수를 호출하세요.

[권장] predict 함수는 1개의 시점에만 호출하세요!
  • 사용자 경험을 최적화하고 캠페인 성과를 가장 명확하게 측정하기 위해, predict() 함수는 1개의 시점에만 호출하는 것을 권장합니다.
  • 사용자가 상품의 가치를 충분히 인지하고, 구매를 가장 망설이는 순간에 호출하는 것이 가장 효과적입니다.
    앱의 특성에 따라 아래와 같은 시점을 고려해볼 수 있습니다.
    • 정상가 구독 페이지를 이탈했을 때
    • 메인 플로우를 완료했을 때
    • 프리미엄 기능을 사용하려고 시도했을 때
import MonetaiSDK

func predictUserPurchase() async {
do {
let result = try await MonetaiSDK.shared.predict()

print("예측 결과:", result.prediction)
print("테스트 그룹:", result.testGroup)

if result.prediction == .nonPurchaser {
// 미구매자로 예측될 때 할인 제공
print("미구매자로 예측됨 - 할인 적용 가능")
} else if result.prediction == .purchaser {
// 구매자로 예측될 때
print("구매자로 예측됨 - 할인 불필요")
}
} catch {
print("예측 실패:", error)
}
}

API 참조

반환값

반환값타입설명
predictionPredictResult예측 결과
testGroupABTestGroupA/B 테스트 그룹

PredictResult 타입

설명
nonPurchaser구매하지 않을 것으로 예측
purchaser구매할 것으로 예측
null예측할 수 없음 (모델 생성 전이거나 활성 캠페인 없음)
predict() 함수 중요 참고사항
  1. 여러 번 호출하는 경우
    • 이전에 predict()를 호출해서 프로모션이 활성화된 상태에서는 predict()를 여러 번 호출해도 새로운 프로모션이 시작되지 않습니다.
  2. 프로모션 다시 시작
    • 프로모션 기간이 종료된 후에 predict()를 다시 호출하면, 사용자가 여전히 비구매자로 예측되는 경우 새로운 프로모션이 시작됩니다.
  3. 유료 구독 사용자 제외 - 이미 유료 구독 중인 사용자에게는 프로모션을 제공하지 않으려면, 해당 사용자에 대해서는 predict() 함수를 호출하지 않도록 처리해야 합니다.

2. 프로모션 UI 노출하기

predict()호출 결과 사용자가 미구매자로 예측되면, SDK는 onDiscountInfoChange 콜백을 통해 할인 정보를 전달합니다. 이 정보로 사용자에게 프로모션 UI를 보여줄 수 있습니다.

A. UI 템플릿 사용하기 (권장)

MonetaiSDK.shared.configurePaywall()paywallConfig를 전달하세요. predict() 호출 결과 사용자가 미구매자로 예측되고 할인이 유효 기간 내에 있을 때, 배너/페이월이 자동으로 나타납니다.

Paywall UI 템플릿 지원

Paywall UI 템플릿은 iOS SDK 1.2.0 이상에서 지원됩니다.

UI 템플릿 살펴보기

사용 가능한 템플릿 스타일과 예제를 확인하세요: UI 템플릿 디자인 가이드

import MonetaiSDK

class ViewController: UIViewController {

override func viewDidLoad() {
super.viewDidLoad()

// 페이월 설정
configurePaywall()

// 구독 상태 설정 (실제 사용자의 구독 상태에 따라서 초기 값을 설정해야합니다.)
MonetaiSDK.shared.setSubscriptionStatus(false)
}

private func configurePaywall() {
let features = [
Feature(title: "모든 프리미엄 기능", description: "모든 것을 잠금 해제", isPremiumOnly: true),
Feature(title: "고급 분석", description: "인사이트와 상세 보고서"),
Feature(title: "우선 지원", description: "24/7 고객 지원")
]

let config = PaywallConfig(
discountPercent: 50,
regularPrice: "$10.00",
discountedPrice: "$5.00",
locale: "ko",
style: .highlightBenefits,
features: features,
enabled: true,
bannerBottom: 20
)

config.onPurchase = { [weak self] close in
// TODO: 구매 플로우 트리거
// 성공 시 페이월을 닫고 구독자 상태 업데이트
close()
MonetaiSDK.shared.setSubscriptionStatus(true)
}

config.onTermsOfService = {
// TODO: 이용약관 열기
}

config.onPrivacyPolicy = {
// TODO: 개인정보처리방침 열기
}

MonetaiSDK.shared.configurePaywall(config)
}
}

PaywallConfig

타입필수설명
discountPercentInt할인 퍼센트 (0-100)
regularPriceString정상가 라벨
discountedPriceString할인가 라벨
localeString언어 코드 (예: "ko", "en")
stylePaywallStyle템플릿 스타일
features[Feature]-.highlightBenefits 또는 .keyFeatureSummary에만 필요
enabledBool-자동 배너/페이월 표시 활성화 (기본값: true)
bannerBottomCGFloat-플로팅 배너의 하단 오프셋 (기본값: 20)

PaywallStyle 타입

설명
.compact컴팩트 디자인
.highlightBenefits혜택 강조 디자인
.keyFeatureSummary주요 기능 요약 디자인
.textFocused텍스트 중심 디자인

Feature 모델

속성타입설명
titleString기능 제목
descriptionString기능 설명
isPremiumOnlyBool프리미엄 전용 기능 여부 (기본값: false)

콜백

콜백타입설명
onPurchase((@escaping () -> Void) -> Void)?구매 버튼 콜백 (성공 시 close() 호출)
onTermsOfService(() -> Void)?이용약관 클릭 콜백
onPrivacyPolicy(() -> Void)?개인정보처리방침 클릭 콜백

구독 상태 관리

SDK는 사용자의 구독 상태에 따라 배너/페이월 표시를 자동으로 제어합니다. 다음 메서드를 사용하여 구독 상태를 관리하세요:

// 초기 구독 상태 설정 (configurePaywall 전후 언제든지 호출 가능)
MonetaiSDK.shared.setSubscriptionStatus(true) // true는 구독자, false는 비구독자

자동 배너 제어

페이월이 설정되면 SDK는 자동으로:

  • 할인이 활성화되어 있고, 페이월이 활성화되어 있으며, 사용자가 구독자가 아닌 경우 배너를 표시합니다.
  • 사용자가 구독자이거나, 할인이 없거나, 할인이 만료되었거나, 페이월이 비활성화된 경우 배너를 숨깁니다.

B. UI 직접 구현하기 (고급)

B-1. onDiscountInfoChange 콜백을 활용한 구현

프로모션 화면 구현

프로모션 화면을 직접 구현할 수 있습니다. Monetai SDK가 제공하는 할인 적용 시점(startedAt, endedAt) 정보와 onDiscountInfoChange 콜백을 활용, 실제 UI 컴포넌트와 프로모션 화면 로직을 직접 구현하여 사용할 수 있습니다.

할인 정보에 포함된 startedAtendedAt 값은 프로모션의 유효 기간을 나타냅니다. 이 타임스탬프를 사용하여 아래와 같이 처리해야 합니다.

  • 유효 기간 동안에만 프로모션 화면 노출하기
  • 기간이 만료되면 프로모션 화면 숨기기
콜백 등록 시점 주의사항

중요: onDiscountInfoChange 콜백은 initialize() 호출 전에 등록해야 합니다.

콜백을 나중에 등록하면 기존 진행 중인 프로모션 정보를 놓치면 이슈가 발생할 수 있습니다. 이는 앱이 다시 시작되었을 때 이전에 활성화된 프로모션을 즉시 표시할 수 없게 되는 문제를 야기할 수 있습니다.

실시간 UI 업데이트

onDiscountInfoChange 콜백은 앱 시작 시 유효한 할인 정보가 있거나, predict() 함수 호출 후 새로운 할인 정보가 생성될 때 모두 호출됩니다. 이 콜백을 활용하여 배너, 가격 정보 등 UI를 실시간으로 업데이트할 수 있습니다.

import MonetaiSDK

class ViewController: UIViewController {

override func viewDidLoad() {
super.viewDidLoad()

// 할인 정보 변경 콜백 설정
MonetaiSDK.shared.onDiscountInfoChange = { [weak self] discountInfo in
DispatchQueue.main.async {
self?.handleDiscountInfoChange(discountInfo)
}
}
}

private func handleDiscountInfoChange(_ discountInfo: AppUserDiscount?) {
if let discount = discountInfo {
// 할인 정보가 사용 가능할 때 UI 업데이트
let now = Date()
let endTime = discount.endedAt

if now < endTime {
// 할인이 유효할 때
showDiscountBanner(discount)
}
} else {
// 할인 정보가 없을 때
hideDiscountBanner()
}
}

private func showDiscountBanner(_ discount: AppUserDiscount) {
// 할인 배너 표시 로직
print("할인 배너 표시:", discount)
}

private func hideDiscountBanner() {
// 할인 배너 숨기기 로직
print("할인 배너 숨기기")
}
}

API 참조

콜백 타입

public var onDiscountInfoChange: ((AppUserDiscount?) -> Void)?

AppUserDiscount 타입

속성타입설명
startedAtDate할인 시작 시간
endedAtDate할인 종료 시간
appUserIdstring사용자 ID
sdkKeystringSDK 키

B-2. currentDiscount 속성을 활용한 반응형 구현

currentDiscount 속성을 사용하여 현재 활성화된 할인 정보에 즉시 접근할 수 있습니다. onDiscountInfoChange 콜백 없이도 현재 할인 상태를 확인할 수 있습니다.

onDiscountInfoChange 콜백은 이벤트를 놓치면 이슈가 발생할 수 있기 때문에 initialize() 호출 전에 등록해야 한다는 제약이 있습니다. 하지만 이 제약을 우회하고 더 유연한 방식으로 구현하고 싶다면, @Published 객체와 Combine을 활용한 반응형 처리 방식을 고려해볼 수 있습니다.

API 참조

현재 할인 정보 속성

@Published public private(set) var currentDiscount: AppUserDiscount?

사용자 상태 관리

SDK 재설정

사용자가 로그아웃할 때 SDK를 초기화합니다.

import MonetaiSDK

// 사용자가 로그아웃할 때
func logoutUser() {
MonetaiSDK.shared.reset()
print("사용자 로그아웃 완료")
}

지원
SDK 연동 중 문제가 발생하면 support@monetai.io로 편하게 문의해 주세요.


다음 단계

SDK 설정이 완료되면 다음 단계를 진행하세요: