# Flutter 연동

## 사전 작업 <a href="#pre-work" id="pre-work"></a>

Push Notification을 설정하려면 Flutter SDK 연동이 필요합니다. 다음 가이드를 완료 후 진행해주세요.

{% content-ref url="../../sdk-integrating/initialize/flutter-sdk" %}
[flutter-sdk](https://docs.marketap.io/t3ZS4WXNMj0HK27EtIMV/developer/sdk-integrating/initialize/flutter-sdk)
{% endcontent-ref %}

## 1. 푸시 권한 요청 (선택)

SDK가 제공하는 함수로 플랫폼 공통 푸시 권한 요청 및 등록을 진행할 수 있습니다. 푸시 권한 설정에 다른 솔루션을 사용하거나 직접 관리중일 경우 생략해주세요.

<pre class="language-dart"><code class="lang-dart">import 'package:marketap_sdk/marketap_sdk.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  Marketap.initialize('PROJECT_ID');
<strong>  Marketap.requestAuthorizationForPushNotifications() // 권한 요청 및 등록
</strong>  runApp(const MyApp());
}
</code></pre>

## 2. iOS

### 사전 작업

[#id-1.-xcode](https://docs.marketap.io/t3ZS4WXNMj0HK27EtIMV/developer/push-notification/ios#id-1.-xcode "mention") 가이드에 따라 Runner.xcworkspace의 Runner 프로젝트에 Push Capabilities, Notification Service Extension을 추가합니다.

### 2.1 AppDelegate 연동 코드 추가

다음과 같이 AppDelegate에 연동 코드를 추가합니다.

<pre class="language-swift"><code class="lang-swift">
@main
@objc class AppDelegate: FlutterAppDelegate {
    override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        GeneratedPluginRegistrant.register(with: self)
        // ...
        Marketap.application(application, didFinishLaunchingWithOptions: launchOptions)
<strong>        UNUserNotificationCenter.current().delegate = self
</strong>        
        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
    }
    
    override func application(
        _ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
    ) {
        // 푸시 토큰 수집
<strong>        Marketap.setPushToken(token: deviceToken)
</strong>    }

    override func userNotificationCenter(
        _ center: UNUserNotificationCenter, willPresent notification: UNNotification,
        withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void
    ) {
        // active 상태 노티피케이션 수신 핸들링 추가
<strong>        if Marketap.userNotificationCenter(center, willPresent: notification, withCompletionHandler: completionHandler) {
</strong><strong>            return
</strong><strong>        }
</strong>        // ...
    }

    override func userNotificationCenter(
        _ center: UNUserNotificationCenter,
        didReceive response: UNNotificationResponse,
        withCompletionHandler completionHandler: @escaping () -> Void
    ) {
        // 푸시 클릭 핸들링 추가
<strong>        if Marketap.userNotificationCenter(center, didReceive: response, withCompletionHandler: completionHandler) {
</strong><strong>            return
</strong><strong>        }
</strong>        // ...
    }
}
</code></pre>

### 2.2 NotificationServiceExtension 설정

[#id-1.2-notification-service-extension](https://docs.marketap.io/t3ZS4WXNMj0HK27EtIMV/developer/push-notification/ios#id-1.2-notification-service-extension "mention") 에서 설정한 NotificationServiceExtension용 sdk를 설치해야합니다. `ios/Podfile` 에 다음과 같이 추가합니다.

```ruby
target 'Runner' do
  ...
  # 추가한 NotificationServiceExtension 타겟 이름을 넣어주세요.
  target 'DummyNotificationServiceExtension' do
    inherit! :search_paths
    pod 'MarketapSDKNotificationServiceExtension', '1.0.9'
  end
end
```

`pod install` 이후, [#id-3.3-notification-service-extension](https://docs.marketap.io/t3ZS4WXNMj0HK27EtIMV/developer/push-notification/ios#id-3.3-notification-service-extension "mention") 문서를 참고하여 설정을 완료합니다.

## 3. Android

### 사전 작업

Marketap Android SDK는 [Jitpack](https://jitpack.io/)을 통해 배포되고 있습니다.  Flutter프로젝트의 android 디렉토리 최상단 build.gradle.kts 파일에 아래 repository를 추가해주세요.

<pre class="language-kts"><code class="lang-kts">dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {		
        mavenCentral()
<strong>	maven { url = uri("https://jitpack.io") }
</strong>    }
}
</code></pre>

이어서, AndroidManifest.xml 파일에 아래 권한들을 추가합니다. 각각 푸시 발송, 이벤트 및 유저정보 수집을 목적으로 합니다.

```xml
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.INTERNET" />
```

### 3.1 푸시 연동

{% hint style="success" %}
Marketap은 안드로이드 푸시를 지원하기 위해서 Firebase Cloud Messaging을 사용하고 있습니다. 따라서 Flutter 프로젝트의 안드로이드 의존성에 Firebase가 추가되어야 합니다. 자세한 내용은 구글의 [가이드 문서](https://firebase.google.com/docs/android/setup?hl=ko)를 참고해주세요.
{% endhint %}

푸시를 수신하기 위해서는 FirebaseMessagingService 설정이 필요합니다.

{% tabs %}
{% tab title="신규 연동" %}
Marketap은 FCM 기반 푸시 메시지를 수신하고 클릭을 처리하기 위한 전용 서비스를 제공합니다. `MarketapFirebaseMessagingService` 클래스를 AndroidManifest.xml 파일에 등록해 주세요.

```xml
<service
    android:name="com.marketap.sdk.client.push.MarketapFirebaseMessagingService"
    android:exported="false">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>
```

{% endtab %}

{% tab title="기존 서비스와 함께 사용" %}
이미 앱에서 FirebaseMessagingService를 사용 중이라면, Marketap에서 제공하는 `MarketapFirebaseMessagingService.handleMarketapRemoteMessage()` 메서드를 통해 Marketap 푸시만 안전하게 처리할 수 있습니다.

```kotlin
// Kotlin 예시
class MyFirebaseMessagingService : FirebaseMessagingService() {
    override fun onMessageReceived(remoteMessage: RemoteMessage) {
        super.onMessageReceived(remoteMessage)

        if (MarketapFirebaseMessagingService.handleMarketapRemoteMessage(this, remoteMessage)) {
            // Marketap 메시지를 처리했습니다.
            // 추가 처리는 필요하지 않습니다.
        } else {
            // Marketap 메시지가 아닙니다.
            // 다른 푸시 핸들러가 있다면 이 메시지를 전달하세요.
        }
    }
}
```

```java
// Java 예시
public class MyFirebaseMessagingService extends FirebaseMessagingService {
    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);

        if (MarketapFirebaseMessagingService.handleMarketapRemoteMessage(this, remoteMessage)) {
            // Marketap 메시지를 처리했습니다.
            // 추가 처리는 필요하지 않습니다.
        } else {
            // Marketap 메시지가 아닙니다.
            // 다른 푸시 핸들러가 있다면 이 메시지를 전달하세요.
        }
    }
}
```

{% endtab %}
{% endtabs %}

## 4. 클릭 액션 커스텀하기 (선택)

푸시 캠페인에 클릭 액션 URL이 설정되어 있는 경우, 마켓탭 SDK는 OS별 기본 동작으로 URL을 처리합니다.

OS별 동작은 아래 링크를 참고해주세요.

* ios: [#id-4](https://docs.marketap.io/t3ZS4WXNMj0HK27EtIMV/developer/push-notification/ios#id-4 "mention")
* android: [#id-5](https://docs.marketap.io/t3ZS4WXNMj0HK27EtIMV/developer/push-notification/android#id-5 "mention")

이 기본 동작을 비활성화하고 클릭 시 액션을 직접 제어하려면, 아래 페이지 안내에 따라 clickHandler 기반 커스텀 연동을 진행해주세요.

{% content-ref url="../../advanced-usage/custom-click-handler" %}
[custom-click-handler](https://docs.marketap.io/t3ZS4WXNMj0HK27EtIMV/developer/advanced-usage/custom-click-handler)
{% endcontent-ref %}

## 5. 이어서 진행하기

이제 Push Notification 연동이 완료되었습니다. 아래 문서에서 이어서 진행해주세요.

<table data-view="cards"><thead><tr><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td>Push Notification 테스트</td><td><a href="../test">test</a></td></tr><tr><td>In-App Campaign 테스트</td><td><a href="../../in-app-message/in-app-campaign">in-app-campaign</a></td></tr><tr><td>심화 연동</td><td><a href="../../advanced-usage/overview">overview</a></td></tr></tbody></table>
