# Flutter 플러그인 연동

## 1. 플러그인 설치 (Android/iOS 공통 설정)

### 1.1 pubspec.yaml에 depedency 추가

아래 경로에 있는 `pubspec.yaml` 파일에 `dot_flutter: ^1.0.12` dependency를 추가합니다.

![](/files/jlfcmFCoJLUslHaBf7kZ)

```yaml
dependencies:
  flutter:
    sdk: flutter 
  
  # Wisetracker Analytics SDK   
  dot_flutter: ^1.0.12
```

### 1.2 프로젝트 폴더에서 커맨드 라인으로 아래 명령어를 실행해주세요.

```
flutter pub get
```

### 1.3 의존성 추가 완료 이후, dart 파일에서 패키지를 import하여 사용 할 수 있습니다.

```dart
import 'package:dot_flutter/dot_flutter.dart';
```

## 2. Android 플러그인 설정

### 2.1 **repository** 추가(build.gradle.kts)

android프로젝트에서 가장 상위에 있는 build.gradle(project)에 아래와 같이 와이즈트래커의 **maven repository 주소**를 추가합니다.

```java
import java.net.URL

allprojects {
    repositories {
        google()
        mavenCentral() 
        maven {
            val endPoint = "https://analytics.wisetracker.co.kr/console/android/sdk/github/credentials.do"
            url = uri(URL("$endPoint?name=URI").readText().trim())
            credentials {
                username = URL("$endPoint?name=USER").readText().trim()
                password = URL("$endPoint?name=TOKEN").readText().trim()
            }
        } 
    }
}
```

### 2.2 dependency 추가(build.gradle.kts)

빨간색으로 표시된 build.gradle 파일의 dependencies에 `base_module`과 `new_dot_module` implementation을 추가합니다.

![](/files/9fWO8vEpXnoSH3Fmv4Hr)

```yaml
dependencies {
    implementation("com.sdk.wisetracker:base_module:latest.release")
    implementation("com.sdk.wisetracker:new_dot_module:latest.release")
}
```

### 2.3 AuthorizationKey 설정

프로젝트폴더 내부의 android 폴더에서 `android/app/src/main/res/values` 경로로 들어갑니다. strings.xml 파일이 없고, styles.xml 파일만 존재할 경우 **strings.xml 파일을 새로 생성**하여 주세요. 아래 경로 그림을 참고해 주세요.

![왼쪽은 폴더 내 경로 , 오른쪽은 안드로이드 스튜디오 경로](/files/RS0BXLzlk61YzAKva1tE)

```markup
<resources>
    <string name="app_name">SampleFlutter</string>
    <string-array name="dotAuthorizationKey">
        <item name="useMode">1</item>
        <item name="serviceNumber">xxxxx</item>   <!--서비스 번호 필수 변경! -->
        <item name="expireDate">14</item>
        <item name="isDebug">false</item>
        <item name="isInstallRetention">true</item>
        <item name="isFingerPrint">true</item>
        <item name="accessToken"></item>
    </string-array>
</resources>
```

추가한 코드 중 `serviceNumber` 의 value를 올바른 값으로 변경해야 합니다.&#x20;

[<mark style="color:blue;">와이즈트래커 대시보드</mark>](https://analytics.wisetracker.co.kr/)에 로그인하여 설정 > 서비스설정 메뉴에서 '<mark style="color:red;">`서비스번호`</mark>' 항목에 기재된 숫자를 확인 후 복사하여 serviceNumber 값을 변경 해 주세요.

<figure><img src="/files/c3cUFi4kczUln6oJ16bj" alt=""><figcaption><p>서비스번호 확인</p></figcaption></figure>

### 2.4 Http 통신 허용 설정

프로젝트의 **Target API 28** 이상일 경우 <mark style="color:red;">AndroidManifest.xml 파일</mark>에서 application부분에 `android:networkSecurityConfig="@xml/network_security_config"` 코드를 추가하여 Http 통신 허용 추가합니다.

![AndroidManifest.xml 파일 경로 : 왼쪽은 폴더 , 오른쪽은 안드로이드 스튜디오 경로](/files/j7dWDawNNn70bdS2p2Hv)

```markup
<application
        android:label="my_app"
        android:name="${applicationName}"
        android:icon="@mipmap/ic_launcher"
        android:networkSecurityConfig="@xml/network_security_config">
```

AndroidManifest.xml 완료 후 <mark style="color:red;">프로젝트명/android/app/src/main/res 경로</mark>에 xml 폴더를 새로 만든 후 `network_security_config.xml` 파일을 새로 생성하여 아래의 코드를 복사, 붙여넣기 합니다.

![왼쪽은 폴더 내 경로 , 오른쪽은 안드로이드 스튜디오 경로](/files/V6UREd9YBEQPUAhjBywZ)

```markup
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">trk.analytics.wisetracker.co.kr</domain>
    </domain-config>
</network-security-config>
```

## 3. Android 초기화

Application을 상속받는 클래스가 아닌 Activity를 상속받는 최초 기본/메인 화면의 onCreate() 함수에 적용해 주세요.

(모든 Activity 에 추가하는 것이 아닌 <mark style="color:red;">**최초로 진입하는 메인 Activity에 1회 적용**</mark>합니다.)

```dart
import com.sdk.wisetracker.new_dot.open.DOT;

class MainActivity: FlutterActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState);
        /**
         * Wisetracker SDK init
         * **/
        DOT.initialization(this);
    };
}
```

![왼쪽은 폴더 내 경로 , 오른쪽은 안드로이드 스튜디오 경로](/files/2zETzEsdKFXERbPsxRUA)

### Deffered Deep Link (지연된 딥링크) 적용(Android)

{% hint style="info" %}

1. 지연된 딥링크 기능은 `Growth` 레벨 이상의 사용자에게 제공됩니다.
2. 지연된 딥링크 기능 제공 SDK 버전 - Android SDK: Base Modeul - 1.0.81 이상 / New Dot Module - 1.0.51 이상
3. 지연된 딥링크를 사용하는경우  기존의 DOT.initialization(this); 호출대신 <mark style="color:red;">DOT.initializationForDeferredCallback</mark> 함수를 사용 해 주세요.
   {% endhint %}

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
import com.sdk.wisetracker.new_dot.open.DOT;

class MainActivity: FlutterActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState);
        /**
         * Wisetracker SDK init
         * **/
         DOT.initializationForDeferredCallback(this) { 
            // deferred deeplink  정보는 DOT.getDeferredUrl() 로 사용이 가능하며,
            // 앱에서는 해당 변수를 다음과 같이 사용할 수 있음.
            // 1. callback 이 호출되는 시점에 즉시 __deferredUrl 화면으로 이동 처리. __deferredUrl 값이 nil 이면 메인 화면으로 이동 처리.
            // 2. __deferredUrl 변수값을 어딘가에 저장하고, 회원가입 이후, 로그인이 완료된 이후등과 같이 필요한 시점에 저장된 값을 꺼내서 이동 처리.
            // 3. 사용 가능한 Deferred deeplink 정보가 없는 경우에는, __deferredUrl 값이 널(NULL) 이 될 수 있음을 고려하여 사용.
            String __deferredUrl = DOT.getDeferredUrl();
            WiseLog.d("current deferred url : $__deferredUrl")
            if(__deferredUrl != null){
                // Dart 로 링크 전달
                val flutterChannel = MethodChannel(flutterEngine?.dartExecutor as BinaryMessenger, "dot");
                flutterChannel.invokeMethod("deferredLink", __deferredUrl);
            }
        }
    };
}
```

{% endtab %}

{% tab title="Dart" %}

```dart
//.dart 에서 전달된 링크 수신 예제 코드 

// 1. service 추가. 
import 'package:flutter/services.dart';

void main() {
        WidgetsFlutterBinding.ensureInitialized();   
...
...
}

class MyApp extends StatelessWidget {

  // 2.deferred link 수신 채널 생성 
  static const __deferredLinkOfWisetracker = MethodChannel('dot');

  @override
  Widget build(BuildContext context) {

        // 3. Native 에서 dot 채널로 전송되어 오는 데이터 처리 code 
    __deferredLinkOfWisetracker.setMethodCallHandler((call) async {
        // deferredLink 로 전달되어 오면 
        if (call.method == 'deferredLink') { 
           // 전달 받은 call.arguments 에 따라서 화면 이동 처리. 
           print("call.arguments " + call.arguments); 
        }
      });
    ...
    ...
  }
}
```

{% endtab %}
{% endtabs %}

### Facebook 광고 성과 측정

[Facebook App Ads](https://www.facebook.com/business/help/1471413626484885?id=1858550721111595) 의 퍼포먼스를 와이즈트래커로 측정하는데 필요한 설정으로, **Facebook SDK가 앱에 추가되어 있는 경우**에만 설정을 적용할 수 있습니다.

아래 페이지로 이동하여 Android Facebook 광고 성과 측정을 위한 코드를 추가 해 주세요.

{% embed url="<https://document.wisetracker.co.kr/v/v2-developer/sdk/android/integration#facebook_ad_aos>" %}
Android Facebook 광고성과측정
{% endembed %}

## 4. iOS 플러그인 설정

### 4.1 SDK 설치 <a href="#sdk-1" id="sdk-1"></a>

**Cocoapod 환경에서 SDK 다운로드 방법**

XCode 프로젝트 중 Podfile 파일에 다음과 같이 SDK를 추가합니다

```
pod 'RW'
```

기존에 SDK를 한번 설치한 경우에는 설치할SDK 버전을 표시해야 하는 경우도 있습니다. 아래와 같이 설치할 SDK버전을 명시적으로 표시하면 됩니다.

```
pod 'RW', '~> 1.1.58'
```

Podfile 에 해당라인을 추가한 후 Terminal 프로그램을 실행하여 다음의 명령을 수행합니다

```
pod install
```

SDK 버전 업데이트의 경우 다음의 명령을 수행합니다.

```
pod update
```

정상적으로 설치가 되면 아래와 같은 폴더 구조를 확인할 수 있습니다.

<figure><img src="/files/JUOmRUJbAal7Mzd5TDzC" alt=""><figcaption></figcaption></figure>

### 4.2 HTTP 통신 허용 설정

HTTP통신을 허용하기 위해 info.plist파일을 엽니다. 파일의 위치는 다음과 같습니다.

![](/files/zfiElYv72t5YtEdTkwsW)

`</dict>검색`을 통해 닫히는 라인 바로 위에 `NSAppTransportSecurity` 코드를 추가합니다.

```markup
    <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
    </dict>
</dict>
</plist>
```

### 4.3 dotAuthorizationKey 값 세팅

NSAppTransportSecurity 코드를 추가한 곳 바로 아래에 `dotAuthorizationKey`도 추가 해 줍니다.

```markup
<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를 올바른 값으로 변경해야 합니다.&#x20;

[<mark style="color:blue;">와이즈트래커 대시보드</mark>](https://analytics.wisetracker.co.kr/)에 로그인하여 설정 > 서비스설정 메뉴에서 '<mark style="color:red;">`서비스번호`</mark>' 항목에 기재된 숫자를 확인 후 복사하여 serviceNumber 값을 변경 해 주세요.

<figure><img src="/files/c3cUFi4kczUln6oJ16bj" alt=""><figcaption><p>서비스번호 확인</p></figcaption></figure>

### 4.4 Pod install 이슈 발생 시

iOS 실행시 Pod install에서 이슈 발생하는 경우 ios/Podfile 내에 use\_frameworks! 부분을 아래와 같이 주석처리를 해주세요.

```
target 'Runner' do
  # use_frameworks!
  use_modular_headers!

  flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
end
```

## 5. iOS 초기화

AppDelegate의 `didFinishLaunchingWithOptions` 함수에 SDK를 Initialization하기 위한 코드를 다음과 같이 적용합니다. AppDelegate 파일의 위치는 다음과 같습니다.

![왼쪽은 폴더 내 경로 , 오른쪽은 xcode 경로](/files/vR6LhICxyXBuwqElqHyJ)

```swift
/** wisetracker SDK import */
import DOT

override func application(
      _ application: UIApplication,
            ...
            ...
      /** wisetracker SDK init */
      DOT.initialization(launchOptions, application: application)
      
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}
```

### Deffered Deep Link (지연된 딥링크) 적용(iOS)

{% hint style="info" %}

1. 지연된 딥링크 기능은 `Growth` 레벨 이상의 사용자에게 제공됩니다.
2. iOS SDK: RW 1.1.52 이상
3. 지연된 딥링크를 사용하는경우  기존의 DOT.initialization 호출대신 <mark style="color:red;">DOT initializationForDeferredCallback</mark> 함수를 사용 해 주세요.
   {% endhint %}

{% tabs %}
{% tab title="Objective-C" %}

```objectivec
[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);
    
    if(__deferredUrl != nil){
        dispatch_async(dispatch_get_main_queue(), ^{
            // Dart 로 링크 전달
            FlutterViewController* controller = (FlutterViewController*)self.window.rootViewController;
            FlutterMethodChannel* methodChannel = [FlutterMethodChannel
                methodChannelWithName:@"dot"
                      binaryMessenger:controller.binaryMessenger];
            [methodChannel invokeMethod:@"deferredLink" arguments:__deferredUrl];
        });
    }
}];
```

{% endtab %}

{% tab title="Swift" %}

```swift
DOT.initialization(forDeferredCallback: launchOptions, application: application ) {
    // deferred deeplink  정보는 DOT.getDeferredUrl() 로 사용이 가능하며,
    // 앱에서는 해당 변수를 다음과 같이 사용할  수 있음.
    // 1. callback 이 호출되는 시점에 즉시 __deferredUrl 화면으로 이동 처리. __deferredUrl 값이 nil 이면 메인 화면으로 이동 처리.
    // 2. __deferredUrl 변수값을 어딘가에 저장하고, 회원가입 이후, 로그인이 완료된 이후등과 같이 필요한 시점에 저장된 값을 꺼내서 이동 처리.
    let deferredUrl = DOT.getDeferredUrl()
    print("Deferred callback executed \(deferredUrl)")
    if(deferredUrl != nil){ 
        DispatchQueue.main.async {
            // Dart로 링크 전달
            if let controller = self.window?.rootViewController as? FlutterViewController {
                let methodChannel = FlutterMethodChannel(name: "dot", binaryMessenger: controller.binaryMessenger)
                methodChannel.invokeMethod("deferredLink", arguments: deferredUrl)
            }
        }
    }
}
```

{% endtab %}

{% tab title="Dart" %}

```dart
// .dart 에서 전달된 링크 수신 예제 코드 

// 1. service 추가. 
import 'package:flutter/services.dart';

void main() {
        WidgetsFlutterBinding.ensureInitialized();   
...
...
}

class MyApp extends StatelessWidget {

  // 2.deferred link 수신 채널 생성 
  static const __deferredLinkOfWisetracker = MethodChannel('dot');

  @override
  Widget build(BuildContext context) {

        // 3. Native 에서 dot 채널로 전송되어 오는 데이터 처리 code 
    __deferredLinkOfWisetracker.setMethodCallHandler((call) async {
        // deferredLink 로 전달되어 오면 
        if (call.method == 'deferredLink') { 
           // 전달 받은 call.arguments 에 따라서 화면 이동 처리. 
           print("call.arguments " + call.arguments); 
        }
      });
    ...
    ...
  }
}
```

{% endtab %}
{% endtabs %}

### Facebook 광고 성과 측정

[Facebook App Ads](https://www.facebook.com/business/help/1471413626484885?id=1858550721111595) 의 퍼포먼스를 와이즈트래커로 측정하는데 필요한 설정으로, **Facebook SDK가 앱에 추가되어 있는 경우**에만 설정을 적용할 수 있습니다.

아래 페이지로 이동하여 ios Facebook 광고 성과 측정을 위한 코드를 추가 해 주세요.

{% embed url="<https://document.wisetracker.co.kr/v/v2-developer/sdk/ios/integration#facebook_ad_ios>" %}
ios Facebook 광고성과측정
{% endembed %}

## 6. 이벤트 설정

:white\_check\_mark:화면전환 또는 이벤트 분석을 위한 적용 방법은 플러그인 설정 및 초기화 이후에  [`sample소스`](https://github.com/WisetrackerTechteam/SdkSampleSource.git)를 다운받으신 후 확인이 가능합니다.

### 설정 확인&#x20;

모든 설정 완료 후 log를 통해 데이터 수집을 확인 합니다. (Android 기준)\
\&#xNAN;*아래 log 내용은 서비스별로 달라질 수 있으나, Data Receive Success가 기록되는지를 중심으로 확인이 필요합니다.*

```
[WiseLog]: RetrofitLogInterceptor#intercept(33)#DEBUG_MESSAGE#SERVER RESPONSE 
-> {"msg":"Data Receive Success","code":"RES001","visitNewServerTime":1657536903244,
"attributedInfo":{"linkId":{},"install":{"isNewInstall":false},"pushMessage":{},
"assist":[],"iosAd":{},"open":{},"abusing":{"installDt":1657256885220,
"regDt":1657256887972,"adid":"","sno"xxxxx:,abuseTarget":"organic","platform":"AOS"}}}
```

log에 해당 내용이 확인이 된다면 수신이 정상적으로 이루어졌으며, 와이즈트래커의 SDK를 호출할 준비가 완료되었습니다.&#x20;

### :warning:IOS platform 지정 에러 발생시

:warning: ios 확인을 위해 "flutter run" 확인 시 아래와 같은 에러 코드가 발생한다면 다음과 같은 조치를 해야합니다.

프로젝트 폴더 > ios폴더 > Podfile 에서 가장 상단에 있는 platform : ios 버전을 9.3으로 변경 해 주세요. (주석 처리가 되어 있다면 주석 해제 후 9.3 버전으로 수정)

```
[!] Automatically assigning platform `iOS` with version `9.0` on target `Runner` because no platform was specified. Please specify a platform for this target in your Podfile. See
    `https://guides.cocoapods.org/syntax/podfile.html#platform`.
```

![](/files/guPUgrMcgPKhQMzyOWs4)

### 5. SampleCode 제공

☑️Flutter SDK 설정을 도와드리기위한 샘플코드가 제작되어 있습니다.&#x20;

해당 가이드 참고시 샘플 코드도 함께 참고 하신다면, SDK 적용을 수월하게 진행하실 수 있습니다.

{% embed url="<https://github.com/WisetrackerTechteam/SdkSampleSource.git>" %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://document.wisetracker.co.kr/v2-developer/sdk/flutter/plugin.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
