일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- Got
- rao
- study book
- bloc
- PCA
- BFS
- Image Processing
- DART
- system hacking
- Kaggle
- Computer Architecture
- MATLAB
- pytorch
- C++
- Stream
- FastAPI
- Flutter
- BOF
- 백준
- 파이토치 트랜스포머를 활용한 자연어 처리와 컴퓨터비전 심층학습
- BAEKJOON
- Algorithm
- ARM
- ML
- MDP
- llm을 활용 단어장 앱 개발일지
- fastapi를 사용한 파이썬 웹 개발
- 영상처리
- Dreamhack
- Widget
- Today
- Total
Bull
[Dev] LLM을 활용 단어장 앱 개발일지 002: key 기기 보관 본문
심도있게 하고 차근차근 조금씩 코드를 해석하기 위해 분량이 적다.
SharedPreferences 패키지로 api key 저장하기
SharedPreferences 패키지는 비동기적으로 모바일 기기와 통신하여 데이터를 파일로 저장해준다. 만약 서비스를 회원 등록없이 간단한 데이터만을 사용하여 기록 저장을 하고 싶다면 SharedPreferences를 사용할 수 있다.
난 우선 api key를 통해 내 백엔드 서버를 배포하고 api 통신을 하도록 생각을 하고 있다. 그래서 회원등록이 아닌 개인 api key를 사용하여 서버에 접근할 수 있도록 모바일 기기에 데이터를 저장할 것이다. 그래서 SharedPreferences를 사용하기로 결정했다.
순서는 간단하다.
1. 라우팅 설정으로 api key 입력 페이지로 들어갈 때 apiKey
prefs 값을 확인하고 이미 설정되어 있다면 /chat
으로, 설정되어 있지 않다면 /
(api key 입력 창)으로 들어가게 된다.
2. api key 입력 페이지에서 버튼을 누르면 apiKey
prefs 값을 등록하고 /chat으로 들어간다.
// filename: api_key_input_page.dart
// class ApiKeyInputPage extends StatefulWidget
// ...
Future<void> _registerApiKey() async =>
SharedPreferences.getInstance().then((prefs) {
prefs.setString('apiKey', _apiKeycontroller.text);
});
// ...
basicButton(
text: '제출',
onPressed: () async {
await _registerApiKey();
context.go('/chat');
},
)
여기서 간지를 위해 메소드를 한 줄로 구현했다.
prefs는 비동기로 핸드폰 기기와 통신하기 때문에 데이터를 가져올 때는 비동기로 하는 것이 좋지만 안정성을 위해 저장하는 것도 비동기로 해주었다. setString
을 통해 문자열 프로퍼티를 저장하였다.
한줄 메소드를 람다식을 안 쓰면 다음과 같다.
Future<void> _registerApiKey() async =>
await SharedPreferences.getInstance().then((prefs) {
prefs.setString('apiKey', _apiKeycontroller.text);
});
// ↓↓↓↓
Future<void> _registerApiKey() async {
final prefs = await SharedPreferences.getInstance();
await prefs.setString('apiKey', _apiKeycontroller.text);
}
라우팅 설정
// filename: router.dart
import 'package:go_router/go_router.dart';
import '../pages/api_key_input_page.dart';
import '../pages/chatting_page.dart';
import '../pages/home_page.dart';
import 'package:shared_preferences/shared_preferences.dart';
Future<bool> hasApiKey() async => await SharedPreferences.getInstance()
.then((prefs) => (prefs.getString('apiKey') != null));
final router = GoRouter(
initialLocation: '/',
routes: [
GoRoute(
path: '/',
builder: (context, state) => const ApiKeyInputPage(),
),
GoRoute(
path: '/chat',
builder: (context, state) => ChattingPage(),
),
GoRoute(
path: '/home',
builder: (context, state) => const HomePage(),
),
],
redirect: (context, state) async {
final currentPath = state.uri.path;
final hasKey = await hasApiKey();
switch (currentPath) {
case '/':
return (hasKey) ? '/chat' : '/';
default:
return null;
}
},
);
패키지는 GoRouter
를 사용하였다. 이 파일에서 페이지를 관리할 수 있다. 여기서 GoRouter
의 routes
프로퍼티 만으로도 페이지의 라우팅 설정을 할 수 있지만 나는 라우터 관리창에서 분기문을 구현하고 싶었다. 이 때 redirect
프로퍼티를 사용하면 된다.
GoRouter redirect는 페이지가 네비게이션 되기전에 호출 되는데, 가장 최상단의 GoRouter
와 GoRoute
두 객체 모두 redirect
프로퍼티를 가지고 있다. GoRouter
는 탑 레벨인 가장 최고 상단에 위치하는 객체이기 때문에 GoRouter
의 계층에서 네비게이션될 때 redirect
프로퍼티에 등록된 콜백을 호출한다. switch
문을 보면 알겠지만 특별한 페이지에서 리다이렉션을 원하지 않아도 같은 계층에서 네비게이션될 때 호출되므로 특정 경로에서는 null
을 반환시켜주어야 한다.
나는 '/'(api key 입력 창)에서 hasKey
메소드를 통해 apiKey
prefs 값을 확인한 후 리다이렉션시킨다.
구현은 완성했지만 apiKey
의 값을 다시 null
로 만들어 api key 입력창으로 가고 싶다면 prefs의 remove
메소드를 통해서 다시 null
으로 초기화할 수 있다.
redirect
콜백에 다음과 같은 코드를 추가하면 '/'로 가지않고 '/chat'으로 리다이렉션 되는 것을 확인할 수 있다.
print('currentPath: $currentPath');
print('hasKey: $hasKey');
'일상 > 개발일지' 카테고리의 다른 글
[Dev] LLM을 활용 단어장 앱 개발일지 006: 단어장 UI 변경 (0) | 2024.08.27 |
---|---|
[Dev] LLM을 활용 단어장 앱 개발일지 005: CRUD - 단어 DB 읽어서 표시하기 (0) | 2024.08.20 |
[Dev] LLM을 활용 단어장 앱 개발일지 004: Bloc 상태 관리(대화 내용) (0) | 2024.08.18 |
[Dev] LLM을 활용 단어장 앱 개발일지 003: Fast API로 Langchain 설정하기 (0) | 2024.08.17 |
[Dev] LLM을 활용 단어장 앱 개발 일지 001: UI 구성 (0) | 2024.08.14 |