Event Channel_IOS

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초에 하나씩 받아오는 방법으로 설명하겠다

Swift

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

flutter 코드에서 스타틱으로 채널을 설정해주고 채널의 네임은 AppDelegate.swift에서 선언해준 채널명과 동일하여야 한다.

이벤트 채널에 리스너로 구독을 받아 원하는 상태로 변경해 주면된다.

  static const _eventChannel = EventChannel('random_number_channel');

 _eventChannel.receiveBroadcastStream().listen((event) {
     value.changedNumber(number: event);
    });

마무리

이번 글에서는 간단한 예제로 Event 채널을 설명하고 있지만 다음 글에서는 네이티브에서 직접 푸시를 수신 받아 flutter로 넘겨주는 글을 쓰려고 한다

현재 Android에서는 네이티브 통신의 필요성을 크게 느끼지 못하고 있어서 추후 시간이 될 때 Android 코드도 추가할 예정이다

profile
Flutter Developer

0개의 댓글