Platform Channel 한 번에 이해하기 - IOS(swift) / Android(kotlin)
플랫폼 통신(IOS) - Method Channel
플랫폼 통신(Android) - Method Channel
플랫폼 통신(Android) - Event Channel
이번 글에서는 flutter와 native간의 통신 방식 중 하나인 Event Channel에 대해서 글을 작성하려고 한다.
Flutter Platform Channel이란 네이티브와 통신을 할 수 있도록 도와주는 방식으로 네이티브 고유의 기능에 접근하고자 할 때 사용할 수 있다.
통신 방식에는 Method / Event 2개의 방식이 있다
위 링크는 Method Channel에 대해서 작성한 글임(IOS)
Flutter에서 특정 버튼 또는 시점에 네이티브에 접근하고자 할 때에 Method 채널을 사용할 수 있는데 반대로 네이티브에서 flutter로 특정 기능을 제공하고자 할 때에 Event Channel을 사용한다
Event Channel은 스트림 방식으로 구현하여 리스너를 통해 네이티브로 부터 원하는 기능을 제공받게 된다
Method 채널에 대해서는 작성된 글이 많아 쉽게 사용해 볼 수 있는데, Event 채널을 작성한 글이 많지 않아서 자세히 글을 써보려고 한다
Event 채널을 사용하고자 하는 목적은 IOS 푸시 수신 / 노치 스크롤 터치 이벤트를 받아보고 싶어서 사용하게 되었다
해당 글에서는 간단한 예제로 IOS 네이티브로 부터 랜덤 숫자를 1초에 하나씩 받아오는 방법으로 설명하겠다
IOS > Runner > AppDelegate.swift
먼저 프로젝트에 포함되어 있는 스위프트 파일에서 flutter 컨트롤러/채널/핸들러를 선언해준다
컨트롤러와 채널은 Method 채널의 방식과 똑같다고 보면된다
핸들러는 로직을 넣어주는 객체이며, 생성한 채널을 스트림에 연결하여 스트림안에 핸들러를 넘겨주는 구조로 이벤트 채널이 작동이 된다
let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
let randomNumberChannel = FlutterEventChannel(name: "random_number_channel", binaryMessenger: controller.binaryMessenger)
let randomNumberStreamHandler = RandomNumberStreamHandler()
randomNumberChannel.setStreamHandler(randomNumberStreamHandler)
핸들러 부분의 코드이다 swift코드가 익숙치 않아 코드에 대해서는 설명하지 않을 예정이고, 아래의 핸들러에서 가장 중요한 부분은 onListen()/onCancel() 부분만 이해하고 있으면 된다
onListen()과 onCancel()은 함수명 그대로 리스너 로직과 디스포즈 구현이다
1초에 한 번씩 1-10까지 랜덤 넘버를 하나씩 받아와 스트림에 넘겨주고 있다
class RandomNumberStreamHandler: NSObject, FlutterStreamHandler{
var sink: FlutterEventSink?
var timer: Timer?
func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? {
sink = events
timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(sendNewRandomNumber), userInfo: nil, repeats: true)
return nil
}
@objc func sendNewRandomNumber() {
guard let sink = sink else { return }
let randomNumber = Int.random(in: 1..<10)
sink(randomNumber)
}
func onCancel(withArguments arguments: Any?) -> FlutterError? {
sink = nil
timer?.invalidate()
return nil
}
}
flutter 코드에서 스타틱으로 채널을 설정해주고 채널의 네임은 AppDelegate.swift에서 선언해준 채널명과 동일하여야 한다.
이벤트 채널에 리스너로 구독을 받아 원하는 상태로 변경해 주면된다.
static const _eventChannel = EventChannel('random_number_channel');
_eventChannel.receiveBroadcastStream().listen((event) {
value.changedNumber(number: event);
});
이번 글에서는 간단한 예제로 Event 채널을 설명하고 있지만 다음 글에서는 네이티브에서 직접 푸시를 수신 받아 flutter로 넘겨주는 글을 쓰려고 한다
현재 Android에서는 네이티브 통신의 필요성을 크게 느끼지 못하고 있어서 추후 시간이 될 때 Android 코드도 추가할 예정이다