StreamProvider는 FutureProvider와 유사하지만 Future가 아닌 Stream을 위한 것입니다.
StreamProvider는 일반적으로 다음과 같은 용도로 사용됩니다:
- Firebase 또는 웹 소켓 수신 중
- 몇 초마다 다른 provider rebuild
Stream은 업데이트를 수신하는 방법을 자연스럽게 노출하기 때문에 StreamProvider를 사용하는 것이 가치가 낮다고 생각할 수 있습니다. 특히 스트림을 수신하는 데는 Flutter의 StreamBuilder도 잘 작동할 것이라고 생각할 수 있지만, 이는 잘못된 생각입니다.
- StreamBuilder 대신 StreamProvider를 사용하면 많은 이점이 있습니다:
- 다른 provider가 ref.watch를 사용하여 스트림을 수신할 수 있도록 허용합니다.
- 로딩 및 오류 케이스가 적절히 처리되도록 보장합니다.
- 생방송 스트림과 일반 스트림을 구분할 필요가 없습니다.
- 스트림이 전송한 최신 값을 캐시하여 이벤트가 전송된 후 리스너가 추가되더라도 리스너가 최신 이벤트에 즉시 액세스할 수 있도록 합니다.
- SteamProvider를 재정의하여 테스트 중에 스트림을 쉽게 모의 테스트할 수 있습니다.
사용 예시: 소켓을 사용한 실시간 채팅
StreamProvider는 다음과 같이 비디오 스트리밍, 날씨 방송 Apis 또는 라이브 채팅과 같은 비동기 데이터 스트림을 처리할 때 사용됩니다:
@riverpod
Stream<List<String>> chat(ChatRef ref) async* {
// 소켓을 사용하여 API에 연결하고 출력을 디코딩합니다.
final socket = await Socket.connect('my-api', 4242);
ref.onDispose(socket.close);
var allMessages = const <String>[];
await for (final message in socket.map(utf8.decode)) {
// 새 메시지가 수신되었습니다. 모든 메시지 목록에 추가해 보겠습니다.
allMessages = [...allMessages, message];
yield allMessages;
}
}
그러면 UI에서 다음과 같이 실시간 스트리밍 채팅을 수신할 수 있습니다:
Widget build(BuildContext context, WidgetRef ref) {
final liveChats = ref.watch(chatProvider);
// FutureProvider와 마찬가지로 로딩/오류 상태를 처리하기 위해 AsyncValue.when을 사용할 수 있습니다.
return liveChats.when(
loading: () => const CircularProgressIndicator(),
error: (error, stackTrace) => Text(error.toString()),
data: (messages) {
// 모든 메시지를 스크롤 가능한 목록 보기로 표시합니다.
return ListView.builder(
// 아래에서 위로 메시지 표시
reverse: true,
itemCount: messages.length,
itemBuilder: (context, index) {
final message = messages[index];
return Text(message);
},
);
},
);
}
'Flutter > Package' 카테고리의 다른 글
Flutter Riverpod All Providers (5-7) - ChangeNotifierProvider (0) | 2023.07.18 |
---|---|
Flutter Riverpod All Providers (5-6) - StateProvider (0) | 2023.07.17 |
Flutter Riverpod All Providers (5-4) - FutureProvider (0) | 2023.07.17 |
Flutter Riverpod All Providers (5-3) - StateNotifierProvider (0) | 2023.07.16 |
Flutter Riverpod All Providers (5-2) - (Async)NotifierProvider (0) | 2023.07.16 |