일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 재귀
- Render object tree
- Widget Tree
- 앱아이콘 변경
- 초기화
- 에러
- linebreak
- 플러터 동작
- 코틀린
- 완전탐색
- flutter
- 프로그래머스
- Kotlin
- IOS
- element tree
- Lazy
- Android
- dart
- 거리알고리즘
- 자료구조
- 비동기 처리
- Singleton
- 플러터
- 프리즈드
- dfs
- 알고리즘
- zwj
- 싱글톤
- Java
- 자바
- Today
- Total
목록Flutter (19)
모바일 개발하는 자바리안의 메모장
강제 업데이트를 구현하며 업데이트 안내 Dialog가 닫힐 때 앱을 강제 종료하는 기능을 구현했는데,, 기본적으로 dart:io에서 제공해주는 exit(0) 함수를 통해 앱을 쉽게 강제 종료할 수 있다. 하지만 이러한 방식으로 코드를 통해 앱을 종료하는 방식은 iOS, AOS 모두 권장하는 방법은 아니라고 하는데,,안드로이드 개발자 가이드에서는 이에 대해 직접적으로 명시하진 않았으나 앱의 life cycle을 관리할 필요가 있음을 강조하며 사용자가 직접 특정한 액션을 취함으로써 앱을 종료하는 방식을 권장한다고 한다.iOS Human Interface Guideline에는 프로그래밍 방식으로 종료하는 것이 사용자 경험을 저해할 수 있다고 명시되어 있으며, 프로그래밍을 통한 강제 종료는 지양해야한다는 내용..
아이콘 변경은 자주하는 작업이 아닌만큼 할 때마다 귀찮고, 헷갈려서 이번 기회에 글로 깔꼼하게 정리해두려고 한다. 공식 플러그인을 사용하는 방법도 있지만 나는 내 기준에서의 shortcut을 택했다. (macOS, Windows 앱을 개발할 경우 플러그인 추천) 우선 Icon으로 사용할 n * n 크기의 png image를 준비한다. Generator 웹 툴을 이용해 필요한 이미지를 추출한다.(iphone, ipad만 선택✅) 압축 파일이 떨어지는데 아래 구조로 되어있다.(appstore.png & playstore.png 는 추후 스토어 app icon 등록할 때 사용) [project root]/ios/Runner/Assets.xcassets를 삭제하고 generator가 만들어준 Assets.xca..
Multi-line Text 위젯에 한글을 띄워줄 때 단어 단위로 줄바꿈이 안되는 상황,,, 모두 한번쯤은 이 답답함을 경험해봤을 것이다. 공식 커뮤니티에서도 약 3년전부터 관련 이슈에 대한 이야기가 계속 되고 있지만 아직까지 수정은 안된 상태. 아마도 원인은 line break처리를 담당하는 API가 CJK(한중일)텍스트의 줄 교환 위치를 정확히 계산하지 못해서인듯하다. Wrap을 이용한 workaround도 있지만 뭔가 무거운 느낌이 있어 regular expression을 찾게되었다 : RegExp(r'(\S)(?=\S)') 이 마법의 정규표현식은 실제 각 character들이 붙어있는지 아닌지를 판단해준다. replaceAllMapped를 사용하여 정규식과 match되는 위치에 ZWJ는 추가해주면..
PC를 바꾸고 난 후부터 iOS쪽에서만 종종 빌드 오류가 발생한다. 처음 플러터를 배울때부터 종종 겪었던 아래와 비슷한 유형의 Cocoapod 에러인데 모두들 한번은 본적이 있지 않을까 싶다 : flutter단에서 네이티브 config 영역에 영향을 끼치는 변경 사항을 반영하고 다시 빌드할 때 뭔가가 꼬여서 발생하는 듯 한데,, flutter clean, iOS clean build 등 뭘해도 해결이 되지 않는다.. 그렇게 삽질을 하다 찾게된 깔끔한 솔루션을 찾았다. Flutter 프로젝트 디렉토리에서 아래 명령어를 실행해준다 : flutter clean rm -rf /ios/Pods rm -rf /ios/Podfile.lock flutter pub get cd ios pod install cd .. f..
Widget 트리만 알고 있었는데, 면접에서 받은 질문을 통해 플러터는 총 3개의 트리가 존재한다는 걸 알게됐다.. 아래와 같은 3개의 트리가 존재하는데, 영역을 나눈 이유는 퍼포먼스를 최적화하기 위해서라고 한다. - Widget - Element - Render Object Widget tree 는 아마 플러터를 사용하는 사람들에겐 가장 익숙한 tree가 아닐까 싶다. 우선 Widget은 immutable 이며 공식 문서에서 설명하는 바로는 Widget은 Element의 설정에 대한 description이라고 한다. 즉, widget을 개발하며 추가하는 property와 같은 정보들이 widget tree에 담기게 된다. Element tree 에서 관리되는 element는 widget의 인스턴스로..
Dart는 Single-threaded 환경에서 작동한다. 그럼 우리가 await, async 등을 통해 사용한 비동기 처리는 어떻게 가능할까... 정답은 Event Loop이다. 이벤트 루프는 애플리케이션에서 발생하는 이벤트(예: 사용자 입력, 타이머, 네트워크 응답 등)를 처리하며, 이러한 이벤트가 발생할 때마다 이벤트 루프는 각 이벤트에 대한 callback을 실행한다. 이벤트는 Event Queue에 추가되며 다음과 같이 2개 타입의 Event Queue가 존재한다 : 1. Microtask Queue 2. Event Queue Microtask Queue는 이벤트 루프가 처리해야 할 가장 높은 우선순위를 가지는 작업을 담는 Queue로 Microtask Queue에는 Future.microtas..
https://pub.dev/packages/freezed freezed | Dart Package Code generation for immutable classes that has a simple syntax/API without compromising on the features. pub.dev Freezed 패키지는 모델을 보다 효율적으로 관리하고 사용할 수 있게 도와주는 Package다. Riverpod을 개발한 팀에서 개발했기 때문에 Provider와 같이 쓰면 더 빛을 발한다고 한다. Freezed pub.dev에 들어가보면 개발자들이 dart에서 모델을 정의하는 일은 매우 지루한 일이라고 설명하며 아래와 같은 기능들을 직접 구현해야하는 게 불편하다고 설명했다 : Constructor Pro..
Flutter에서 non-nullable 객체의 경우 선언과 동시에 값을 초기화해줘야 한다. 처음 flutter를 접하고 instance 변수들을 선언할 때 아래와 같은 에러를 많이 접할 수 있었다 : 그렇다면 나중에 초기화가 필요한 객체의 경우 어떻게 선언을 해줄까? 물론 nullable로 타입을 바꿔주면 문제를 쉽게 해결할 수 있다. 하지만 만약 해당 객체가 절대 null이 될 수 없는, 특정 시점에 무조건 초기화가 될 객체라면? 절대 null이 되지 않는 객체임에도 불구하고, 오랜 시간이 지난 후에 다시 보거나 다른 개발자가 봤을 때 nullable한 객체로 간주하게 될 우려가 있다.. 또한, 공식 문서에 정리된 내용을 보면 control flow analysis가 인스턴스 변수, top-level..
개발을 하다보면 많은 import 때문에 코드 상단이 지저분해지는 경우가 많다. 보다 정결하게 코드를 관리하는 법은 없을지 항상 고민하다가 최근 아주 속시원한 솔루션을 찾을 수 있었다. 바로 export를 이용하는 방법이다. 예를들어 A라는 페키지 아래와 같은 파일이 있다고 생각해보자. 그리고 동일, 혹은 다른 페키지에 있는 파일에서 상기 정의한 파일들을 사용해야 한다면 아래와 같이 각 dart 파일에 대한 import를 해줘야한다 : import 'package:flutter/widgets.dart'; import 'package:solve/pacakage_a/class_a.dart'; import 'package:solve/pacakage_a/class_b.dart'; import 'package:s..
메인 함수에서 WidgetsFlutterBinding.ensureInitialized() 함수를 사용하는 경우가 많다. 지금까진 해당 함수를 직접 작성할 일이 없어 그냥 지나치다가 이번에 새로운 프로젝트를 시작하며 해당 함수의 역할을 알게되었다. 해당 함수는 시작점인 main() 함수에서 비동기 처리 코드를 사용하기에 앞서, 미리 flutter 엔진과 widget을 바운딩 처리해준다. 우선 아래 코드를 실행할 경우 발생하는 코드를 보자 : void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { MyApp({super.key}) { init(); } @override Widget build(BuildContext context) { r..