> For the complete documentation index, see [llms.txt](https://developers.fingerpush.com/link/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developers.fingerpush.com/link/flutter.md).

# Flutter SDK

2026년 5월 27일에 업데이트됨

{% hint style="success" %} <mark style="color:$success;">**Flutter SDK v1.0.0-alpha01 (호환성 정보)**</mark>

**Flutter** 3.10.0+ | **Dart** 3.0.0+ | **Android** API 23+ | **iOS** 15.0+
{% endhint %}

## 플러터 SDK 설치하기

핑거푸시 링크 플러터 SDK는 아래 방법으로 설치할 수 있습니다.

1. 자동 설치

```bash
 flutter pub add fplink_flutter
```

2. 수동 설치&#x20;

{% code title="pubspec.yaml" %}

```yaml
dependencies:
  flutter:
    sdk: flutter

  fplink_flutter: ^1.0.0-alpha01
```

{% endcode %}

아래 명령어를 실행하여 패키지를 설치합니다

```bash
flutter pub get
```

### SDK 초기화하기

iOS SDK와 Android SDK는 초기화 방법이 다릅니다. 아래 가이드를 참고해 주세요.

YOUR\_APP\_ID와 YOUR\_API\_KEY은 핑거푸시 링크 대시보드의 \[모바일 앱] > \[앱 관리] > \[API 키] 에서 확인할 수 있습니다.

#### iOS

1. CocoaPods 의존성 설치 합니다.

**`ios`** 디렉터리로 이동한 뒤, 아래 명령어를 실행합니다.

```bash
pod install
```

2. Run Script 를 추가 합니다.

\[TARGETS 프로젝트] > \[Build Phases] > '+' 클릭 > 'New RunScript Phase' 클릭 후 아래의 스크립트를 추가합니다.

{% code title="fplink script" overflow="wrap" expandable="true" %}

```sh
set -euo pipefail

: "${CODE_SIGN_ENTITLEMENTS:=}"
[ -n "$CODE_SIGN_ENTITLEMENTS" ] || exit 0

ENTITLEMENTS_PATH="${SRCROOT}/${CODE_SIGN_ENTITLEMENTS}"
[ -f "$ENTITLEMENTS_PATH" ] || exit 0

RESOURCES_DIR="${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
OUTPUT_PLIST="$RESOURCES_DIR/AssociatedDomains.plist"

[ -f "$ENTITLEMENTS_PATH" ] || exit 0

mkdir -p "$RESOURCES_DIR"
rm -f "$OUTPUT_PLIST"

/usr/libexec/PlistBuddy -c "Add :applinks array" "$OUTPUT_PLIST"

i=0
added=0
while true; do
  raw=$(/usr/libexec/PlistBuddy -c "Print :com.apple.developer.associated-domains:${i}" "$ENTITLEMENTS_PATH" 2>/dev/null) || break

  if [[ "$raw" == applinks:* ]]; then
    domain="${raw#applinks:}"
    /usr/libexec/PlistBuddy -c "Add :applinks:$added string $domain" "$OUTPUT_PLIST"
    added=$((added+1))
  fi

  i=$((i+1))
done
```

{% endcode %}

4. ios/YOUR\_PROJECT\_NAME/AppDelegate.swift 파일에 아래와 같이 코드를 추가해 주세요.

{% code title="AppDelegate.swift" %}

```swift
import fplink_flutter

@main
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {

    FplinkFlutterPlugin.initialize(appId: "YOUR_APP_ID", apiKey: "YOUR_API_KEY")

    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}
```

{% endcode %}

#### Android

android/app/src/main/java/.../MainApplication.kt 파일에 아래와 같이 코드를 추가해 주세요.

{% code title="MainApplication.kt" %}

```kt
override fun onCreate() {
    super.onCreate()
    FplinkFlutter.initialize(this, "YOUR_APP_ID", "YOUR_API_KEY")
    ...
}
```

{% endcode %}

## 딥링크

딥링크를 설정하면 트래킹 링크가 있는 광고를 클릭한 유저를 원하는 앱의 특정 페이지로 이동시킬 수 있습니다.

{% hint style="danger" %} <mark style="color:$danger;">**알립니다.**</mark>

Flutter SDK 에서 딥링크를 직접 처리할 수 있어 딥링크 기능의 오작동 방지를 위해 플랫폼별로 다음 조치가 반드시 필요합니다.

* Android\
  AndroidManifest.xml 파일에서 `<meta-data android:name="flutter_deeplinking_enabled" android:value="false" />` 로 설정하세요.
* iOS\
  Info.plist 파일에서 `FlutterDeepLinkingEnabled` 키 값을 `NO` 로 설정하세요.
  {% endhint %}

### 딥링크로 앱이 실행되도록 설정하기

유저가 트래킹 링크를 클릭한 후에 앱이 핑거푸시 딥링크로 실행되도록 설정합니다.

#### iOS

1\. 딥링크의 스킴 딥링크 앱 설정이 필요합니다. Xcode에서 \[YOUR\_PROJECT]>\[Info]>\[URL Types]로 이동합니다.

2\. '+'를 클릭한 후에 URL Schemes에 핑거푸시 링크 대시보드에서 입력한 iOS URI 스킴을 입력합니다.

{% hint style="danger" %} <mark style="color:$danger;">**주의하세요**</mark>

<mark style="color:$danger;">**://**</mark> 를 제외한 iOS URL 스킴을 입력해야 합니다.
{% endhint %}

3\. 딥링크의 유니버셜 링크 앱 설정이 필요합니다. Xcode에서 \[YOUR\_PROJECT]>\[Signing & Capabilities]로 이동합니다.

4\. '+ Capability'를 클릭하면 Associated Domains를 추가할 수 있습니다.

5\. 핑거푸시 링크 대시보드의 \[커스텀 도메인] 에서 생성한 도메인 정보를 Associated Domains에 applinks:\[커스텀 도메인] 형태로 추가합니다.

#### Android

1\. 딥링크의 스킴 딥링크 앱 설정이 필요합니다. AndroidManifest.xml에 딥링크를 처리하는 Activity에 Intent Filter를 추가합니다.

추가하는 Intent Filter는 핑거푸시 링크 대시보드에 입력한 안드로이드 URI Scheme를 사용해야 합니다. ://를 제외한 안드로이드 URI 스킴을 입력합니다.

{% code title="AndroidManifest.xml" %}

```xml
<activity ...>
    ...
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />

        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />

        <data android:scheme="YOUR_SCHEME" />
    </intent-filter>
    ...
</activity>
```

{% endcode %}

{% hint style="danger" %} <mark style="color:$danger;">**주의하세요**</mark>

반드시 분리된 <mark style="color:$danger;">\<intent-filter></mark> 태그로 추가하세요. 하나의 <mark style="color:$danger;">\<intent-filter></mark> 태그에 모든 <mark style="color:$danger;">\<data></mark> 태그를 추가하면 딥링크로 앱이 열리지 않을 수 있습니다.
{% endhint %}

2\. 딥링크의 앱 링크(App Links) 앱 설정이 필요합니다. AndroidManifest.xml에 딥링크를 처리하는 Activity 아래 Intent Filter를 추가합니다.

핑거푸시 링크 대시보드의 \[커스텀 도메인] 에서 생성한 도메인 정보를 추가합니다.

{% code title="AndroidManifest.xml" %}

```xml
<activity ...>
    ...
    <intent-filter android:autoVerify="true">
        <action android:name="android.intent.action.VIEW" />

        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        
        <data android:scheme="http" android:host="YOUR_DOMAIN_NAME" />
        <data android:scheme="https" android:host="YOUR_DOMAIN_NAME" />
    </intent-filter>
    ...
</activity>
```

{% endcode %}

{% hint style="danger" %} <mark style="color:$danger;">**주의하세요**</mark>

반드시 분리된 <mark style="color:$danger;">\<intent-filter></mark> 태그로 추가하세요. 하나의 <mark style="color:$danger;">\<intent-filter></mark> 태그에 모든 <mark style="color:$danger;">\<data></mark> 태그를 추가하면 딥링크로 앱이 열리지 않을 수 있습니다.
{% endhint %}

### 앱에서 딥링크 이벤트 수집하기

딥링크 이벤트를 핑거푸시 링크 SDK에 전달해 수집합니다. 딥링크로 앱이 열리면서 호출되는 OS 콜백의 가장 위에 FplinkFlutterPlugin.trackDeeplink 함수를 호출합니다.

전달받은 딥링크 데이터를 활용해 유저를 설정한 목적지도 보냅니다.

#### Flutter

{% code title="main.dart" %}

```dart
_deeplinkSubscription = Fplink.setOnDeeplinkReceived((data) {
    // 여기서 Navigator.push 등으로 화면 이동 수행
});
```

{% endcode %}

#### iOS

ios/YOUR\_PROJECT\_NAME/AppDelegate.swift 파일에 아래와 같이 코드를 추가해 주세요.

{% code title="AppDelegate.swift" %}

```swift
// when app is opened with scheme deeplink
override func application(
    _ app: UIApplication, 
    open url: URL, 
    options: [UIApplication.OpenURLOptionsKey : Any] = [:]
) -> Bool {
    FplinkFlutterPlugin.trackDeeplink(url: url)    
    return super.application(app, open: url, options: options)
}
...
// when app is opened with universal links
override func application(
    _ application: UIApplication, 
    continue userActivity: NSUserActivity, 
    restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
) -> Bool {
    FplinkFlutterPlugin.trackUniversalLink(userActivity: userActivity)
    return super.application(application, continue: userActivity, restorationHandler: restorationHandler)
    }
```

{% endcode %}

SceneDelegate를 사용하는 경우,

ios/YOUR\_PROJECT\_NAME/SceneDelegate.swift 파일에 아래와 같이 코드를 추가해 주세요.

{% code title="SceneDelegate.swift" %}

```swift
override func scene(
    _ scene: UIScene,
    willConnectTo session: UISceneSession,
    options connectionOptions: UIScene.ConnectionOptions
) {
    // Scheme Deeplink
    if let urlContext = connectionOptions.urlContexts.first {
        let url = urlContext.url
        FplinkFlutterPlugin.trackDeeplink(url: url)
    }

    // Universal Link
    if let userActivity = connectionOptions.userActivities.first,
       userActivity.activityType == NSUserActivityTypeBrowsingWeb {
       FplinkFlutterPlugin.trackUniversalLink(userActivity: userActivity)
    }
}
...
// when app is opened with scheme deeplink
override func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
    guard let url = URLContexts.first?.url else { return }
    _ = FplinkFlutterPlugin.trackDeeplink(url: url)
}
...
// when app is opened with universal links
override func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
    _ = FplinkFlutterPlugin.trackUniversalLink(userActivity: userActivity)
}

```

{% endcode %}

#### Android

android/app/src/main/java/.../MainActivity.kt 파일에 아래와 같이 코드를 추가해 주세요.

{% code title="MainActivity.kt" %}

```kotlin
override fun onResume() {
    super.onResume()
    FplinkFlutter.trackDeeplink(intent = intent)
}
...
override fun onNewIntent(intent: Intent?) {
    super.onNewIntent(intent)
    setIntent(intent)
}
```

{% endcode %}

#### 수집한 핑거푸시 링크 딥링크로 유저를 이동시키기&#x20;

핑거푸시 딥링크가 실행되면 [OnDeeplinkReceived](#undefined-1) 콜백에 전달됩니다.

## 디퍼드 딥링크 설정하기

디퍼드 딥링크는 자동으로 [OnDeeplinkReceived](#undefined-1)에 전달되기 때문에 별도의 설정이 필요하지 않습니다.

### 하이브리드 앱 설정하기

웹뷰는 기본적으로 딥링크를 지원하지 않습니다. 따라서 Fplink.click 함수로 SDK가 대신 트래킹 링크의 딥링크를 실행하도록 설정해야 합니다.

Fplink.click 함수는 입력된 주소가 핑거푸시 링크에서 생성한 링크면 True 를 반환합니다. 그리고 주소로 앱을 실행하면 onSuccess 함수를 호출합니다.&#x20;

입력된 주소가 다른 플랫폼의 딥링크가 실행되면 false 로 반환합니다.

{% code title="Flutter" %}

```dart
...
NavigationDelegate(
  onNavigationRequest: (NavigationRequest request) async {
    final String url = request.url;
    
    final bool isHandled = await Fplink.click(
      url,
      onSuccess: () {
        // 성공 콜
      });

     if (isHandled) {
       return NavigationDecision.prevent; // 핑거푸시 딥링크 주소로 웹뷰 로딩을 중단합니다.
     }
     
     return NavigationDecision.navigate; // 일반 링크는 로딩을 허용합니다.
   },
)
...
```

{% endcode %}
