SKAdNetwork 지원
SKAdNetwork는 iOS 앱 인스톨 캠페인을 위한 Apple의 개인정보 보호 중심의 어트리뷰션 프레임워크입니다. Singular 플러터 SDK는 대시보드에서 설정한 전환 모델에 따라 자동으로 전환 값을 업데이트하는 관리 모드에서 기본적으로 SKAdNetwork를 활성화합니다.
추가 구성이 필요하지 않습니다: 최신 Flutter SDK를 사용하는 경우, SKAdNetwork는 즉시 작동합니다. 기본 기능을 위해 코드를 변경하거나 추가 설정이 필요하지 않습니다.
SKAN 모드 이해
관리 모드(기본값)
관리 모드에서는 대시보드에서 구성한 전환 모델에 따라 Singular가 자동으로 전환 값 업데이트를 처리합니다. 최소한의 코드가 필요하고 최적의 전환 추적을 제공하므로 대부분의 앱에 권장되는 방식입니다.
- 자동 업데이트: Singular는 사용자 이벤트 및 구성된 모델을 기반으로 모든 전환 값 업데이트를 관리합니다.
- 대시보드 구성: 코드 변경 없이 Singular 대시보드에서 전환 모델을 디자인할 수 있습니다.
- 최적화: Apple의 제약 조건 내에서 전환 가치 업데이트를 극대화하는 Singular의 전문성을 활용하세요.
- 24시간 창 관리: Singular는 데이터 수집을 극대화하기 위해 SKAdNetwork의 24시간 업데이트 윈도우를 지능적으로 처리합니다.
수동 모드(고급)
수동 모드에서는 전환 값 업데이트를 완벽하게 제어할 수 있으며, SKAN 전환 값 업데이트 시기와 방법을 결정하기 위한 사용자 지정 로직을 구현할 수 있습니다. 관리 모드로는 충족할 수 없는 특정 요구 사항이 있는 경우에만 이 모드를 사용하세요.
고급 기능: 수동 모드를 사용하려면 전환 값 업데이트 기간 및 제한 사항 등 Apple의 SKAdNetwork 제약 조건을 신중하게 구현하고 이해해야 합니다. 대부분의 앱은 관리 모드를 사용해야 합니다.
SKAdNetwork 지원 비활성화하기
SKAdNetwork 추적은 기본적으로 활성화되어 있습니다. 비활성화하려면 SingularConfig 객체를 빌드할 때 skAdNetworkEnabled 구성 속성을 false로 설정하세요.
import 'package:singular_flutter_sdk/singular_config.dart';
SingularConfig config = SingularConfig('API_KEY', 'SECRET');
config.skAdNetworkEnabled = false; // Disable SKAdNetwork
수동 모드 구성
사용자 지정 전환 값 로직을 구현하려면 수동 모드를 활성화하고 제공된 SDK 메서드를 사용하여 앱의 수명 주기 동안 전환 값을 업데이트하고 모니터링하세요.
수동 모드 활성화
전환 값 업데이트를 제어하려면 SingularConfig 객체를 빌드할 때 manualSkanConversionManagement 구성 속성을 true로 설정합니다.
import 'package:singular_flutter_sdk/singular_config.dart';
SingularConfig config = SingularConfig('API_KEY', 'SECRET');
config.manualSkanConversionManagement = true; // Enable manual mode
중요: 수동 업데이트 방법은 manualSkanConversionManagement 이 활성화된 경우에만 작동합니다. 관리 모드가 활성화되어 있으면 수동 업데이트는 무시됩니다.
전환 값 업데이트(SKAN 2.0-3.0)
skanUpdateConversionValue 방법을 사용하여 사용자 지정 로직에 따라 SKAdNetwork 전환 값을 수동으로 업데이트할 수 있습니다. 전환 값은 0에서 63 사이의 정수여야 합니다.
메서드 서명
static void skanUpdateConversionValue(int conversionValue)
사용 예시
import 'package:singular_flutter_sdk/singular.dart';
import 'dart:io';
// User completed signup - update conversion value to 7
void onUserSignUp() {
if (Platform.isIOS) {
// Track the sign-up event
Singular.event('SignUp');
// Update SKAN conversion value
Singular.skanUpdateConversionValue(7);
print('Conversion value updated to 7');
}
}
// User completed purchase - update based on purchase amount
void onPurchaseComplete(double purchaseAmount) {
if (Platform.isIOS) {
// Track revenue event
Singular.customRevenue('Purchase', 'USD', purchaseAmount);
// Calculate conversion value based on purchase tier
int conversionValue = calculateConversionValue(purchaseAmount);
Singular.skanUpdateConversionValue(conversionValue);
print('Conversion value updated to $conversionValue');
}
}
int calculateConversionValue(double amount) {
// Your custom logic to determine conversion value
if (amount >= 100) return 63; // High value
if (amount >= 50) return 40; // Medium value
if (amount >= 10) return 20; // Low value
return 10; // Minimal value
}
전환 값 업데이트 (SKAN 4.0)
iOS 16.1+의 경우, skanUpdateConversionValues 메서드를 사용하여 미세값, 거친값, 잠금 파라미터로 SKAdNetwork 4.0 전환 값을 업데이트할 수 있습니다. 이를 통해 전환 값 업데이트를 보다 세밀하게 제어할 수 있습니다.
메서드 서명
static void skanUpdateConversionValues(
int conversionValue, // Fine value (0-63)
int coarse, // Coarse value (0=low, 1=medium, 2=high)
bool lock // Lock status
)
사용 예시
import 'package:singular_flutter_sdk/singular.dart';
import 'dart:io';
void updateSKAN4ConversionValue(
int fineValue,
String coarseValue,
bool shouldLock
) {
if (Platform.isIOS) {
// Map coarse value string to number
Map<String, int> coarseMap = {
'low': 0,
'medium': 1,
'high': 2
};
// Update SKAdNetwork 4.0 conversion values
Singular.skanUpdateConversionValues(
fineValue,
coarseMap[coarseValue] ?? 0,
shouldLock
);
print('SKAN 4.0 updated: fine=$fineValue, coarse=$coarseValue, lock=$shouldLock');
}
}
// Example: High-value user completes tutorial
void onTutorialComplete() {
updateSKAN4ConversionValue(15, 'medium', false);
}
// Example: Premium purchase - lock the value
void onPremiumPurchase() {
updateSKAN4ConversionValue(63, 'high', true);
}
현재 전환 값 가져오기
Singular SDK에서 추적한 현재 변환 값을 가져옵니다. 현재 상태를 기반으로 조건부 로직을 구현하는 데 유용하며 관리 모드와 수동 모드 모두에서 작동합니다.
메서드 서명
static Future<int> skanGetConversionValue()
사용 예시
import 'package:singular_flutter_sdk/singular.dart';
import 'dart:io';
Future<void> checkAndUpdateConversionValue() async {
if (Platform.isIOS) {
int currentValue = await Singular.skanGetConversionValue();
print('Current conversion value: $currentValue');
// Only update if current value is below threshold
if (currentValue < 30) {
Singular.skanUpdateConversionValue(30);
print('Updated conversion value to 30');
}
}
}
전환 값 업데이트 모니터링
전환 값이 변경될 때마다 실시간 알림을 받도록 핸들러를 설정하세요. 이를 통해 전환 값 업데이트 및 로그 분석에 대응하거나 다른 앱 동작을 트리거할 수 있습니다.
구성
SDK를 초기화할 때 conversionValueUpdatedCallback 속성을 사용하여 전환 값 업데이트 핸들러를 구성합니다.
import 'package:singular_flutter_sdk/singular.dart';
import 'package:singular_flutter_sdk/singular_config.dart';
void initializeSingularSDK() {
SingularConfig config = SingularConfig('API_KEY', 'SECRET');
// Set up conversion value update handler
config.conversionValueUpdatedCallback = (int conversionValue) {
print('Conversion value updated to: $conversionValue');
// Log the update to your analytics
logConversionValueUpdate(conversionValue);
// Trigger app-specific behavior
if (conversionValue >= 50) {
unlockPremiumFeature();
}
};
Singular.start(config);
}
void logConversionValueUpdate(int value) {
// Your analytics logging logic
print('Analytics: SKAN CV = $value');
}
void unlockPremiumFeature() {
// Your custom logic
print('Premium feature unlocked based on high conversion value');
}
모범 사례: 전환 값 핸들러를 사용하여 앱 전체에서 현재 전환 상태의 동기화된 보기를 유지하세요. 이는 사용자 지정 로직이 올바르게 작동하는지 디버깅하고 확인하는 데 특히 유용합니다.
앱 추적 투명성(ATT) 지원
ATT(앱 추적 투명성)는 디바이스의 IDFA(광고주 식별자)에 액세스하고 사용자 데이터를 공유하기 전에 사용자 동의를 요구하는 Apple의 개인정보 보호 프레임워크입니다. iOS 어트리뷰션과 사용자 획득 캠페인의 정확도를 극대화하기 위해서는 ATT를 올바르게 구현하는 것이 중요합니다.
어트리뷰션에 ATT가 중요한 이유
iOS 14.5부터 앱은 IDFA에 액세스하기 전에 ATT 프레임워크를 통해 사용자 권한을 요청해야 합니다. IDFA 없이도 핑거프린팅과 확률적 방법을 사용하여 어트리뷰션이 가능하지만, IDFA를 사용하면 어트리뷰션 정확도가 크게 향상되고 결정론적 매칭을 제공할 수 있습니다.
- 결정론적 어트리뷰션: IDFA는 광고 노출을 인스톨로 직접 연결하는 정밀한 디바이스 수준의 어트리뷰션을 가능하게 합니다.
- 애드 네트워크 최적화: 애드 네트워크는 IDFA 액세스를 통해 캠페인을 더 잘 최적화하고 더 정확한 리포팅을 제공할 수 있습니다.
- 사용자 수준 인사이트: IDFA에 액세스하면 보다 세분화된 사용자 행동 분석 및 코호트 추적이 가능합니다.
권장 사항: Singular는 ATT 프롬프트를 구현하고 사용자 동의를 요청할 것을 강력히 권장합니다. 사용자에게 혜택(맞춤화된 광고, 더 나은 앱 경험)을 설명하여 옵트인 비율을 극대화하세요.
구현 요구 사항
iOS 14.5 이상(iOS 18 포함)의 경우, 추적을 위해 IDFA에 액세스하기 전에 사용자 동의를 요청하기 위해 ATTrackingManager 프레임워크를 사용합니다. Singular SDK는 ATT를 지원하므로 동의 전에 초기화할 수 있고 동의가 승인되거나 시간 초과가 발생할 때까지 이벤트를 지연시킬 수 있습니다.
1단계: ATT 프레임워크 구성 추가하기
사용자 대상 사용 설명으로 Info.plist 파일을 업데이트하여 iOS 앱이 ATT 프레임워크를 지원하도록 구성합니다.
-
Info.plist를 엽니다: Flutter 프로젝트의 iOS Info.plist 파일(
ios/Runner/Info.plist)로 이동합니다. -
사용 설명을 추가합니다: 앱에 추적 권한이 필요한 이유에 대한 명확한 설명과 함께
NSUserTrackingUsageDescription키를 추가합니다.
<key>NSUserTrackingUsageDescription</key>
<string>This app uses tracking to provide personalized ads and improve your experience.</string>
중요: 사용 설명은 ATT 프롬프트에서 사용자에게 표시됩니다. 추적을 통해 사용자에게 어떤 이점이 있는지 명확하고 간결하며 솔직하게 설명하세요.
2단계: ATT 지원 패키지 설치
앱에서 ATT 기능을 활성화하려면 Flutter ATT 지원 패키지를 설치합니다. app_tracking_transparency 플러그인을 권장합니다.
종속성 추가
dependencies:
flutter:
sdk: flutter
singular_flutter_sdk: ^1.8.0
app_tracking_transparency: ^2.0.4
종속성을 추가한 후 flutter pub get 을 실행하여 패키지를 설치합니다.
flutter pub get
대체 패키지: 앱_추적_투명성을 권장하지만, 유사한 기능을 제공하는 Flutter ATT 플러그인을 사용할 수 있습니다. 플러그인이 iOS 14.5 이상을 지원하는지 확인합니다.
3단계: SDK 대기 시간 구성하기
waitForTrackingAuthorizationWithTimeoutInterval 속성을 설정하여 초기화하기 전에 사용자의 ATT 응답을 기다리도록 Singular SDK를 구성합니다. 이 지연 시간은 사용자가 권한을 부여하는 경우 IDFA가 캡처되도록 보장합니다.
중요: Singular SDK가 첫 세션을 보내기 전에 항상 ATT 동의를 요청하고 IDFA를 검색하세요. 그렇게 하지 않으면 해당 디바이스의 어트리뷰션 데이터에 대한 IDFA가 영구적으로 손실됩니다.
import 'package:singular_flutter_sdk/singular_config.dart';
SingularConfig config = SingularConfig('API_KEY', 'SECRET');
config.waitForTrackingAuthorizationWithTimeoutInterval = 300; // Wait up to 5 minutes
권장 값: 앱에 ATT 프롬프트가 표시되는 경우 시간 제한을 300초(5분)로 설정하세요. 이렇게 하면 프롬프트가 지연되거나 표시되지 않을 경우 사용자 경험이 저하되지 않고 사용자가 프롬프트를 보고 응답할 수 있는 충분한 시간을 확보할 수 있습니다.
4단계: ATT 동의 요청
앱에서 ATT 요청 플로우를 구현하여 사용자 경험의 적절한 시점에 사용자에게 추적 권한을 요청하는 메시지를 표시합니다.
import 'package:flutter/material.dart';
import 'dart:io';
import 'package:singular_flutter_sdk/singular.dart';
import 'package:singular_flutter_sdk/singular_config.dart';
import 'package:app_tracking_transparency/app_tracking_transparency.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
void initState() {
super.initState();
initializeApp();
}
Future<void> initializeApp() async {
if (Platform.isIOS) {
// Request ATT authorization
final trackingStatus = await AppTrackingTransparency.requestTrackingAuthorization();
// Log the user's response
print('ATT Status: $trackingStatus');
// Possible values: TrackingStatus.authorized, .denied, .restricted, .notDetermined
}
// Initialize Singular SDK (configured with wait timeout)
SingularConfig config = SingularConfig('API_KEY', 'SECRET');
config.waitForTrackingAuthorizationWithTimeoutInterval = 300;
config.enableLogging = true;
Singular.start(config);
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: MyHomePage(),
);
}
}
ATT 흐름 이해
waitForTrackingAuthorizationWithTimeoutInterval 을 사용하여 초기화 지연을 설정하면 앱 흐름은 다음과 같이 작동합니다:
- 앱이 열리면 Singular SDK가 세션과 사용자 이벤트를 기록하기 시작하지만 아직 Singular 서버로 전송하지는 않습니다.
- 앱 추적 투명성 동의가 승인/거부되거나 설정된 시간이 경과하면, SDK는 세션과 대기열에 있는 모든 이벤트를 (IDFA를 사용하거나 사용하지 않고) Singular 서버로 보냅니다.
- 그러면 Singular는 사용 가능한 경우 IDFA를 활용하여 어트리뷰션 프로세스를 시작합니다.
ATT 시나리오
다음 표에는 이 연동을 사용하여 가능한 시나리오가 요약되어 있습니다:
| 시나리오 | IDFA 사용 가능 여부 |
| 사용자가 동의 대화 상자를 보고 설정된 시간이 경과하기 전에 동의를 부여합니다. | IDFA를 사용할 수 있음 |
| 사용자가 동의 대화 상자를 보고 설정된 시간이 경과하기 전에 동의를 거부합니다. | IDFA를 사용할 수 없음 |
| 설정된 시간이 만료된 후 사용자에게 동의 대화 상자가 표시되고 동의를 허용합니다. | 동의를 받은 후에 보고된 사용자 이벤트에 대해서만 IDFA를 사용할 수 있습니다. |
| 설정된 시간이 만료되면 사용자에게 동의 대화 상자가 표시되고 동의를 거부합니다. | IDFA를 사용할 수 없는 경우 |
| 사용자에게 동의 대화 상자가 표시되고 아무런 조치 없이 앱을 종료한 다음 설정된 시간이 만료된 후 앱을 열고 동의를 부여합니다. | 대기 중인 모든 이벤트는 앱이 다시 열릴 때 Singular 서버로 전송됩니다. 이러한 이벤트에는 IDFA를 사용할 수 없습니다. 동의가 부여된 후 추적된 모든 이벤트에는 IDFA가 연결됩니다. |
| 사용자에게 동의 대화 상자가 표시되고 아무 조치 없이 앱을 종료한 후 나중에 앱을 열고 동의를 거부합니다. | 대기 중인 모든 이벤트는 앱이 다시 열리면 Singular 서버로 전송됩니다. 이러한 이벤트 또는 이후 추적된 이벤트에 대해서는 IDFA를 사용할 수 없습니다. |
ATT 모범 사례
- 사전 프롬프트 메시지: 사용자에게 추적 권한이 필요한 이유와 이를 통해 얻을 수 있는 혜택(더 나은 광고, 향상된 경험)을 설명하는 사전 ATT 화면을 표시하세요. 이를 통해 옵트인 비율을 크게 높일 수 있습니다.
- 타이밍이 중요합니다: 앱을 처음 실행할 때 바로 표시하지 말고 앱 흐름의 자연스러운 순간에 ATT 프롬프트를 표시하세요. 사용자가 먼저 앱을 경험하게 하여 신뢰를 쌓을 수 있도록 하세요.
-
시간 제한 구성:
waitForTrackingAuthorizationWithTimeoutInterval을 30-300초로 설정합니다. 시간 초과 후, Singular는 SKAN 4.0 어트리뷰션을 진행합니다(IDFA 없음). - 철저하게 테스트하세요: 승인 및 거부 시나리오를 모두 테스트하여 사용자의 선택에 관계없이 앱이 올바르게 작동하는지 확인하세요.
- 사용자의 선택권을 존중하세요: 추적을 거부한 사용자에게 반복적으로 메시지를 표시하거나 옵트인하도록 압력을 가하는 공격적인 메시지를 표시하지 마세요.
-
오류 처리:
restricted(예: 자녀 보호 기능) 또는notDetermined상태의 추적 상태를 확인하고 분석을 위해 로그를 기록합니다. - SKAN 4.0 연동: 전환 값 업데이트가 ATT 동의와 일치하는지 확인하여 SKAN 포스트백을 최적화합니다(예: 이벤트를 0-63 값에 매핑하기 위해 Singular의 대시보드 사용).
앱 스토어 검토: ATT를 제대로 구현하지 않거나 프레임워크를 우회하려는 앱은 앱 스토어 검토 과정에서 거부될 수 있습니다. 구현이 Apple의 가이드라인을 따르고 사용자의 개인정보 보호 선택권을 존중하는지 확인하세요.