플러터(Flutter)와 RxDart를 사용하여 로그인 및 회원가입 기능을 구현하는 방법에 대해 알아보겠습니다.
1. RxDart란?
RxDart는 Dart언어를 위한 반응형 프로그래밍 라이브러리로써, 스트림(Streams)과 관찰자(Observer) 패턴을 사용하여 애플리케이션의 데이터 흐름을 조작하는 데 도움을 줍니다.
2. 플러터(Flutter)에서 RxDart 사용하기
RxDart를 플러터 프로젝트에 추가하려면 pubspec.yaml
파일에 다음 의존성을 추가해야 합니다:
dependencies:
rxdart: ^0.26.0
의존성 추가 후, pub get
명령을 실행하여 의존성을 설치합니다.
3. 로그인 및 회원가입 스트림 생성하기
RxDart의 기능을 최대한 활용하기 위해 로그인 및 회원가입 기능을 스트림으로 구현해보겠습니다.
import 'package:rxdart/rxdart.dart';
class AuthBloc {
final _emailController = BehaviorSubject<String>();
final _passwordController = BehaviorSubject<String>();
// 입력받은 이메일과 비밀번호를 검증하는 기능을 구현할 수 있습니다.
Stream<bool> get isValid =>
CombineLatestStream.combine2(email, password, (e, p) => true);
// 이메일 입력을 받는 스트림
Sink<String> get emailChanged => _emailController.sink;
// 비밀번호 입력을 받는 스트림
Sink<String> get passwordChanged => _passwordController.sink;
// 검증된 이메일을 반환하는 스트림
Stream<String> get email => _emailController.stream.transform(validateEmail);
// 검증된 비밀번호를 반환하는 스트림
Stream<String> get password =>
_passwordController.stream.transform(validatePassword);
// 이메일 대한 검증 로직
final validateEmail = StreamTransformer<String, String>.fromHandlers(
handleData: (email, sink) {
if (email.contains('@')) {
sink.add(email);
} else {
sink.addError('올바른 이메일 형식이 아닙니다');
}
},
);
// 비밀번호에 대한 검증 로직
final validatePassword = StreamTransformer<String, String>.fromHandlers(
handleData: (password, sink) {
if (password.length >= 6) {
sink.add(password);
} else {
sink.addError('비밀번호는 6자 이상이어야 합니다');
}
},
);
// 회원가입 기능 구현
void signUp() {
final email = _emailController.value;
final password = _passwordController.value;
// 회원가입 로직을 여기에 작성합니다.
}
// 로그인 기능 구현
void signIn() {
final email = _emailController.value;
final password = _passwordController.value;
// 로그인 로직을 여기에 작성합니다.
}
// AuthBloc 종료 시에 메모리 누수를 방지하기 위해 dispose 메소드를 추가합니다.
void dispose() {
_emailController.close();
_passwordController.close();
}
}
위 코드에서 AuthBloc
클래스는 이메일과 비밀번호의 변화를 관찰하고, 검증된 값을 내보내는 역할을 합니다. 또한 회원가입 및 로그인 버튼 클릭 시 해당 기능을 수행하는 메소드도 추가되어 있습니다.
4. 로그인 및 회원가입 UI 연동하기
위에서 생성한 AuthBloc
클래스를 사용하여 UI와 로그인 및 회원가입 기능을 연동해보겠습니다. 예시로 로그인 화면과 회원가입 화면을 작성해보겠습니다.
import 'package:flutter/material.dart';
class LoginScreen extends StatelessWidget {
final _bloc = AuthBloc();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('로그인'),
),
body: Container(
padding: EdgeInsets.all(16.0),
child: Column(
children: [
StreamBuilder<String>(
stream: _bloc.email,
builder: (context, snapshot) {
return TextField(
onChanged: _bloc.emailChanged.add,
decoration: InputDecoration(
labelText: '이메일',
errorText: snapshot.error,
),
);
},
),
StreamBuilder<String>(
stream: _bloc.password,
builder: (context, snapshot) {
return TextField(
onChanged: _bloc.passwordChanged.add,
obscureText: true,
decoration: InputDecoration(
labelText: '비밀번호',
errorText: snapshot.error,
),
);
},
),
SizedBox(height: 16.0),
StreamBuilder<bool>(
stream: _bloc.isValid,
builder: (context, snapshot) {
return RaisedButton(
onPressed: snapshot.hasError || !snapshot.hasData
? null
: _bloc.signIn,
child: Text('로그인'),
);
},
),
SizedBox(height: 16.0),
RaisedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SignUpScreen()),
);
},
child: Text('회원가입'),
),
],
),
),
);
}
@override
void dispose() {
_bloc.dispose();
super.dispose();
}
}
class SignUpScreen extends StatelessWidget {
final _bloc = AuthBloc();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('회원가입'),
),
body: Container(
padding: EdgeInsets.all(16.0),
child: Column(
children: [
StreamBuilder<String>(
stream: _bloc.email,
builder: (context, snapshot) {
return TextField(
onChanged: _bloc.emailChanged.add,
decoration: InputDecoration(
labelText: '이메일',
errorText: snapshot.error,
),
);
},
),
StreamBuilder<String>(
stream: _bloc.password,
builder: (context, snapshot) {
return TextField(
onChanged: _bloc.passwordChanged.add,
obscureText: true,
decoration: InputDecoration(
labelText: '비밀번호',
errorText: snapshot.error,
),
);
},
),
SizedBox(height: 16.0),
StreamBuilder<bool>(
stream: _bloc.isValid,
builder: (context, snapshot) {
return RaisedButton(
onPressed: snapshot.hasError || !snapshot.hasData
? null
: _bloc.signUp,
child: Text('회원가입'),
);
},
),
],
),
),
);
}
@override
void dispose() {
_bloc.dispose();
super.dispose();
}
}
위 코드에서는 StreamBuilder
위젯을 사용하여 이메일과 비밀번호 입력값의 변화를 관찰하고, 에러 메시지를 출력하는 로직이 구현되어 있습니다. 또한 로그인 및 회원가입 버튼을 눌렀을 때 AuthBloc
클래스의 메소드가 실행되도록 설정되어 있습니다.
5. 결론
이제 플러터(Flutter)와 RxDart를 사용하여 로그인 및 회원가입 기능을 구현하는 방법을 알아보았습니다. RxDart를 사용하면 반응형 프로그래밍의 장점을 활용하여 애플리케이션의 데이터 흐름을 더욱 효율적으로 관리할 수 있습니다.