월 24,200원
5개월 할부 시다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결Flutter 중급 1편 - 클린 아키텍처
type 에러
안녕하세요 선생님! 다름이 아니라 테스트 코드 작성중에result 를 Success로 캐스팅 하여 테스트 코드 실행 하였는데 터미널과 같은 에러가 발생하는데 무엇때문에에러가 뜨는지 모르겠어요 ㅠㅠ운영 관련 문의는 1:1 문의하기를 이용해주세요.
- 미해결Flutter 중급 1편 - 클린 아키텍처
안녕하세요 선생님 아키텍쳐 관련해서 질문드릴것이있습니다.
일단 선생님의 강의를 듣고 제 생각을 정의해보자면데이터레이어(데이터소스, 레퍼지토리(구현))도메인레이어(레퍼지토리(추상), 모델, 유스케이스)프레젠트레이어(뷰 모델, 뷰)레퍼지토리는 기본적으로 외부데이터와의 소통을 위한 통로라고 이해했습니다그렇기 때문에도메인레이어에서 레퍼지토리를 추상화하고데이터레이어에서 이를 구현하는 방식으로 사용되고이 레퍼지토리를 유스케이스에서 도메인레이어의 모델과, 레퍼지토리를 이용해우리 도메인의 입맛에 맞는 데이터형식과 로직을 작성하지요이런 상황속에서 몇가지 의문이 들었습니다 -첫번째질문!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!-만약 외부데이터와 관련이 없는 온리 client 내부적으로만 필요한 상태를 관리해야하는 로직이 필요하다.그렇다면도메인 레이어에 필요한 모델을 작성하고레포지토리없는 유스케이스를 만들면외부데이터와 관련이 없는 상태를 관리할수있지 않을까?=> 외부데이터와 관련없는 데이터 관리가 필요할경우레포지토리가 없는 유스케이스에대한 생각이 궁금합니다!! (레포지토리가 필요없는 유스케이스의 경우쉽게 생각하면 viewModel에서 작성하면 되는 로직 아니야?라고 생각할수있는데, 만약해당 데이터 타입과 로직이 꽤많은 화면에서 공통적으로사용되고있다면 모든 뷰에 대응하는 모든 뷰모델에서같은 로직을 계속해서 반복하게될텐데비효율적일것같아서레포지토리 없는 유스케이스라는 것을 생각하게되었습니다.) -두번째질문!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!-비지니스로직은 유스케이스에UI로직은 뷰모델에 작성한다고해주셨는데비지니스 로직과 UI로직을 나누는 기준이 무엇인지 궁금합니다.어떤걸 유스케이스에 넣고어떤걸 뷰모델에 넣어야하는지에 대한혼란이 있을때가 있어서요!! -세번째질문!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!-노트관련강의30번째 강의의 두번째화면 UI작성 28분쯤해당 색깔을 선택할때 배경색이 바뀌는 로직이뷰에서 로직이 선언되어있는데,뷰모델에서 해당 로직을 선언하지 않은 이유가 궁금합니다! 선생님의 강의 정말 잘 듣고있고매번 너무 감사드립니다ㅜㅜ질문 세가지 드렸는데,글이 길지만 세가지 질문에 대한답변 주시면 정말 감사하겠습니다ㅜㅜ
- 미해결Flutter 중급 1편 - 클린 아키텍처
UI Event의 리턴값을 이용하고 싶습니다
안녕하세요, 좋은 강의 잘 듣고 있습니다.이벤트 컨트롤러를 이용하여 스낵바 이벤트를 발생시키는 부분에서 질문이 있습니다.스낵바 대신 alertDialog를 사용하려 하는데, alert사용자가 선택한 값을 받아오려면 어떻게 하면 될까요?result 값에 따라 분기를 태우고 싶은데, showDialog 이벤트를 사용하는 곳이 많아 showDialog 함수 내에서 분기를 태우긴 찝찝합니다.event.when( showDialog: () async { dynamic result = await showDialog( context: context, barrierDismissible: false, // user must tap button! builder: _buildPopup, ); // 여기에서 if (result==~) 하기엔 범용성이 적다 return result; },
- 미해결Flutter 중급 1편 - 클린 아키텍처
의존성 주입 질문있습니다.
안녕하세요~ 덕분에 클린 아키텍쳐 구조 잘 공부했습니다.혹시 의존성 주입부분에서 질문이 있습니다.제가 개인적으로 연습을 하면서 클린 아키텍쳐를 적용하고 있습니다./di/provider_setup.dart 에서 한번에 의존성 주입List<ChangeNotifierProvider> getProviders() { final dio = Dio(); SongRepository repository = SongRepository(dio); UseCases useCases = UseCases( getSearchSong: GetSearchSongUseCase(repository: repository), getSearchSinger: GetSearchSingerUseCase(repository: repository), getRecentlySongsList: GetRecentlySongsListUseCase(repository:repository), ); SearchViewModel searchViewModel = SearchViewModel(useCases: useCases); HomeViewModel homeViewModel = HomeViewModel(useCases: useCases); return [ ChangeNotifierProvider(create: (_) => searchViewModel), ChangeNotifierProvider(create: (_) => homeViewModel), ]; }main 에서 주입void main() { // provider 호출 final providers = getProviders(); runApp( MultiProvider( providers: providers, child: const MyApp(), ), ); }context.watch<SearchViewModel>(); 은 잘 작동해서 뷰에 출력을 잘 하고있습니다.class _SearchScreenState extends State<SearchScreen> { @override Widget build(BuildContext context) { final searchViewModel = context.watch<SearchViewModel>(); final state = searchViewModel.state; ... }context.watch<HomeViewModel>();은 에러가 발생합니다.class _Body extends StatelessWidget { const _Body({Key? key}) : super(key: key); @override Widget build(BuildContext context) { final homeViewModel = context.watch<HomeViewModel>(); final state = homeViewModel.state; ... }에러내용======== Exception caught by widgets library ======================================================= The following ProviderNotFoundException was thrown building _Body(dirty): Error: Could not find the correct Provider<HomeViewModel> above this _Body Widget This happens because you used a `BuildContext` that does not include the provider of your choice. There are a few common scenarios: - You added a new provider in your `main.dart` and performed a hot-reload. To fix, perform a hot-restart. - The provider you are trying to read is in a different route. Providers are "scoped". So if you insert of provider inside a route, then other routes will not be able to access that provider. - You used a `BuildContext` that is an ancestor of the provider you are trying to read. Make sure that _Body is under your MultiProvider/Provider<HomeViewModel>. This usually happens when you are creating a provider and trying to read it immediately. For example, instead of: ``` Widget build(BuildContext context) { return Provider<Example>( create: (_) => Example(), // Will throw a ProviderNotFoundError, because `context` is associated // to the widget that is the parent of `Provider<Example>` child: Text(context.watch<Example>().toString()), ); } ``` consider using `builder` like so: ``` Widget build(BuildContext context) { return Provider<Example>( create: (_) => Example(), // we use `builder` to obtain a new `BuildContext` that has access to the provider builder: (context, child) { // No longer throws return Text(context.watch<Example>().toString()); } ); } ``` If none of these solutions work, consider asking for help on StackOverflow: https://stackoverflow.com/questions/tagged/flutter The relevant error-causing widget was: When the exception was thrown, this was the stack: #0 Provider._inheritedElementOf (package:provider/src/provider.dart:343:7) #1 Provider.of (package:provider/src/provider.dart:293:30) #2 WatchContext.watch (package:provider/src/provider.dart:693:21) #3 _Body.build (package:what_do_you_want_to_sing/presentation/home/home_screen.dart:79:35) #4 StatelessElement.build (package:flutter/src/widgets/framework.dart:4949:49) #5 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4878:15) #6 Element.rebuild (package:flutter/src/widgets/framework.dart:4604:5) #7 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2667:19) #8 WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:882:21) #9 RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:378:5) #10 SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1175:15) #11 SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1104:9) #12 SchedulerBinding.scheduleWarmUpFrame.<anonymous closure> (package:flutter/src/scheduler/binding.dart:881:7) (elided 4 frames from class _RawReceivePortImpl, class _Timer, and dart:async-patch)저번에 이런 에러가 발생했을때, 의존성 주입이 안된 상태에서 context.watch() 를 해서 오류가 나 의존성을 추가해 해결했습니다.하지만 이번에는 잘모르겠습니다. 의존성도 잘 주입되어서 view 단에서 잘 호출 하고 있는거 같은데.. 어떻게 해결해야할까요?
- 미해결Flutter 중급 1편 - 클린 아키텍처
dart factory에 대하여 질문드립니다.
안녕하세요!! 선생님 강의에서 Result클래스 관련해서질문드립니다.일단factory Result.success(T data)= Success;factory.error(String message) = Error;freezed를 사용한 하위클래스 반환이라는 것은 알겠습니다 혹시 freezed를 사용하지 않는다라고했을때 아래 처럼 사용하면 똑같은 기능이 되는걸까요?
- 미해결Flutter 중급 1편 - 클린 아키텍처
List<List<Photo>>로 통일하지 않은이유
안녕하세요 선생님!! 14강좌 클린아키텍처 강의를 듣다가 궁금한점이 생겨 질문드립니다!pixabay_api.dart에서fetch함수는Futurue<Iterable> 타입을 반환하는데, phto_api_repository.dart 파일의 abstract 클래스의 fetch와이를 오버라이드하는PhotoApiRepositoryImpl클래스의 fetch는 Future<List<photo>>타입을 반환하고 있습니다.같은 fetch함수인데왜 pixabay_api.dart의fetch함수는 Future<List<photo>>타입을 반환시키지않고 Future<Iterable> 타입을 반환시킨 이유가 궁금합니다!!!
- 미해결Flutter 중급 1편 - 클린 아키텍처
freezed사용하지 않고 Result 분기처리
안녕하세요!! 선생님 다름이 아니라에러처리강의에서13분32초쯤에 아래처럼 freezed를 사용하지 않고 작성하시려다가freezed를 사용하는 방법으로 바꾸셨는데요!!!혹시 freezed를 사용하지 않고원래 하시려던 result is Success 조건문으로처리하시려던 코드에 대해 알려주실수 있으실까요?freezed사용하지않고result is Success 조건문으로도 처리해보려고했는데,한참을 수정하고 고민해봐도 계속 에러가 나서요ㅜㅜ
- 미해결Flutter 중급 1편 - 클린 아키텍처
전역 변수만을 갖고 있는 클래스 위치
안녕하세요!아키텍쳐를 실무에 도입하다 궁금증이 생겨 질문드려요.클래스 중에 전역 변수만을 저장하는 클래스가 있습니다.앱을 켰을 때만 전역 변수에 데이터를 저장하고, 앱을 끄면 데이터를 날리는게 목적인데요. 이 클래스의 레이어가 어느 위치인지 잘 모르겠어요 ㅠㅠ 일단은 usecase 처럼 viewModel에서만 접근할 수 있는 위치다 라고 생각했는데, 다시 생각해보니 어떤 데이터를 메모리에 저장하고 있는거니 db 처럼 data layer(datasource) 에 있어야 하나 싶습니다.이런 클래스는 어떻게 다루는게 좋을까요?
- 미해결Flutter 중급 1편 - 클린 아키텍처
g.dart 파일이 생성이 안됩니다.
import 'package:json_annotation/json_annotation.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; part 'note.freezed.dart'; part 'note.g.dart'; @freezed class Note with _$Note { factory Note({ required String title, required String content, required int color, required int timestamp, int? id, }) = _Note; factory Note.formJson(Map<String, dynamic> json) => _$NoteFromJon(json); }g.dart 파일이 생성이 안됩니다.flutter pub run build_runner buildflutter pub run build_runner cleanflutter pub run build_runner build --delete-conflicting-outputs이거 해 보았는데 안됩니다.provider: ^6.0.5 sqflite: ^2.2.3 json_annotation: ^4.7.0 freezed_annotation: ^2.2.0flutter_lints: ^2.0.1 json_serializable: ^6.5.4 freezed: ^2.3.2 build_runner: ^2.3.3처음엔 강의 대로 버전 맞춰서 했는데 안되서 최신으로 했는데 그래도 안됩니다~도와 주십시요~ 강의를 시작도 못하고 있습니다~ ㅜㅜ
- 미해결Flutter 중급 1편 - 클린 아키텍처
eventStream 중지에 대해
ViewModel을 하나만 생성하고 재활용할 때,eventController는 하나인데 listen하고 있는 화면은 계속 생성되고 메모리에 남아있어서저장을 한 번 할때마다 이벤트가 여러 곳에 날라가는 것 같습니다.해결 방법으로는 화면이 dispose 되면 eventController를 cancel 해주거나,ViewModel을 계속 생성하거나 (eventController가 계속 생성되고 전에 것들은 메모리에 남아있어서 좋은 방법은 아닌 것 같습니다.)unMounted 일 때 return; 해버리면 될 것 같습니다.
- 미해결Flutter 중급 1편 - 클린 아키텍처
viewModel이 생성되자마자 비동기 함수를 실행시키는 방법에 대해
안녕하세요.강사님 덕에 클린 아키텍처와 조금씩 가까워지고 있는 수강생입니다. 너무 많이 여쭤봐서 죄송하지만 제 힘으로는 좋은 답을 얻을 수가 없이 질문 드립니다. 뷰 모델이 생성되자마자 데이터를 인터넷 등에서 비동기로 가지고 와야 할 때 고민이 생깁니다.뷰 모델에서 async 함수를 만들어 뷰 모델 생성자에 넣으면, 생성자에서는 await가 안되기 때문에 즉시 데이터를 가져오지 못하고,뷰 모델이 생성되기 전에, navigator.push를 통해 뷰 모델을 계속 생성하여 생성자 주입으로 넣어주면, async 함수를 또다른 뷰모델에서 사용해야 한다는 문제?가 있지 않나 싶습니다.A에서 B로 이동하는 화면에서 B의 데이터를 A의 뷰모델에서 전달해주는 것이 옳바른가 하는 의문입니다.답은 없지만 강사님의 의견을 듣고 싶습니다.감사합니다.
- 미해결Flutter 중급 1편 - 클린 아키텍처
DI 설정
provider_setup 파일과 MultiProvider사용으로 앱 전역적으로 프로바이더를 사용할 수 있게하셨는데이렇게 되면 MyApp아래 모든 파일에서 같은 provider를 공유하고 있는데 이런 방식보단 해당 provider를 사용하게 될 위젯들의 상위 context에서만 선언을 해주는 것이 좋지 않나요? 메인 바로 아래 선언해주는 방식이 실제 앱실행시 계속해서 메모리를 잡아먹는 부담같은 건 없나요??
- 미해결Flutter 중급 1편 - 클린 아키텍처
Stream result 질문
안녕하세요 선생님. 날씨가 많이 쌀살한데, 건강 관리는 잘 하고 계시는지요 ?다름이 아니라 선생님 강의를 보고 제가 하는 프로젝트에 적용해보고 있는데 궁금증이 생겨 질문드립니다.첨부한 사진을 보시면 Future가 아닌 Stream으로 데이터를 처리하고 있는데 Result 를 통해 Usecase 영역에서 .when을 통해 결과 값이 success 일 때, error 일 때 분기 처리를 해주고 싶은데 Stream일 경우 Result를 어떻게 처리를 해주어야 하나요 ? 마지막 사진의 result.when 에 접근이 되지 않아 방법이 떠오르지 않습니다. Stream 을 첫 데이터 수신 이후 5초 주기로 수신하고자 하는데, 첫 번째 사진과 같이 함수를 작성하니 첫 데이터 호출 부터 5초가 지연이 됩니다. 첫 데이터 수신은 1초, 그 후 5초로 변경하고자 하는데 어떤 방법을 사용해야 하나요 ? 긴 글 읽어주셔서 감사합니다.
- 미해결Flutter 중급 1편 - 클린 아키텍처
레포지토리의 메서드와 유스케이스의 개수
처음 메모 앱을 만든다고 생각을 할 때,우선 모델을 만들고 그 모델을 가지고 앱에서 동작할 것으로 예상되는 행위들을 레포지토리로 추상화하고 그것을 실제로 구현하여 유스케이스로 사용하는 흐름을 잘 이해하게 된 것 같습니다.이렇게 작성하게 되다보니 레포지토리의 메서드 개수 만큼 유스케이스 개수가 정해지는데 혹시 이렇지 않을 경우도 있을까요. 지금 대로라면 1:1개수만큼 생성되는 게 당연한 것 같아서요
- 미해결Flutter 중급 1편 - 클린 아키텍처
Result view 처리
안녕하세요 선생님.선생님 강의를 듣다가 궁금증이 생겨서 질문드립니다.선생님 강의에선 Result를 ViewModel 에서 처리를 하고 View에서 Result에 따라 분기처리하여 화면을 그리셨는데, ViewModel 에서 데이터처리를 하지 않고 사진과 같이 처리를 해도 무관한지 궁금합니다.그리고 강의처럼 ViewModel에서 Result를 처리한 후 View에서 화면을 그리게 하고 싶으나 아래의 코드일 때 Result가 Error일 땐 error 값을 넘겨주면 될 것 같은데 Success 일 땐 어떻게 처리해서 View에 던져줘야 하는지 궁금합니다. 긴 글 읽어주셔서 감사합니다.ViewViewModel Result
- 미해결Flutter 중급 1편 - 클린 아키텍처
Result 타입 에러처리 분기
좋은 강의로 매일 성장하고 있음을 느낍니다 감사합니다.Result 클래스로 viewModel까지 전달 후 분기하는 과정에서 StreamController를 사용하고 뷰에서 이벤트가 발생한 것을 catch하는 방식으로 로직을 구성하셨는데 굉장히 효율적인 방법이라고 생각했습니다.혹시 이것 말고 다른 방법도 있을까요기존에 진행하던 프로젝트에서는 네트워크 연결했을 경우 try catch, 서버에서 400번대 응답을 했을 경우 try catch, json serialization할 때 타입 trycatch(freezed나 jsonSerializable을 사용하지 않았습니다) 이렇게 세번의 try catch가 발생한 것을 하나의 enum을 정의해 뷰에서 enum의 결과에 따라 build안에서 분기하는 과정을 걸쳤는데 굉장히 복잡한 구조가 되었는데 이러한 구조도 괜찮은지, 혹시 이런 구조도 이 강의대로 리팩토링하면 어떨지 감이 안잡히네요
- 미해결Flutter 중급 1편 - 클린 아키텍처
notesEvent 관련 질문
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 안녕하세요!강의를 들으면서 궁금한점이 있습니다. NotesEvent class 가 '사람이 놓칠 수 있는 함수를 미리 정의하기 위해' 라고 이해했습니다.그래서 viewModel 의 onEvent 함수에서 NotesEvent 를 실행하는 거구요. NotesEvent 안의 함수들을 ViewModel 에 바로 정의해서 쓸 수 있음에도 굳이 NotesEvent class 안에 두는건 UI가 나오지 않았지만, 기능정의 먼저 구현하려고 했을 때, 까먹을까봐(?) 미리 일을 해놓는 느낌일까요? 까먹을 수 있을 수도 있는건 NoteEvents class 를 작성할 때도 같을 것이라는 생각이 들어서요! 바로 viewModel 에 event 들을 정의해서 screen 에서 불러 쓰는 건 비추천 하시나요?
- 미해결Flutter 중급 1편 - 클린 아키텍처
viewModel 내의 controller 사용법...
안녕하세요!다른 프로젝트를 만들면서 생기는 고민인데, 어떻게 풀어야 할 지 몰라 여쭤봅니다 ㅠㅠ텍스트 필드 위젯으로 코멘트 작성하기 UI 를 만들고 있습니다.텍스트 필드의 정보를 담고 있는 TextEditingController 를 CommentViewModel에 위치시키고 있고, 이 텍스트 필드는 Reply 기능이나 Email 기능등에도 똑같이 활용하려고 합니다. 그럼 ReplyViewModel 과 EmailViewModel 에도 TextEditingController 를 전부 선언해서 만들어 줘야 할까요? 이럴 경우 어떤 case 인지에 따라 TextField 가 참조해야 하는 viewModel 이 달라지니 분기 처리해서 이번에는 어디ViewModel 의 TextEditingController 를 써~ 라고 해야 할 것 같습니다. 아무래도 좋은 방법이 아닌거 같은데, 선생님의 의견 부탁드립니다 ㅠㅠ
- 미해결Flutter 중급 1편 - 클린 아키텍처
Tab 사용시 Background 상태 혹은 inactive 상태의 알림을 받을 수 있나
안녕하세요 강사님tab 에서 video_play 를 사용하여 네트워크 경로의 비디오를 재생하는데 tab 위에 다른 화면이 올라와도 sound 재생되는 문제가 발생합니다.혹시 해당 문제를 해결할 수 있는 방법이 있을까요? tab 이 pop 되지 않아서 그런지 dispose 함수도 불러오지 못하는데 tab 이 background 혹은 inactive 되었을 때 호출되는 함수가 존재 할까요?
- 미해결Flutter 중급 1편 - 클린 아키텍처
use case 생성할때 repo를 외부에서 주는것과 자신이 생성하는것의 차이가 궁금합니다.
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 강사님이 작성한 use case를 도입하려고 해보는데요use_case들이 repo를 생성해서 가지고 있는것과필수 매개변수로 정의한다음 외부 di에서 주입해서 주는것의 차이가 궁금합니다. 제 생각에는 어차피 생성하는 시점의 차이지 크게 다르지 않은거 같아서 좀더 귀찮음을 방지하려면 use_case가 들고있어도 괜찮을거 같거든요