네트워크 환경 체크
| topics | 500-모바일개발 501 Flutter 0_SubTopics/504 네트워킹 |
| types | 레퍼런스 실습 |
| tags | #flutter #network #connectivity |
| references | www.youtube.com/watch pub.dev/packages/connectivity_plus |
네트워크 환경 체크
Flutter 앱에서 네트워크 연결 상태를 체크하는 방법이다.
Why 네트워크 체크
오프라인에서도 앱이 동작해야 하거나, 네트워크 상태에 따라 다른 UI를 보여줘야 할 때 필요하다.
- WiFi, 모바일 데이터, 연결 없음 상태 감지
- 네트워크 끊김 시 사용자에게 알림
- 오프라인 모드 전환
설치
# <span id="pubspecyaml"></span>pubspec.yaml
dependencies:
connectivity_plus: ^5.0.2
flutter pub get
기본 사용법
현재 연결 상태 확인
import 'package:connectivity_plus/connectivity_plus.dart';
Future<void> checkConnectivity() async {
final result = await Connectivity().checkConnectivity();
switch (result) {
case ConnectivityResult.wifi:
print('WiFi 연결됨');
break;
case ConnectivityResult.mobile:
print('모바일 데이터 연결됨');
break;
case ConnectivityResult.ethernet:
print('이더넷 연결됨');
break;
case ConnectivityResult.none:
print('연결 없음');
break;
default:
print('알 수 없는 연결 상태');
}
}
실시간 연결 상태 감지 (Stream)
class NetworkService {
final Connectivity _connectivity = Connectivity();
StreamSubscription<ConnectivityResult>? _subscription;
void startListening(void Function(ConnectivityResult) onChanged) {
_subscription = _connectivity.onConnectivityChanged.listen(onChanged);
}
void stopListening() {
_subscription?.cancel();
}
}
왜 Stream을 쓰냐면: 네트워크 상태는 언제든 바뀔 수 있다. 앱이 실행 중일 때 WiFi가 끊기거나 모바일 데이터로 전환될 수 있기 때문에 지속적으로 감시해야 한다.
Riverpod 연동
// network_provider.dart
@riverpod
Stream<ConnectivityResult> connectivity(ConnectivityRef ref) {
return Connectivity().onConnectivityChanged;
}
@riverpod
class NetworkStatus extends _$NetworkStatus {
@override
bool build() {
// 네트워크 상태 변화 감지
ref.listen(connectivityProvider, (prev, next) {
next.whenData((result) {
state = result != ConnectivityResult.none;
});
});
return true; // 초기값: 연결됨
}
}
UI에서 사용
class HomeScreen extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final isConnected = ref.watch(networkStatusProvider);
return Scaffold(
appBar: AppBar(
title: Text('홈'),
actions: [
if (!isConnected)
Icon(Icons.wifi_off, color: Colors.red),
],
),
body: isConnected
? MainContent()
: OfflineMessage(),
);
}
}
실제 인터넷 연결 확인
주의:
connectivity_plus는 네트워크 인터페이스 상태만 확인한다. WiFi에 연결되어 있어도 실제 인터넷이 안 될 수 있다.
실제 인터넷 연결을 확인하려면:
import 'dart:io';
Future<bool> hasInternetConnection() async {
try {
final result = await InternetAddress.lookup('google.com');
return result.isNotEmpty && result[0].rawAddress.isNotEmpty;
} on SocketException catch (_) {
return false;
}
}
또는 internet_connection_checker 패키지 사용:
dependencies:
internet_connection_checker: ^1.0.0+1
import 'package:internet_connection_checker/internet_connection_checker.dart';
final bool isConnected = await InternetConnectionChecker().hasConnection;
오프라인 배너 위젯
class OfflineBanner extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final isConnected = ref.watch(networkStatusProvider);
if (isConnected) return SizedBox.shrink();
return MaterialBanner(
content: Text('인터넷 연결이 없습니다'),
leading: Icon(Icons.wifi_off),
backgroundColor: Colors.orange,
actions: [
TextButton(
onPressed: () async {
// 재시도 로직
},
child: Text('재시도'),
),
],
);
}
}
관련 문서
- riverpod read listen - Riverpod 상태 관리
- AsyncValue vs AsyncData - Stream 데이터 처리