반응형
📝Flutter 라이브러리
Http
- Http
- Flutter에서 가장 기본적으로 많이 사용되는 HTTP 통신 라이브러리입니다. 간단한 GET, POST 요청을 할 때 주로 사용됩니다.
- DIO (채택)
- 복잡한 HTTP 요청이나 응답, 예를 들어 인터셉터, 쿠키 관리, 파일 업로드 및 다운로드 등을 쉽게 처리할 수 있는 강력한 HTTP 클라이언트 라이브러리입니다.
Logging
- Flutter는 프론트이기 때문에 프론트의 경우 따로 로깅을 하지 않는다. 로깅이 필요하면 지원하는 logging 라이브러리를 사용한다.
- https://pub.dev/packages/logging
상태관리
- Provider
- Riverpod (Provider 개선버전) [추천]
- Bloc [추천이라는데 안 써봐서 모름]
- GetX [추천이라는데 안 써봐서 모름]
- MobX
- Redux
- Cubit
그 외 라이브러리
- Freezed
- Freezed에 맞게 코드를 짜고 코드제너레이터를 하면 그 필드에 맞게 생성자나, 직렬화, 역직렬화등에 대한 정보를 만들어줍니다. (보일러플레이트 감소)
- jsonDecode
- String으로 온 데이터를 Json으로 변환시켜준다. (DIO하고 Freezed 같이 사용하면 따로 필요 없어보인다.)
- url_launcher
- launchUrlString을 통해 페이지 이동이 가능하다.
- SharedPreferences
- 사용자 내부 디바이스에 저장 및 활용할 수 있게 도와준다.
- GoRouter
- 라우팅을 도와줍니다.
- permission_handler
- 권한 요청을 간단하게 해주는 것
- camera
- 카메라 사용
- gallery_saver
- 갤러리 사용
📝IDE 설정 & 안드로이드 스튜디오 Flutter 팁
https://mondaymonday2.tistory.com/1007
📝네이밍 컨벤션 & Tip
SnakeCase
- file_system.dart
- folder
- import 'package:angular_components/angular_components.dart' as angular_components;
CamelCase
- class SliderMenu { ... }
- function
- function args
- variable
PascalCase
- typedef Predicate<T> = bool Function(T value);
- @Foo(anArg)
- extension MyFancyList<T> on List<T> { ... }
Tip
- 타입캐스팅
- var map = table.asMap(); 또는 toMap이긴한데 얕은복사냐 깊은복사냐에 따라 다르다고하다 그냥 to로 쓰자 귀찮다
- bool 변수는 긍정이름 선호
- hasData (O)
- isEmpty (X)
- 메소드명
- 행위가 강조되는 경우 downloadData처럼 데이터를 반환하는 경우 get 제거
- breakfastOrder (O)
- getBreakfastOrder (X)
- 메소드 매개변수
- add(element) [O]
- addElement(element) [X]
- 함수 New 타입
- 클래스를 하나 만들지말고 typedef Predicate<E> = bool Function(E element); 이렇게 써라. 너무 남발하면 복잡해지니 자제하면서 알아서 사용
// 좋은 예시
typedef Comparison<T> = int Function(T a, T b);
// 나쁜 예시
typedef int Comparison<T>(T a, T b); // 구식 문법
- 메서드 체이닝
- 체이닝을 위해 return에 this를 반환하는것보다는 매서드 케서케이드(..)를 사용하는게 좋다.
// wrong code
class Person {
String name = '';
int age = 0;
Person setName(String name) {
this.name = name;
return this; // `this`를 반환
}
Person setAge(int age) {
this.age = age;
return this; // `this`를 반환
}
}
void main() {
var person = Person()
.setName('Alice') // 메서드 체이닝
.setAge(30); // 메서드 체이닝
print('Name: ${person.name}, Age: ${person.age}');
}
// right code
class Person {
String name = '';
int age = 0;
void setName(String name) {
this.name = name;
}
void setAge(int age) {
this.age = age;
}
}
void main() {
var person = Person()
..setName('Alice') // 메서드 캐스케이드
..setAge(30); // 메서드 캐스케이드
print('Name: ${person.name}, Age: ${person.age}');
}
- 타입 명시화
- 로컬 변수 타입이 명확하면 생략하는게 좋습니다.
- Dart 대부분 제네릭 타입인자 추론이 가능하지만 정보가 없으면 타입인자 명시 해야합니다.
// 좋은 예시
var desserts = <List<Ingredient>>[];
// 나쁜 예시
List<List<Ingredient>> desserts = <List<Ingredient>>[];
// ─────────────────────────────────────────────────────────────
// 좋은 예시
var playerScores = <String, int>{}; // 명시적으로 타입 인자 지정
final events = StreamController<Event>();
// 나쁜 예시
var playerScores = {}; // 타입 인자 없음
final events = StreamController(); // 타입 인자 없음
- 생성자 생성
// 간단한 방식
Point(this.x, this.y);
- Setter 반환타입 지정하지 않기
// 좋은 예시
set foo(Foo value) { ... }
// 나쁜 예시
void set foo(Foo value) { ... } // 불필요한 반환 타입
- dynamic 타입 금지
- 컴파일 타입체크를 비활성하기 때문에 사용하지 않는 게 좋다
- 함수 매개변수 명시화
- 매개변수 위치에 따라 받는 것보다는 이렇게 명시해서 데이터를 직접 받는게 안전하고 이해가 쉽다.
class ListBox {
final bool scroll;
final bool showScrollbars;
ListBox({this.scroll = false, this.showScrollbars = false});
}
void main() {
// 명명된 매개변수를 사용하여 `ListBox` 인스턴스를 생성
var listBox = ListBox(scroll: true, showScrollbars: true);
}
// 명명된 매개변수를 가진 함수
void createUser({required String name, int age = 18, String? email}) {
print('Name: $name, Age: $age, Email: $email');
}
- == 오버라이딩
- 기본적으로 ==는 참조값 비교하기 때문에 실제값 비교를 위해서는 오버라이딩이 필요하다
https://dart.dev/effective-dart/style
https://dart.dev/effective-dart/usage
https://dart.dev/effective-dart/design
📝Flutter 프로젝트 구조
lib/
├─ model
├─ my_menu
├─ my_menu_model.dart
├─ repository
├─ my_menu
├─ my_menu_repository.dart
├─ view_model
├─ my_menu
├─ my_menu_view_model.dart
├─ screen
├─ my_menu
├─ my_menu_screen.dart
├─ common
├─ enum
├─ exception
├─ logger
├─ util
├─ widget
├─ my_menu
├─ profile.dart
다양한 구조가 있지만 MVVM 구조가 앱개발할 때 가장 적합한 스타일이라고한다. (iOS / AOS에도 적극 채용중) Rivderpod을 선택했고 Riverpod의 경우 MVVM에 맞게 개발되었기 때문에 MVVM 프로젝트 구조가 적합하다.
- model
- 데이터의 모델을 의미한다.
- repository
- 비즈니스 로직이 들어간다.
- view_model
- 화면과 연결하는 부분으로 API통신해서 가져온 데이터를 가공해서 화면에 전달해주는 브릿지 역할을 합니다.
- screen
- 사용자가 보는 화면을 의미합니다. view_model에서는 API통신 후 온 데이터에 대한 가공등이 들어가지만 UI관련 로직은 screen에 들어가게 됩니다.
- common
- 공통으로 처리하는 부분입니다.
- widget
- 화면의 요소를 컴포넌트화 시킨 것입니다.
반응형