반응형

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 앱을 확장해 보세요!

반응형

+ Recent posts