SDK ์ฝ์
1. ํ์ ์ค์
SDK ์ค์น
Cocoapod ํ๊ฒฝ์์ SDK ๋ค์ด๋ก๋ ๋ฐฉ๋ฒ
XCode ํ๋ก์ ํธ ํ์ผ์ค Podfile ํ์ผ์ ๋ค์๊ณผ ๊ฐ์ด SDK๋ฅผ ์ถ๊ฐํฉ๋๋ค
pod 'RW'๊ธฐ์กด์ SDK๋ฅผ ํ๋ฒ ์ค์นํ ๊ฒฝ์ฐ์๋ ์ค์นํ SDK ๋ฒ์ ์ ํ์ํด์ผ ํ๋ ๊ฒฝ์ฐ๋ ์์ต๋๋ค. ์๋์ ๊ฐ์ด ์ค์นํ SDK๋ฒ์ ์ ๋ช ์์ ์ผ๋ก ํ์ํ๋ฉด ๋ฉ๋๋ค.
pod 'RW', '~> 1.1.62'Podfile ์ ํด๋น๋ผ์ธ์ ์ถ๊ฐํ ํ Terminal ํ๋ก๊ทธ๋จ์ ์คํํ์ฌ ๋ค์์ ๋ช ๋ น์ ์ํํฉ๋๋ค
pod installSDK ๋ฒ์ ์ ๋ฐ์ดํธ์ ๊ฒฝ์ฐ ๋ค์์ ๋ช ๋ น์ ์ํํฉ๋๋ค.
pod update์ ์์ ์ผ๋ก ์ค์น๊ฐ ๋๋ฉด ์๋์ ๊ฐ์ ํด๋ ๊ตฌ์กฐ๋ฅผ ํ์ธํ ์ ์์ต๋๋ค.
Swift Package Manager๋ฅผ ํตํ SDK ๋ค์ด๋ก๋ ๋ฐฉ๋ฒ
Xcode File ๋ฉ๋ด์์ Add Packages... ๋ฅผ ํด๋ฆญํฉ๋๋ค.
RW-iOS-SPM ๋๋ https://github.com/WisetrackerTechteam/RW-iOS-SPM ์ฃผ์๋ก ๊ฒ์ํฉ๋๋ค.
์ต์ ๋ฒ์ ์ ํจํค์ง๋ก ์ ํ ํ, Add Package ๋ฒํผ์ ํด๋ฆญํฉ๋๋ค.
์๋ฃ๋๋ฉด ์ค์น๋ ํจํค์ง๋ฅผ ํ์ธํ ์ ์์ต๋๋ค.
TARGETS โ Build Phases โ Copy Bundle Resources ์ dop-native-sdk-inf.js ํ์ผ์ ๋๋๊ทธ ์ค ๋๋ํ์ฌ ๋ณต์ฌํฉ๋๋ค.
SDK ์ค์น - Cocoapod, Swift Package Manger๋ฅผ ์ฌ์ฉํ์ง ์์ ๊ฒฝ์ฐ
SDK ํ์ผ์ https://github.com/WisetrackerTechteam/RW-iOS-SDK ์์ ๋ค์ด๋ก๋ ํฉ๋๋ค.
๋ค์ด๋ ํ์ผ์ ์์ถ ํด์ ํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ํ์ผ์ด ํ์ธ ๊ฐ๋ฅํ๊ณ ์ด์ค ์๋์ ์ ํ๋ 3๊ฐ์ ํ์ผ์ ๋ถ์ ๋์ ์ฑ ํ๋ก์ ํธ์ ์ถ๊ฐํฉ๋๋ค.
ํ๋ก์ ํธ ์ ํํ ๋ง์ฐ์ค ์ฐํด๋ฆญ, Add Files to ๋ฉ๋ด๋ฅผ ์ ํํฉ๋๋ค.
![]()
์์์ ๋ค์ด๋ก๋ ๋ฐ๊ณ , ์์ถ ํด์ ํ ํด๋์ ๋ค์ด๊ฐ์ ์๋์ ๊ฐ์ด ์ถ๊ฐ ๋์ ํ์ผ์ ์ ํํ๊ณ , ํ๋ฉด ์๋์ชฝ ์ค์ ์ ์กด์ฌํ๋ ๋ชจ๋ target์ ํฌํจ๋์๋์ง ํ์ธํ ์ถ๊ฐ ํ๋ฉด ๋ฉ๋๋ค.
BuildSetting ์ ์๋์ ๊ฐ์ด ์ค์ ์ ์ถ๊ฐํฉ๋๋ค.
xcode ๊ฐ 12.3 ์ดํ ๋ฒ์ ์ด๊ณ ๋น๋ ๊ณผ์ ์์ ์๋์ ์ ์ฌํ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ ๊ฒฝ์ฐ๊ฐ ์์ผ๋ฉฐ,
์์ ๊ฒฝ์ฐ์๋ ์๋์ ๊ฐ์ด ์ค์ ์ ํ๊ณ , ๋น๋๋ฅผ ํ๋ฉด๋ฉ๋๋ค.
๋ง์ง๋ง์ผ๋ก, SDK ๊ฐ Dependencies ๋ก ์ฌ์ฉํ๋ Couchbase-Lite framework ๋ฅผ ์๋์ ์ฃผ์์์ ๋ค์ด๋ก๋ ํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ์์ ๋์ผํ ๋ฐฉ๋ฒ์ผ๋ก ๋์ ํ๋ก์ ํธ์ ์ถ๊ฐํ์ฌ ์ค๋๋ค. ์๋์ ํ์ผ์ ๋ค์ด๋ก๋ ํธ์๋ฅผ ์ํด์ zip ํ์ผ๋ก ์์ถํ์์ต๋๋ค. ๋ค์ด๋ก๋ ๋ฐ์ ํ์ผ์ ์์ถ ํด์ ํ์๊ณ , CouchbaseLite.xcframework ํด๋๋ฅผ ํ๋ก์ ํธ์ framework ๋ก ์ถ๊ฐํฉ๋๋ค. https://wisetracker-public.s3.ap-northeast-2.amazonaws.com/CouchbaseLite.xcframework.zip
dotAuthorizationKey ๋ฑ๋ก
info.plist ํ์ผ์ Open As Source Code ๋ฐฉ์์ผ๋ก ์คํํ ํ, ์๋ ์ฝ๋๋ฅผ ์ถ๊ฐํฉ๋๋ค.
<key>dotAuthorizationKey</key>
<dict>
<key>serviceNumber</key>
<string>xxxxx</string>
<key>expireDate</key>
<string>14</string>
<key>isDebug</key>
<string>true</string>
<key>isInstallRetention</key>
<string>true</string>
<key>isFingerPrint</key>
<string>true</string>
<key>accessToken</key>
<string></string>
<key>useMode</key>
<string>2</string>
</dict>์ถ๊ฐํ ์ฝ๋ ์ค serviceNumber ์ value๋ฅผ ์ฌ๋ฐ๋ฅธ ๊ฐ์ผ๋ก ๋ณ๊ฒฝํด์ผ ํฉ๋๋ค.
์์ด์ฆํธ๋์ปค ๋์๋ณด๋์ ๋ก๊ทธ์ธํ์ฌ ์ค์ > ์๋น์ค์ค์ ๋ฉ๋ด์์ '์๋น์ค๋ฒํธ' ํญ๋ชฉ์ ๊ธฐ์ฌ๋ ์ซ์๋ฅผ ํ์ธ ํ ๋ณต์ฌํ์ฌ serviceNumber ๊ฐ์ ๋ณ๊ฒฝ ํด ์ฃผ์ธ์.

HTTP ํต์ ํ์ฉ
httpํต์ ์ ํ์ฉํ๊ธฐ ์ํด NSAppTransportSecurity ๋ฅผ ์๋์ ๊ฐ์ด ์ถ๊ฐํฉ๋๋ค.
์ด์ ๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก info.plist ํ์ผ์ Open As Source Code ๋ฐฉ์์ผ๋ก ์คํํ ํ, ์๋ ์ฝ๋๋ฅผ ์ถ๊ฐํฉ๋๋ค.
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>์ด๊ธฐํ
์ด๊ธฐํ ๋ฐฉ๋ฒ์ SceneDelegate ๊ฐ ์ค์ ๋ ๊ฒฝ์ฐ์ ์ค์ ๋์ง ์์ ๊ฒฝ์ฐ์ ๋ฐ๋ผ ๋ฌ๋ผ์ง๋๋ค.
SceneDelegate๋ฅผ ์ฌ์ฉํ์ง ์์ผ๋ฉด AppDelegate์์ ์ด๊ธฐํ์์ ์ ํ๊ณ , ๊ทธ๋ ์ง ์๊ณ SceneDelegate๋ฅผ ์ฌ์ฉํ๋ฉด SceneDelegate์์ ์ด ์์ ์ ํด์ผ ํฉ๋๋ค.
1. iOS13 ๋ฏธ๋ง (SceneDelegate ์์)
SceneDelegate ์์)AppDelegate์ didFinishLaunchingWithOptions ํจ์์ SDK๋ฅผ Initializationํ๊ธฐ ์ํ ์ฝ๋๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ์ ์ฉํฉ๋๋ค. SDK๊ฐ ์ ์์ ์ผ๋ก ์ด๊ธฐํ ๋์์ ๋ ์๋์ ๊ฐ์ ๊ธฐ๋ณธ ๋ถ์์ด ๊ฐ๋ฅํฉ๋๋ค.
์ฑ ์คํ ๋ฐ ๋ฐฉ๋ฌธ์, ์ผ/์ฃผ/์์์๋ฐฉ๋ฌธ์ ๋ฑ ๋ฐฉ๋ฌธ๊ณผ ๊ด๋ จ๋ ์งํ
ํต์ ์ฌ, ๋จ๋ง๊ธฐ, ๊ตญ๊ฐ ๋ฑ ๋ฐฉ๋ฌธ์์ ๋จ๋ง๊ธฐ ํ๊ฒฝ์ผ๋ก ๋ถํฐ ์ถ์ถ๋ ์ ์๋ ์งํ
import DOT
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// S: Wisetracker SDK init
DOT.initialization(launchOptions, application: application)
#if DEBUG
DOT.checkDebugMode(true)
#else
DOT.checkDebugMode(false)
#endif
// E: Wisetracker SDK init
}#import <DOT/DOT.h>
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// S: Wisetracker SDK init
[DOT initialization:launchOptions application:application];
#ifdef DEBUG
[DOT checkDebugMode:true]
#else
[DOT checkDebugMode:false]
#endif
// E: Wisetracker SDK init
}DOT๊ฐ ์ฌ์ฉ๋๋ ๊ณณ์์๋ import DOT์ ํตํด import๊ฐ ํ์ํฉ๋๋ค. ์ดํ ์ ์ฉ ์์์์๋ importํ๋ ๋ถ๋ถ์ด ์๋ต๋์ด ์์ต๋๋ค.
2. iOS13 ์ด์ (SceneDelegate ์ฌ์ฉ)
SceneDelegate ์ฌ์ฉ)๐ iOS13 ์ด์์ด์ด๋ SceneDelegate๋ฅผ ์ฌ์ฉํ์ง ์์ ์๋ ์์ด์, ์ด ๋์๋ ์์ SceneDelegate๋ฅผ ์ฌ์ฉํ์ง ์๋ ๊ฒฝ์ฐ๋ฅผ ์ฐธ์กฐํ์ธ์.
SceneDelegate์ sceneDidBecomeActiveํจ์์ SDK๋ฅผ Initializationํ๊ธฐ ์ํ ์ฝ๋๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ์ ์ฉํฉ๋๋ค. SDK๊ฐ ์ ์์ ์ผ๋ก ์ด๊ธฐํ ๋์์ ๋ ์๋์ ๊ฐ์ ๊ธฐ๋ณธ ๋ถ์์ด ๊ฐ๋ฅํฉ๋๋ค.
์ฑ ์คํ ๋ฐ ๋ฐฉ๋ฌธ์, ์ผ/์ฃผ/์์์๋ฐฉ๋ฌธ์ ๋ฑ ๋ฐฉ๋ฌธ๊ณผ ๊ด๋ จ๋ ์งํ
ํต์ ์ฌ, ๋จ๋ง๊ธฐ, ๊ตญ๊ฐ ๋ฑ ๋ฐฉ๋ฌธ์์ ๋จ๋ง๊ธฐ ํ๊ฒฝ์ผ๋ก ๋ถํฐ ์ถ์ถ๋ ์ ์๋ ์งํ
import DOT
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
...
func sceneDidBecomeActive(_ scene: UIScene) {
// S: Wisetracker SDK init
DOT.initialization(nil, application: UIApplication.shared)
#if DEBUG
DOT.checkDebugMode(true)
#else
DOT.checkDebugMode(false)
#endif
// E: Wisetracker SDK init
}
...
}#import <DOT/DOT.h>
@implementation SceneDelegate
...
- (void)sceneDidBecomeActive:(UIScene *)scene {
// S: Wisetracker SDK init
[DOT initialization:nil application:[UIApplication sharedApplication]];
#ifdef DEBUG
[DOT checkDebugMode:true]
#else
[DOT checkDebugMode:false]
#endif
// E: Wisetracker SDK init
}
...
@end์ดํธ๋ฆฌ๋ทฐ์
๋ฐ์ดํฐ ์ ๊ทผ
[DOT getAttributedInfo] ํธ์ถ์ ํตํด ์์ด์ฆํธ๋์ปค ๋์๋ณด๋์์ ์์ฑํ ์ดํธ๋ฆฌ๋ทฐ์
๋งํฌ๋ฅผ ํตํด ์ฑ์ ์ค์นํ ์ ์ (non-organic)์ attribute ์ ๋ณด๋ฅผ ํ์ธํ ์ ์์ต๋๋ค.
โ ํ์ ์ฒดํฌ ์ฌํญ
iOS SDK ์ต์ ๋ฒ์ ์ด ์ ์ฉ๋์ด์ผ ํฉ๋๋ค
SDK ์ด๊ธฐํ ํจ์ DOT.initializationํธ์ถํ ์ดํ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
#import <DOT/DOT.h>
@implementation SceneDelegate
...
- (void)sceneDidBecomeActive:(UIScene *)scene {
// S: Wisetracker SDK init
[DOT initialization:nil application:[UIApplication sharedApplication]];
#ifdef DEBUG
[DOT checkDebugMode:true]
#else
[DOT checkDebugMode:false]
#endif
// E: Wisetracker SDK init
[DOT getAttributedInfo:^(NSDictionary *result) {
// info๋ฅผ ์ฌ์ฉํ์ฌ ์์
์ํ
NSLog(@"current attribution data on AppDelegate : %@ ", result);
}];
}
...
@endresult ํ๋ผ๋ฏธํฐ์ ํํ๋ ์๋์ ์์๋ฅผ ์ฐธ๊ณ ํด์ฃผ์ธ์.
(result ํ๋ผ๋ฏธํฐ ๋ฐ์ดํฐ๊ฐ ๋น์ด์๋ค๋ฉด Organic ์ผ๋ก ์๋ณ๋ ๊ฒฐ๊ณผ์ ๋๋ค.)
โ ์ฑ์ค์น(์์)
{
install_media="P1540365166967", >> ๊ด๊ณ ์ฑ๋
install_mediaNm="WISE_TEST1", >> ๊ด๊ณ ์ฑ๋๋ช
install_campaign="C1710215861051", >> ๊ด๊ณ ์บ ํ์ธ
install_campaignNm="WISETRACKER", >> ๊ด๊ณ ์บ ํ์ธ๋ช
install_medium="", >> ๊ด๊ณ ํ์
install_keyword="" >> ๊ด๊ณ ํค์๋
}โก ์ฑ์คํ(์์)
{
open_media="P1540365166967",
open_mediaNm="WISE_TEST1",
open_campaign="C1710215861051",
open_campaignNm="WISETRACKER",
open_medium="",
open_keyword=""
}Hybrid App์ ์ํ ์ค์
Hybrid ์ฑ์ ๊ฒฝ์ฐ ์ฑ ๋ด์์ WebView ๋ฅผ ์ฌ์ฉํ์ฌ ์น ์ปจํ ์ธ ๋ฅผ ์๋น์ค ํ๊ธฐ๋ ํฉ๋๋ค. ์ด์ ๊ฐ์ด Webview ์ ์ํด์ ๋ณด์ฌ์ง๋ ์น ์ปจํ ์ธ ์ ๊ฒฝ์ฐ์๋ ์์์ ์ค๋ช ๋ Native ํ๋ฉด๊ณผ๋ ๋ค๋ฅธ ๋ฐฉ์์ผ๋ก ๋์ํ๊ธฐ ๋๋ฌธ์, ๋ณ๋์ ๋ถ์ ์ฝ๋ ์ ์ฉ์ด ํ์ํฉ๋๋ค. ๋ถ์ ๋์ ์ฑ์ด ๋ง์ฝ Hybrid ์ฑ์ธ ๊ฒฝ์ฐ์๋ ์๋์ ์ฝ๋๋ฅผ ์ฐธ๊ณ ํ์ฌ ์น ์ปจํ ์ธ ๋ ๋ถ์ํ ์ ์๋๋ก ์ ์ฉ์ ํด์ผํฉ๋๋ค.
์ฑ๋ด์์ ์ฌ์ฉํ WKWebView์ Delegate ํจ์์ ์๋์ ๊ฐ์ด ๋ถ์์ฝ๋๋ฅผ ์ ์ฉํฉ๋๋ค.
extension WebViewController: WKUIDelegate, WKNavigationDelegate {
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
DOT.injectSdk(toHtmlDocument: webView, withStartPage: true );
}
func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {
DOT.injectSdk(toHtmlDocument: webView, withStartPage: false);
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
DOT.injectJavascript(withDomSearch: webView, isOnPageFinished: true)
}
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
...
if let url = navigationAction.request.url{
let absoluteString = url.absoluteString
if (absoluteString.hasPrefix("jscall-dot")) {
let request: URLRequest? = navigationAction.request
DOT.setWkWebView(webView, reqeust: request)
decisionHandler(.cancel)
return;
}
...
}
...
}- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation{
[DOT injectSdkToHtmlDocument:webView withStartPage:true];
}
- (void)webView:(WKWebView *)webView didCommitNavigation:(null_unspecified WKNavigation *)navigation {
[DOT injectSdkToHtmlDocument:webView withStartPage:false];
}
- (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation {
NSLog(@"2. didFinishNavigation");
[DOT injectJavascriptWithDomSearch:webView isOnPageFinished:true];
}
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
if([@"jscall-dot" isEqualToString:navigationAction.request.URL.scheme]) {
NSURLRequest *request = navigationAction.request;
decisionHandler(WKNavigationActionPolicyCancel);
[DOT setWkWebView:webView reqeust:request];
return;
}
}๋ชจ๋ฐ์ผ์ฑ๋ด ์น๋ทฐ์ PC ํน์ ๋ชจ๋ฐ์ผ์น๋ทฐ๋ก ๋์์ ์ฌ์ฉํ๋ ํ๋ฉด์ธ ๊ฒฝ์ฐ ์๋์ ๊ฐ์ ์นํท๋ทฐ๋ฅผ ํฌํจํ viewController์ viewWillApeear์ ์๋์ ๊ฐ์ด ์ ์ฉํด์ฃผ์ธ์.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
webView.evaluateJavaScript("navigator.userAgent") { (userAgent, error) in
if let ua = userAgent {
self.webView.customUserAgent = ua as! String + " RW2SDK"
}
}
}-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[[self webview] evaluateJavaScript:@"navigator.userAgent" completionHandler:^(id _Nullable userAgent, NSError * _Nullable error) {
NSString* addSuffix = [NSString stringWithFormat:@"%@ RW2SDK", userAgent];
if( @available(iOS 9.0,*)){
[self webview].customUserAgent = addSuffix;
}
else{
NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:userAgent, @"UserAgent", nil];
[[NSUserDefaults standardUserDefaults] registerDefaults:dictionary];
}
}];
}์ด๋ฒคํธ ์ค์
โ ํ๋ฉด์ ํ ๋๋ ์ด๋ฒคํธ ๋ถ์์ ์ํ ์ ์ฉ ๋ฐฉ๋ฒ์ ํ๋ฌ๊ทธ์ธ ์ค์ ๋ฐ ์ด๊ธฐํ ์ดํ์ ์๋ ๋งํฌ๋ฅผ ํด๋ฆญํ๊ฑฐ๋, ์ข์ธก IN-APP EVENT ๋ฉ๋ด๋ฅผ ํตํด ๊ฐ์ด๋๋ฅผ ํ์ธํ์ค ์ ์์ต๋๋ค.
๐ํ์ด์ง ๋ถ์ ๊ฐ์ด๋๋ก ์ด๋ํ๊ธฐ
๐์ธ์ฑ ์ด๋ฒคํธ ์ค์ ์ผ๋ก ์ด๋ํ๊ธฐ
2. ๊ณ ๊ธ ์ค์
๊ณ ๊ธ ์ค์ ์ด๋ ๋ฐ๋์ ์ ์ฉํ ํ์๋ ์์ง๋ง ์์ด์ฆํธ๋์ปค์ ํ์ฅ๋ ๋ถ์๊ธฐ๋ฅ์ ํ์ฉํ๊ธฐ ์ํด ์ถ๊ฐํด์ผ ํ๋ ์ค์ ์ ๋งํฉ๋๋ค. ํ์์ ๋ฐ๋ผ ์ ํ์ ์ผ๋ก ์ค์ ์ ์ถ๊ฐํด์ฃผ์๊ธฐ ๋ฐ๋๋๋ค.
Universal Link ์ค์
์ ๋๋ฒ์ ๋งํฌ ์ค์ ๊ฐ์ด๋๋ ๋ณ๋์ ๋ฌธ์์ ์ ๋ฆฌ๋์ด ์์ต๋๋ค.
Universal Link ์ค์ Universal Link ๋ถ์
continueUserActivity ๋ถ๋ถ์ ์๋์ ๊ฐ์ด ์ ์ฉ์ด ๋๋ฉด ์ ๋๋ฒ์ ๋งํฌ๋ฅผ ํตํ ๊ด๊ณ ๋ถ์์ด ๊ฐ๋ฅํฉ๋๋ค.
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
// ์๋์ ์ฝ๋๋ฅผ ์ ์ฉํด์ฃผ์ธ์
if let uniLink = userActivity.webpageURL?.absoluteString {
DOT.setDeepLink(uniLink)
let landingUri :String = DOT.parseAttributionLink(toGetDeeplinkUrl: uniLink)
// ๋ฆฌํด๋ฐ์ landingUri๊ฐ(DeepLink Sheme)์ผ๋ก ํ๋ฉด ์ง์
๋ก์ง ๊ตฌํ(๊ธฐ์กด open url์์ ์ฌ์ฉํ๋ ํ๋ฉด ์ด๋ ๋ก์ง๊ณผ ๋์ผํ๊ฒ ๊ตฌํํ๋ฉด ๋จ)
}
//
return false;
}๋ฅ๋งํฌ ์ค์
๋ฅ๋งํฌ๊ฐ ์ค์ ๋ url ์ ํตํด์ ์คํ๋ ์ด๋ฒคํธ๋ฅผ ๋ถ์ํฉ๋๋ค. ๋ถ์์ ํ๊ธฐ ์ํด์๋ ์ฑ์
custom url scheme์ค์ ํด์ผ ํฉ๋๋ค.
โ๏ธ์์ด์ฆํธ๋์ปค ๋์๋ณด๋์์ ์์ฑํ ์ดํธ๋ฆฌ๋ทฐ์
๋งํฌ๋ฅผ ํตํด ํ
์คํธ ๋ฐ ๊ด๊ณ ์งํ์ ์งํํ๋ฉฐ, ๋ฅ๋งํฌ ํด๋ฆญ ์ ์์ด์ฆํธ๋์ปค ์๋ฒ๊ฐ ์ฑ์ ์ค์น ์ฌ๋ถ๋ฅผ ํ๋จํ์ฌ ๋์ํฉ๋๋ค. ๋ค์๊ณผ ๊ฐ์ ํํ์ "https://xxxx.page.link" ๋งํฌ๋ฅผ ํด๋ฆญํ๊ฒ ๋๋ฉด ํด๋น URL์ด ๊ฐ๋ฅดํค๋ ์น์ผ๋ก ์ด๋ํจ์ผ๋ก์จ ์์ด์ฆํธ๋์ปค๊ฐ ์์งํ์ฌ์ผ ํ๋ ๊ด๊ณ ํ๋ผ๋ฏธํฐ๊ฐ์ด ์ ์ค๋ ์ ์์ด, ์ฑ์ผ๋ก ๋ฐ๋ก ์ด๋ ๊ฐ๋ฅํ ๋ค์๊ณผ ๊ฐ์ ํํ์ Unique ํ ์ปค์คํ
์คํค๋ง๊ฐ ํ์ํฉ๋๋ค.
์ด๋ฏธ ๋ง๋ค์ด์ง ์ ๋๋ฒ์
๋งํฌ๊ฐ ์กด์ฌ ํ๋ค๋ฉด ์์ด์ฆํธ๋์ปค์์ ์ฌ์ฉํ ๋ฅ๋งํฌ ์ง์
์คํค๋ง ์ค์ ์ '์ถ๊ฐ' ํด ์ฃผ์ธ์. (๋ฅ๋งํฌ์คํค๋ง ์ค์ ์ถ๊ฐ์ ๋ค๋ฅธ ๋งํฌ์ ์ด๋ ํ ์ํฅ๋ ์ฃผ์ง ์์ต๋๋ค.)
์์ ๊ฐ์ด ์ค์ ์ ๋ง์น์๊ฒ ๋์๋ฉด ์๋ฅผ๋ค์ด ๋ค์๊ณผ ๊ฐ ํํ์ ์ปค์คํ ์คํค๋ง๊ฐ ์์ฑ๋ฉ๋๋ค.
wisetracker://wisetracker.co.kr
์ฌ๊ธฐ์ wisetracker:// ๋ถ๋ถ์ดScheme(ํน์ ํ๋กํ ์ฝ) ์
๋๋ค. ๊ฐ๋ฐ์๊ฐ ์ฑ์ ์ด Scheme๋ฅผ ์ธ ๊ฒ์ด๋ผ๊ณ ๊ฒฐ์ ํ๋ ๊ฒ์ด๋ฉฐ, ํด๋น Scheme๋ง ์ค์ ์ ํ์
๋ ๋ฉ๋๋ค.
์ด์ด์ wisetracker.co.kr ๋ถ๋ถ์ ํน์ ํ์ด์ง์ ๋๋ฌํ๋๋ก ๋ง๋ค๊ธฐ ์ํ host(ํน์ path or ๋๋ฉ์ธ) ์
๋๋ค.
๊ทธ๋ฆฌ๊ณ wisetracker://wisetracker.co.kr?product=1 ์ด๋ฌํ ํํ๋ก ๋ง๋๋ ๊ฒฝ์ฐ๋ ํน์ ํ์ด์ง๋ก ์ด๋ํ๊ธฐ ์ํ parameter ๊ฐ์ ์ง์ ํ๋ ๊ฒ์ด๋ฉฐ ํด๋น ๋ถ๋ถ์ ์์ด์ฆํธ๋์ปค์ SDK๊ฐ ์๋ ๊ณ ๊ฐ์ฌ์ธก์์ ์ง์ ์ค์ ํด์ฃผ์
์ผ ํ๋ ๊ฐ์ด๋ฉฐ, ํน์ ํ์ด์ง๋ก ์ด๋ํ ํ์๊ฐ ์๋ค๋ฉด parameter ๊ฐ์ ๊ผญ ์ค์ ํ์ง ์์๋ ๋ฉ๋๋ค.
๋ฅ๋งํฌ ๋ถ์
์ฑ์ด ์ค์น๋ ์ดํ DeepLink๋ฅผ ํตํด์ ์ฑ์ด ์คํ๋๋ ๊ฒฝ๋ก ๋ถ์์ด ํ์ํ ๊ฒฝ์ฐ ์๋์ ๊ฐ์ด
setDeepLinkํจ์๋ฅผ ์ฌ์ฉํ๋ฉด ๋ถ์์ด ๊ฐ๋ฅํฉ๋๋ค.
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
DOT.setDeepLink(url.absoluteString)
return true
}- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
[DOT setDeepLink:[url absoluteString]];
return YES;
}๋ฅ๋งํฌ ์์ธ ์ฒ๋ฆฌ
์์ด์ฆํธ๋์ปค SDK๋ฅผ ์ ์ฉํ๊ณ , ๊ด๊ณ ๋ถ์์ ํ๊ณ ์ ํ๋ ๊ฒฝ์ฐ, ์์ด์ฆํธ๋์ปค ์์คํ ์์ ๋ฐ๊ธ๋ ๊ด๊ณ ๋ถ์ ๋งํฌ์ ์ํด์ ์ฑ์ ์คํํ๋ ๋ฅ๋งํฌ URL์ ๋ค์๊ณผ ๊ฐ์ด ๊ด๊ณ ๋ถ์ ๋ชฉ์ ์ ํ๋ผ๋ฏธํฐ๊ฐ ์ถ๊ฐ๋ ์ ์์ต๋๋ค.
ํนํ ์น์ฑ์ ๊ฒฝ์ฐ url ์ด๋ผ๋ ํ๋ผ๋ฏธํฐ๋ฅผ ์ฌ์ฉํ์ฌ ์น๋ทฐ์ ๋ก๋ฉ๋์ด์ง ์นํ์ด์ง url์ ์ ๋ฌํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์๋ฐ, ์ด์ ๊ด๋ จํ์ฌ ์๋์ ์ผ์ด์ค์๋ ๋ฌธ์ ๊ฐ ์๋์ง ๋ฐ๋์ ํ์ธํ์๊ธฐ ๋ฐ๋๋๋ค.
// ๊ธฐ์กด์ deeplink ์ ๊ด๊ณ ๋ถ์ ํ๋ผ๋ฏธํฐ๊ฐ ์ถ๊ฐ๋ ์์๋ฅผ ๋ณด์ฌ์ฃผ๊ณ ์์ต๋๋ค.
YOUR_SCHEMA://YOUR_HOST?url={YOUR_WEB_PAGE_URL}&trackId=M00200881641977334670
&w_start=h&_wtno=102&_wts=P1641977288745
... ์ค๊ฐ ์๋ต ...
&w_end=hDeffered Deep Link (์ง์ฐ๋ ๋ฅ๋งํฌ) ์ ์ฉ
๊ธฐ์กด์ [DOT initialization] SDK ์ด๊ธฐํ ํจ์ ๋์ ์๋์ [DOT initializationForDeferredCallback] ํจ์๋ฅผ ์ฌ์ฉํ์ฌ, ์์ ๋ ์ง์ฐ๋ ๋ฅ๋งํฌ์ ์ฒ๋ฆฌ๋ฅผ ์ํ ์ฝ๋๋ฅผ ์์ฑํฉ๋๋ค.
// your code...
[DOT initializationForDeferredCallback:launchOptions application:application callback:^{
// deferred deeplink ์ ๋ณด๋ [DOT getDeferredUrl]๋ก ์ฌ์ฉ์ด ๊ฐ๋ฅํ๋ฉฐ,
// ์ฑ์์๋ ํด๋น ๋ณ์๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ์ฌ์ฉํ ์ ์์.
// 1. callback ์ด ํธ์ถ๋๋ ์์ ์ ์ฆ์ __deferredUrl ํ๋ฉด์ผ๋ก ์ด๋ ์ฒ๋ฆฌ. __deferredUrl ๊ฐ์ด nil ์ด๋ฉด ๋ฉ์ธ ํ๋ฉด์ผ๋ก ์ด๋ ์ฒ๋ฆฌ.
// 2. __deferredUrl ๋ณ์๊ฐ์ ์ด๋๊ฐ์ ์ ์ฅํ๊ณ , ํ์๊ฐ์
์ดํ, ๋ก๊ทธ์ธ์ด ์๋ฃ๋ ์ดํ๋ฑ๊ณผ ๊ฐ์ด ํ์ํ ์์ ์ ์ ์ฅ๋ ๊ฐ์ ๊บผ๋ด์ ์ด๋ ์ฒ๋ฆฌ.
// 3. ์ฌ์ฉ ๊ฐ๋ฅํ Deferred deeplink ์ ๋ณด๊ฐ ์๋ ๊ฒฝ์ฐ์๋, __deferredUrl ๊ฐ์ด ๋(NULL) ์ด ๋ ์ ์์์ ๊ณ ๋ คํ์ฌ ์ฌ์ฉ.
NSString* __deferredUrl = [DOT getDeferredUrl];
NSLog(@"Deferred callback executed %@", __deferredUrl);
}];
// your code...์์ ๊ฐ์ด ์ง์ฐ๋ ๋ฅ๋งํฌ์ ๋ํ ๋์ ์ฝ๋๊ฐ ์ ์ฉ๋ ์ดํ์ ์์ด์ฆํธ๋์ปค ๋์ฌ๋ณด๋์์ ์๋์ ๊ฐ์ด ์ดํธ๋ฆฌ๋ทฐ์ ๋งํฌ๋ฅผ ์์ฑํ์๋ค๊ณ ๊ฐ์ ํด๋ณด๊ฒ ์ต๋๋ค.
์ง์ฐ๋ ๋ฅ๋งํฌ(๋ํผ๋ ๋ฅ๋งํฌ)๊ฐ ์ฌ์ฉ๋ ์ดํธ๋ฆฌ๋ทฐ์
๋งํฌ์ด๊ธฐ ๋๋ฌธ์ ๋ง์ฝ ์ฑ์ด ์ค์น๋์ด ์์ง ์์๋ ๊ฒฝ์ฐ๋ผ๋ฉด, ๋จผ์ ์ฑ ์ค์น๋ฅผ ์ํด ๋ง์ผ(๊ตฌ๊ธ์คํ ์ด, ์ฑ์คํ ์ด)์ผ๋ก ์ด๋๋๊ณ , ์ฑ ์ค์น ์ดํ์ ์ฑ์ ์คํ์ํค๊ฒ ๋๋ฉด NSString* __deferredUrl ๋ณ์์ ์ค์ ํ ์ฑ ์คํ ๋งํฌ๊ฐ ๋ค์ด๊ฐ ์์์ ํ์ธํ ์ ์์ต๋๋ค. (์: wisetester://mainscreen)
๋ฐ๋ผ์ ๋ค์ด๊ฐ ์๋ (๋ํผ๋) ๋ฅ๋งํฌ ๊ฐ์ ๋ฐ๋ผ ์ด๋ป๊ฒ ์ฒ๋ฆฌํ ์ง ์ดํ ์ก์ ์ ๋ํด ๋์๋๋ ์ฝ๋๋ฅผ ๊ฐ๋ฐํด ์ฃผ์๋ฉด ๋ฉ๋๋ค.
Facebook ๊ด๊ณ ์ฑ๊ณผ ์ธก์
Facebook ์ฑ์์ ์ ์ ๋๋ ์ค์น์๋ฅผ ๋ถ์ํ๊ธฐ ์ํด์๋ Facebook์์ ์ ๊ณตํ๋ SDK๊ฐ ๋ถ์ ๋์ ์ฑ์ ์ค์น๊ฐ ์ ํ๋์ด์ผ ํฉ๋๋ค.
๋น์ฆ๋์ค ์ธ์ฆ
Facebook Developer ์ฌ์ดํธ์ ์ฑ์ค์ -๊ธฐ๋ณธ์ค์ ์์ ๋น์ฆ๋์ค ์ธ์ฆ ์ฌ๋ถ๋ฅผ ํ์ธ ํด ์ฃผ์ธ์. ๋น์ฆ๋์ค ์ธ์ฆ์ด ์๋ฃ๋์ง ์์์ ๊ฒฝ์ฐ, ๋ฆฌํผ๋ฌ ์ ๋ณด๊ฐ ์์ ๋์ง ์์, facebook ๊ด๊ณ ์ฑ๊ณผ์ ๋ํ ์ธก์ ์ด ์ด๋ ต์ต๋๋ค.
FBSDK ๋ค์ด๋ก๋ ๋ฐฉ๋ฒ
1) XCode ํ๋ก์ ํธ ํ์ผ์ค Podfile ํ์ผ์ ๋ค์๊ณผ ๊ฐ์ด SDK๋ฅผ ์ถ๊ฐํฉ๋๋ค
pod โFBSDKCoreKitโ, โ11.2.1โ2) Podfile ์ dependency ๋ฅผ ์ถ๊ฐํ ๋ค์๋ Terminal ํ๋ก๊ทธ๋จ์ ์คํํ์ฌ ๋ค์์ ๋ช ๋ น์ ์ํํฉ๋๋ค
cmd> pod installFBSDK ์ค์น ๋ฐฉ๋ฒ
1) info.plist ํ์ผ์ source๋ก ๋ณด๊ธฐ ๋ก ์คํํฉ๋๋ค
2) ์ด๋ฆ ์์ฑ ์๋์ ํฌํจ๋ ๋ด์ฉ์ค [APP_ID] , [APP_NAME] , [CLIENT_TOKEN] ๋ถ๋ถ์ Facebook Developer Site ์์ ์ ๊ณตํ๋ ๊ฐ์ผ๋ก ์นํํ info.plist ํ์ผ์ ์ ์ฅํฉ๋๋ค
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>fb</string>
</array>
</dict>
</array>
<key>FacebookAppID</key>
<string>[APP_ID]</string>
<key>FacebookDisplayName</key>
<string>[APP_NAME]</string>
<key>FacebookClientToken</key>
<string>[CLIENT_TOKEN]</string>
<key>FacebookAdvertiserIDCollectionEnabled</key>
<true/> FBSDK ๋ก๋ถํฐ Install Referrer๋ฅผ ์์ ํ๊ณ , SDK์ ์ ๋ฌํ๋ ๋ฐฉ๋ฒ
์ด ๊ณผ์ ์์ Facebook ์ง์ฐ๋ ์ฑ ๋งํฌ๊ฐ ์๋ํ๋ ค๋ฉด Facebook ์ฑ๊ณผ ์ฑ ๋ชจ๋ ATT(์ฑ ์ถ์ ํฌ๋ช ์ฑ) ๊ถํ์ด ๋ถ์ฌ๋์ด์ผ ํฉ๋๋ค. FACEBOOK ์ฑ๊ณผ ๊ทํ์ ์ฑ ๋ชจ๋์์ ATT๋ฅผ ํ์ฑํํ ํ referrer ์์ ์ฌ๋ถ๋ฅผ ์ฒดํฌ ํด ์ฃผ์ธ์.
์ฌ์ฉ์๊ฐ Facebook์ ๋ ธ์ถ๋ ๊ด๊ณ ๋ฅผ ํด๋ฆญํ๊ณ ์ฑ์ ์ค์นํ ๊ฒฝ์ฐ ์ค์น๋ ์ฑ์์๋ FBSDK๋ฅผ ํตํด์ AppLinkData๋ฅผ ์์ ๋ฐ์ ์ ์์ต๋๋ค.
์๋์ ์ฝ๋์์ FBSDK๋ก๋ถํฐ AppLinkData๋ฅผ ์์ ๋ฐ๊ณ , ์์ ๋ฐ์ AppLinkData ๋ฅผ SDK๋ก ์ ๋ฌํ๋ ๋ฐฉ๋ฒ์ ํ์ธํ ์ ์์ต๋๋ค. ์ด ํจ์๋ appDelegate์ didFinishLaunchingWithOptions ํจ์์ ์ ์ฉํ์ธ์. SDK ์ด๊ธฐํ ์ด ํ์ DOT.setFacebookreferrerData() ํธ์ถ์ ํตํด SDK์ ๋ฆฌํผ๋ฌ url ์ด ์ ๋ฌ๋ ์ ์๋๋ก ํฉ๋๋ค.
์๋๋ Facebook ์ผ๋ก๋ถํฐ Install Referrer๋ฅผ ์์ ๋ฐ๊ธฐ ์ํด, ATT ๋์ ํ์ธ > ๋์ ์ฌ๋ถ์ ๋ฐ๋ผ SDK์ Facebook ๋ฆฌํผ๋ฌ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌ ํ๋ ์์ ์ฝ๋ ์ ๋๋ค.
import AppTrackingTransparency
import AdSupport
import FBSDKCoreKit
import DOT
func requestTrackingPermission() {
// iOS 14 ์ด์์ธ์ง ์ฒดํฌ
if #available(iOS 14, *) {
ATTrackingManager.requestTrackingAuthorization { (AuthorizationStatus) in
switch AuthorizationStatus {
// ATT ๋์
case .authorized:
Settings.setAdvertiserTrackingEnabled(true)
DispatchQueue.main.async(execute: { [] in
AppLinkUtility.fetchDeferredAppLink({ url, error in
if error != nil {
if let anError = error {
print("๐ Received error while fetching deferred app link: \(anError)")
}
}
if let unwrappedUrl = url {
// Facebook Deferred link ์์ & SDK ์ ๋ฌ.
print("๐ fetchDeferredAppLink: \(url.absoluteString)")
DOT.setFacebookreferrerData(url)
}
})
})
// SDK์ IDFA ์ค์
DOT.setIDFA(ASIdentifierManager.shared().advertisingIdentifier.uuidString)
// ATT ๊ฑฐ๋ถ ๋ฐ ๊ธฐํ
@unknown default:
DOT.denyATT();
}
}
}
// iOS 14 ์ดํ
else {
DOT.setATTAuthorizationStatus(3)
AppLinkUtility.fetchDeferredAppLink({ url, error in
if error != nil {
if let anError = error {
print("๐ Received error while fetching deferred app link: \(anError)")
}
}
if let unwrappedUrl = url {
// Facebook Deferred link ์์ & SDK ์ ๋ฌ.
DOT.setFacebookreferrerData(unwrappedUrl)
}
});
}
}#import "AppDelegate.h"
#import <DOT/DOT.h>
#import <AppTrackingTransparency/ATTrackingManager.h>
#import <AdSupport/AdSupport.h>
#import <FBSDKCoreKit/FBSDKCoreKit.h>
- (void)requestTrackingPermission {
if (@available(iOS 14, *)) {
[ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus authorizationStatus) {
switch (authorizationStatus) {
case ATTrackingManagerAuthorizationStatusAuthorized:
[FBSDKSettings setAdvertiserTrackingEnabled:YES];
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"FBSDKAppLinkUtility fetchDeferredAppLink started.");
[FBSDKAppLinkUtility fetchDeferredAppLink:^(NSURL *_Nullable url, NSError *_Nullable error) {
if (error) {
NSLog(@"๐ Received error while fetching deferred app link : %@", error);
}
if (url) {
NSLog(@"๐ fetchDeferredAppLink : %@", [url absoluteString]);
[DOT setFacebookreferrerData:url];
}
else{
NSLog(@"๐ fetchDeferredAppLink is nil");
}
NSLog(@"FBSDKAppLinkUtility fetchDeferredAppLink finished.");
}];
});
[DOT setIDFA:[[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString]];
break;
default:
[DOT denyATT];
break;
}
}];
} else {
// 14 ์ดํ IDFA ์ฒ๋ฆฌ
[DOT setATTAuthorizationStatus:3];
// 14.0 ๋ฏธ๋ง์ธ ๊ฒฝ์ฐ...
dispatch_async(dispatch_get_main_queue(), ^{
[FBSDKAppLinkUtility fetchDeferredAppLink:^(NSURL *_Nullable url, NSError *_Nullable error) {
if (error) {
NSLog(@"๐ Received error while fetching deferred app link: %@", error);
}
if (url) {
[DOT setFacebookreferrerData:url];
}
}];
});
}
}
Facebook SDK์ ๊ด๋ จํ์ฌ ๋ณด๋ค ์์ธํ ์ค์น ๋ฐฉ๋ฒ์ ์๋์ ๋งํฌ์์ ํ์ธ์ด ๊ฐ๋ฅํฉ๋๋ค.
FBSDK iOS ์ ์ฉ๋ฐฉ๋ฒ ์์ธํ ๋ณด๊ธฐ
Facebook ์ฑ ์ค์นํ ๊ด๊ณ ์ฑ๊ณผ ์ธก์ ์ ์ํ ํ ์คํธ ์ ์ฐธ๊ณ ์ฌํญ
iOS์ ๊ฒฝ์ฐ Facebook Developer - ์ฑ ๊ด๊ณ ์ง์ ๋๊ตฌ๋ฅผ ํตํด '์ฑ ์ค์นํ ๊ด๊ณ ํ
์คํธ' ์ iOS ๋ณด๋ด๊ธฐ ๋ฒํผ์ ํด๋ฆญํ์ฌ๋ ์ง์ฐ๋ ๋ฅ๋งํฌ๊ฐ ์๋ ์ผ๋ฐ์ ๋ฅ๋งํฌ๋ก ๋์ํ๊ฒ ๋ฉ๋๋ค.
iOSํ ์คํธ์ด์ง๋ง "Android์ ๋ณด๋ด๊ธฐ" ๋ฒํผ์ ํด๋ฆญํ์ฌ ์๋์ ๊ฐ์ ์ง์ฐ๋ ๋ฅ๋งํฌ ์ฒ๋ฆฌ ํ์ ์ด ๋ฐ์๋๋์ง ํ์ธ ํ ํ ์คํธ๋ฅผ ์งํ ํด ์ฃผ์ธ์.

4. iOS 14 ๊ฐ์ธ์ ๋ณด๋ฐฉ์นจ ๋ณ๊ฒฝ ๊ด๋ จ ๊ฐ์ด๋
iOS 14๋ถํฐ IDFA๋ฅผ ํ๋ํ๊ธฐ ์ํด์๋ ์ฌ์ฉ์์ ๋์๋ฅผ ์ป์ด์ผ ํฉ๋๋ค.
3.1 info.plistํ์ผ์ NSUserTrackingUsageDescription ์ค์ ์ถ๊ฐ
<key>NSUserTrackingUsageDescription</key>
<string>Your data will be used to deliver personalized ads to you.</string>3.2 App Tracking Transparency ๋์ System Alert ๋
ธ์ถ & API ํธ์ถ
IDFA ํ๋์ ์ํด ์ฑ ์ถ์ ํฌ๋ช ์ฑ ๋์ ์์ฒญ System Alert(๋ํ ์์)์ ๋์์ผ ํฉ๋๋ค. ๋์ ์์ฒญ System Alert(๋ํ ์์) ํ๋ฉด์ ๋์ฐ๋ ค๋ฉด requestTrackingAuthorizationWithCompletionHandler:๋ฅผ ํธ์ถํฉ๋๋ค. completionHandler์์ ๋์ ์ SDK API๋ฅผ ํธ์ถํ๋๋ก ์์ ๊ฐ์ด ๊ตฌํํ์๋ฉด ๋ฉ๋๋ค.
import AppTrackingTransparency
import AdSupport
if #available(iOS 14, *) {
ATTrackingManager.requestTrackingAuthorization { (AuthorizationStatus) in
if(AuthorizationStatus == .authorized) {
DOT.setIDFA(ASIdentifierManager.shared().advertisingIdentifier.uuidString)
}
}
} else {
DOT.setATTAuthorizationStatus(3)
}#import <AppTrackingTransparency/ATTrackingManager.h>
#import <AdSupport/AdSupport.h>
if (@available(iOS 14, *)) {
[ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {
if(status == ATTrackingManagerAuthorizationStatusAuthorized) {
[DOT setIDFA:[[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString]];
}
}];
} else {
[DOT setATTAuthorizationStatus:3];
}๊ด๋ จ ๊ณต์ ๋ฌธ์ https://developer.apple.com/app-store/user-privacy-and-data-use/
๊ฐ๋ฐ ๊ด๋ จ ๊ณต์ ๋ฌธ์ https://developer.apple.com/documentation/apptrackingtransparency
Last updated
Was this helpful?