Flutter - Native Code 추가 방법

반응형

Flutter에서 네이티브 코드를 추가하는 방법은 플랫폼별(Android, iOS)로 나뉘며, 보통 플러그인을 직접 개발하거나, 기존 네이티브 기능을 호출하는 방식으로 진행됩니다.

1. Method Channel을 사용하여 네이티브 코드 호출

Flutter에서 네이티브(Android/iOS) 기능을 호출하는 가장 일반적인 방법은 Method Channel을 사용하는 것입니다.

1.1 Method Channel 기본 개념

  • Flutter에서 MethodChannel을 통해 Dart와 네이티브(Android, iOS) 코드 간에 메시지를 주고받습니다.
  • Dart에서 특정 메서드를 호출하면, 네이티브 코드에서 해당 메서드를 처리한 후 결과를 반환합니다.

2. Android 네이티브 코드 추가 (Kotlin)

2.1 Method Channel 설정

먼저, Flutter 프로젝트에서 MethodChannel을 선언합니다.

2.2 Dart 코드 작성

lib/main.dart에서 네이티브 코드를 호출하는 메서드를 작성합니다.

import 'package:flutter/services.dart';

class NativeHelper {
  static const MethodChannel _channel = MethodChannel('samples.flutter.dev/native');

  static Future<String?> getNativeMessage() async {
    try {
      final String? result = await _channel.invokeMethod('getMessage');
      return result;
    } on PlatformException catch (e) {
      return "Failed to get message: '${e.message}'.";
    }
  }
}

2.3 Android 네이티브 코드 추가

  1. android/app/src/main/kotlin/com/example/app/MainActivity.kt 파일을 열고 다음과 같이 수정합니다.
package com.example.app

import android.os.Bundle
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel

class MainActivity : FlutterActivity() {
    private val CHANNEL = "samples.flutter.dev/native"

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
            if (call.method == "getMessage") {
                result.success("Hello from Android Native!")
            } else {
                result.notImplemented()
            }
        }
    }
}

2.4 실행 및 확인

이제 NativeHelper.getNativeMessage()를 호출하면 Android 네이티브 코드에서 응답을 받을 수 있습니다.

void main() async {
  String? message = await NativeHelper.getNativeMessage();
  print(message); // "Hello from Android Native!" 출력
}

3. iOS 네이티브 코드 추가 (Swift)

Flutter는 iOS에서도 MethodChannel을 통해 네이티브 코드를 호출할 수 있습니다.

3.1 iOS 네이티브 코드 추가

  1. ios/Runner/AppDelegate.swift 파일을 열고 다음 코드를 추가합니다.
import UIKit
import Flutter

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    let controller: FlutterViewController = window?.rootViewController as! FlutterViewController
    let channel = FlutterMethodChannel(name: "samples.flutter.dev/native", binaryMessenger: controller.binaryMessenger)
    
    channel.setMethodCallHandler { (call: FlutterMethodCall, result: @escaping FlutterResult) in
      if call.method == "getMessage" {
        result("Hello from iOS Native!")
      } else {
        result(FlutterMethodNotImplemented)
      }
    }

    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}

3.2 실행 및 확인

Flutter 앱을 iOS에서 실행하면 "Hello from iOS Native!"가 출력됩니다.


4. Flutter에서 네이티브 코드 실행

위에서 작성한 NativeHelper.getNativeMessage()를 Flutter 위젯에서 실행하면 네이티브 코드가 호출됩니다.

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String _message = "Waiting for native response...";

  void _getMessageFromNative() async {
    String? message = await NativeHelper.getNativeMessage();
    setState(() {
      _message = message ?? "Error retrieving message";
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text("Flutter Native Code")),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text(_message),
              SizedBox(height: 20),
              ElevatedButton(
                onPressed: _getMessageFromNative,
                child: Text("Get Native Message"),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

5. 네이티브 코드 활용 예시

위의 예제는 단순히 문자열을 반환하는 기능이지만, 실제 앱에서는 다음과 같은 네이티브 기능을 추가할 수 있습니다.

네이티브 기능 추가 예시

  • 카메라 및 갤러리 접근 (Android & iOS)
  • Bluetooth 및 NFC 연동
  • 파일 저장 및 읽기 (외부 저장소)
  • 네이티브 API 호출 (Android Jetpack, iOS CoreML 등)
  • 백그라운드 서비스 실행
  • 배터리 정보 및 센서 데이터 가져오기

6. 네이티브 패키지를 직접 개발하는 경우

Flutter에서 네이티브 기능을 자주 사용할 경우, 플러그인을 직접 개발하여 패키지를 만드는 것도 가능합니다.

  1. 새로운 플러그인 생성
    flutter create --template=plugin my_plugin
    
  2. my_plugin 디렉터리 내에서 Android 및 iOS의 네이티브 코드를 수정하여 원하는 기능을 구현한 후, pub.dev에 배포할 수도 있습니다.

7. 결론

  • Flutter에서 네이티브 코드를 추가하려면 MethodChannel을 활용하여 Android/iOS 네이티브 코드를 실행할 수 있습니다.
  • Android에서는 MethodChannel을 FlutterEngine에 연결하여 Kotlin/Java 코드를 실행하고, iOS에서는 FlutterMethodChannel을 사용하여 Swift/Objective-C 코드를 실행합니다.
  • 네이티브 기능을 자주 사용해야 한다면 플러그인을 직접 개발하는 것도 좋은 방법입니다.

이제 원하는 네이티브 기능을 추가하여 Flutter 앱을 확장해 보세요!

반응형