728x90

플러터 30

[Flutter 앱 개발하기] 구글 플레이스토어에 올릴 번들 만들기

번들 만들기 간단하다. 프로젝트 홈에서: $ flutter run appbundle 생성되는 위치 위치를 기억하는게 더 어렵다. [PROJECT] / build / app /outputs / bundle / release / app-release.aab 이 파일을 플레이스토어 - (사이드메뉴의) 출시 - 프로덕션 - 새버전만들기 그리고는 아래 파일 업로드 영역에 드래그하거나 파일 열기 창을 이용해 업로드 한다.

IT 2023.04.01

[Flutter 앱 개발하기] 파이어베이스 Remote Config 사용하기

설정값을 리모트로 관리하면 앱을 업데이트 하지 않아도 (특정 config값을 통해) 앱의 설정 등을 바꿀 수 있어 도움이 될 때가 있다. 또한 모바일앱 강제 업데이트의 사례에서 현재 배포된 최신 앱 버전이나 강제 업데이트 대상을 확인하는 목적의 최소 앱 버전을 확인하는 등 앱 운영 측면에서도 활용도가 높다. https://pub.dev/packages/firebase_remote_config firebase_remote_config | Flutter Package Flutter plugin for Firebase Remote Config. Update your application look and feel and behavior without re-releasing. pub.dev 클라우드 환경에 설정값..

IT 2023.03.17

[Flutter 앱 개발하기] 패키지 정보를 읽기

패키지 정보를 읽어내는 플러그인을 소개한다. https://pub.dev/packages/package_info_plus package_info_plus | Flutter Package Flutter plugin for querying information about the application package, such as CFBundleVersion on iOS or versionCode on Android. pub.dev 예를들어 플러터앱을 배포하거나, 혹은 관리 차원에서 pubspec.yaml 파일에 version을 설정하는데, package_info_plus 패키지를 이용하면 쉽게 이 정보를 앱에서 읽어올 수 있다. import 'package:package_info_plus/package_in..

IT 2023.03.17

[Flutter 앱 개발하기] 릴리즈 모드와 디버그 모드

Release mode vs. Debug mode 플러터를 개발하는 과정은 보통 디버그(Debug) 모드, 앱 개발을 마치고 배포할 때는 릴리즈(Release) 모드로 개발한다. 예를들어 릴리즈 모드로 실행할 때에는 이렇게 한다. $ flutter run --release 릴리즈 모드는 디버깅에 필요한 정보가 포함되지 않으므로 디버그 모드로 실행할 때보다 용량이 작아 배포하기에 용이하다. 반대로 디버깅이 필요하다면 디버그 모드로 실행하는게 유리하다. 앱 내에서 Release mode, Debug mode 구분하기 앱 안에서 릴리즈 모드로 실행 중인지, 아니면 디버그 모드로 실행 중인지에 따라 동작을 달리하고 싶다면 다음과 같이 할 수 있다. import 'package:flutter/foundation...

IT 2023.03.17

[Flutter 앱 개발] 폰트 사이즈 고정하기

사용자가 설정 - 디스플레이 옵션에서 폰트크기를 크게 키우면 내가 만든 앱에서 설정한 폰트 크기에도 영향을 주게 된다. 그러다보면 UI가 깨지게 되는데, 절대값으로 고정하는 방법이 있다 class MyApp extends StatelessWidget { const MyApp({super.key}); // This widget is the root of your application. @override Widget build(BuildContext context) { return MultiProvider( providers: [ ChangeNotifierProvider(create: (_) => Auth()), ], child: MaterialApp( builder: (context, child) { re..

IT 2023.03.13

[Flutter 앱 개발하기] ListTile 높이 변경하기

ListTile() 객체에는 height 높이를 설정하는 파라메터가 없다. 직접 수치를 입력할 수는 없지만 dense, visualDensity 파라미터 설정을 통해 ListTile객체의 높이를 조절할 수 있다. 예시는 아래와 같다. ListTile( dense: true, visualDensity: VisualDensity(vertical: -3), leading: Icon(Icons.signal_cellular_alt), title: Text( "타이틀", style: TextStyle(fontSize: 16), ), trailing: Text("값"), ), dense를 true로 놓으면 leading, trailing 의 크기(높이)가 32, false이면 40으로 제한된다. VisualDensi..

IT 2023.02.08

[Flutter 앱 개발하기] ffi wrong architecture 에러 해결하기

Error: To set up CocoaPods for ARM macOS, run: sudo gem uninstall ffi && sudo gem install ffi -- --enable-libffi-alloc 애플 맥미니 M1 버전에서 플러터 앱을 실행하다보면 위와 같은 running pod install 과정에서 위와 같은 에러를 접할 때가 있다. 아래와 같이 관련 코코아파드 컴포넌트들을 하나하나 지워 준 후 x86_64 아키텍처로 새로 설치해 주면 해당 에러를 해결 할 수 있다. sudo gem uninstall ffi && sudo gem install ffi -- --enable-libffi-alloc brew uninstall ruby --force gem list --local | grep..

IT 2023.02.04

[Flutter 앱 개발하기] Firestore에 복수 field로 필터링 할 때 에러 해결

아래와 같이 Firestore의 where 절을 이용해 쿼리를 날릴 때, 응답이 없을 때가 있다. QuerySnapshot querySnapshot = await notificationReference .where("userId", isEqualTo: authClient.currentUser!.uid) .where("isValid", isEqualTo: false) .where("createdAt", isGreaterThanOrEqualTo: Timestamp.fromDate( DateTime.now().subtract(const Duration(days: 1)))) .get(); 보통 이렇게 firestore 응답이 없으면 exception인 경우가 많은데, 이 경우에는 index가 없어서 그렇다 디버..

IT 2023.01.16

[Flutter 앱 개발하기] TextField 에 숫자만 입력 받기

데이터를 입력 받는 기능을 구현하다보면, 문자가 아니라 숫자만, 혹은 숫자와 - 기호, 소수점 표현을 위한 . 등의 특수 문자만 입력 받고 싶을 때가 있다. 아래와 같이 FilteringTextInputFormatter 를 이용해 허용하는 캐릭터를 지정할 수 있다. import 'package:flutter/services.dart'; ... return TextField( onChanged: (value) { registerInputField.setKRWUSDRate(double.parse(value)); }, inputFormatters: [ FilteringTextInputFormatter.allow(RegExp(r'^-?\d*.?\d*')), ], keyboardType: TextInputType..

IT 2023.01.11

[Flutter 앱 개발하기] 정렬(sort)하기

코딩을 하다보면 iterable 값들(elements)을 정렬 해 보여줘야 할 때가 있다. 예를 들어 각 element가 Voca 라는 class이고 각 instance에는 voca라는 속성이 있다고 하자. alphabetical 오름차순으로 정렬한다면 아래와 같이 할 수 있다. voca_list.sort((a, b) => a.voca.toLowerCase().compareTo(b.voca.toLowerCase())); alphabetical 내림차순은 a,b의 순서가 바뀐다. voca_list.sort((a, b) => b.voca.toLowerCase().compareTo(a.voca.toLowerCase())); element에 있는 속성값으로 비교해서 정렬하기 힘들고, 특정 함수를 거쳐서 정렬해야..

IT 2023.01.09

[Flutter 앱 개발하기] map 함수 사용하기

플러터에서 사용하는 언어인 Dart에는 Iterable 이란 개념이 있다. - 데이터 컬렉션 (모음) 이고, - 순차적으로(sequentially) 접근이 가능한 데이터를 말한다. 예를들면, list 나 array는 iterable 이다. map 함수는 iterable에 대해서 foreach를 수행할 수 있다. var l = [1, 2, 3]; var new_l = l.map((e) => e + 1).toList(); print(l); // [1, 2, 3] print(new_l); // [2, 3, 4] iterable을 돌면서 각각의(for each) element(e)에 대해 +1 을 수행한다.

IT 2023.01.09

[Flutter 앱 개발하기] Unique ID 만들기

개발하다보면 객체별로 고유한 ID 값이 필요할 때가 있는데, https://pub.dev/packages/uuid uuid | Dart Package RFC4122 (v1, v4, v5) UUID Generator and Parser for all Dart platforms (Web, VM, Flutter) pub.dev 위에 소개된 UUID를 사용하는 방법을 우선 소개해 본다. import 'package:uuid/uuid.dart'; var uuid = Uuid(); print(uuid.v1()); print(uuid.v4()); print(uuid.v5(Uuid.NAMESPACE_URL, 'www.google.com')); v1()은 time-base 로 ID 값을 생성해 주고, v4()는 랜덤하게..

IT 2023.01.02

[Flutter 앱 개발하기] 위젯 안에서 조건문에 따라 child widget 그리기

예를들어, 특정 변수가 true이면 성공 버튼을 보여주고 false 일 때는 실패 버튼을 보여주고 싶다면, Column( children: [ SizedBox( height: 100, width: _width, child: Container( color: Colors.amber, child: Text("결과 성공여부 = ${(arg.isWin ? "성공" : "실패")}, 시간"), ), ), (arg.isWin) ? CupertinoButton( child: Text("성공"), color: Color.fromARGB(255, 59, 121, 255), onPressed: () { showSnackbar(context, '성공했습니다.'); }) : CupertinoButton( child: Text(..

IT 2023.01.02

[Flutter 앱 개발하기] TabBar 에서 Tab text가 짤려 보일 때

Tab의 갯수가 많고 Tab의 text가 긴 경우에는 아래와 같이 짤려 보인다. 이런 경우에 TabBar의 속성 중 isScrollable 을 true로 하면 필요한 만큼 horizontal 스크롤이 가능하다. return Scaffold( appBar: AppBar( title: Text("연습"), bottom: TabBar( controller: _tabController, isScrollable: true, tabs: [ Tab(text: "가나다라마", icon: Icon(Icons.home)), Tab(text: "바사아자차", icon: Icon(Icons.stadium)), Tab(text: "카타파하가", icon: Icon(Icons.south_america)), Tab(text: "나..

IT 2022.12.31

[Flutter 앱 개발하기] Navigator 페이지 전환할 때 파라미터 넘기기

페이지 이동할 때 특정 값을 넘기고 싶을 때가 있다. ​ Navigator의 pushNamed() 메소드를 예로들면 arguments라는 속성이 있어 이를 통해 특정 오브젝트를 넘길 수 있다. Navigator.of(context).pushNamed('/addObject', arguments: obj) 파라미터를 받는 페이지에서는 build 함수 안에서 아래와 같이 값을 확인 할 수 있다. @override Widget build(BuildContext context) { final arg = ModalRoute.of(context)!.settings.arguments as ObjectType; return Scaffold( ... ); } ​ obj객체는 int, double 같은 기본 타입이거나, e..

IT 2022.12.30

[Flutter 앱 개발하기] ListView.builder hasSize 에러 해결

구현하다보면 SingleChildScrollView 아래 Column, 그 안에 ListView.builder 같은 구조를 구현할 때가 있는데, 실행해 보면 hasSize 에러가 나올 때, ​ ListView.builder에 shrinkWrap 속성을 true로 하면 에러를 피할 수 있다. ​ 애초에 왜 에러가 났는지 이해하고 넘어가보자면 ListView.builder는 기본적으로 List item을 보여줄 때 꼭 필요한 공간만 사용하지 않고, 가능한 영역을 최대한 사용하도록 구현되어 있는데 이 길이가 고정되어 있지 않아서 hasSize 가 아니라는 에러가 나오는 결과로 이어진다. shrinkWrap 을 true로 하면, List item을 보여주는데 꼭 필요한 영역만 사용하도록 제약하기 때문에 size..

IT 2022.12.30

[Flutter 앱 개발하기] webview_flutter 에서 비디오 인라인으로 플레이하기

webview_flutter | Flutter Package A Flutter plugin that provides a WebView widget on Android and iOS. pub.dev 앱에서 웹뷰 구현을 위해 webview_flutter 플러그인을 사용한다. (Android, iOS 지원) ​ 구현을 하다보니 웹뷰 내에서 유튜브 등의 비디오를 플레이 해야 하는데, (ios 정책에 따라) 앱에서 플레이 누르면 전체 화면으로 따로 떠서 재생이 된다. 내가 원하는 것은 앱 내에서 임베디드 되서 플레이 되는 것인데.. ​ 웹 비디오라면 video 태그 안에 playsinline 속성을 이용해서 이를 구현 할 수 있다. ​ webview_flutter 플러그인은 다행히 같은 동작을 지원한다. 아래와 ..

IT 2022.12.30

[Flutter 앱 개발하기] MACOSX_DEPLOYMENT_TARGET 에러 해결

macos / Podfile에 입력을 해도 컴파일 할 때 버전 반영이 안될 경우가 있다. 버그 같다. ​ Workaround는 해당 파일 하단의 아래 내용을 post_install do |installer| installer.pods_project.targets.each do |target| flutter_additional_macos_build_settings(target) end end​ 아래와 같이 수정한다. (원하는 버전으로 수정) post_install do |installer| installer.pods_project.targets.each do |target| flutter_additional_macos_build_settings(target) target.build_configuration..

IT 2022.12.30

[Flutter 앱 개발하기] Firebase auth 를 macOS에서 사용하기

Firebase_auth를 macOS에서 사용하려고 하면 아래와 같은 에러를 만나게 된다. [!] The FlutterFire plugin firebase_auth for macOS requires a macOS deployment target of 10.12 or later. 아래와 같이 해결 방안도 함께 알려준다. - Update the `platform :osx, '10.11'` line in your macOS/Podfile to version `10.12` and ensure you commit this file. - Open your `macos/Runner.xcodeproj` Xcode project and under the 'Runner' target General tab set your ..

IT 2022.12.30

[Flutter 앱 개발하기] 여러 OS 지원하기 (앱에서 OS 확인하는 법)

Multi OS를 지원하는 앱을 만들 경우 (예를들어 Android, iOS, MacOS, Windows..), 다음과 같은 방법으로 앱 내에서 OS 종류를 확인 할 수 있다. import 'dart:io'; ... if (Platform.isMacOS) { } else if (Platform.isIOS) { } else if (Platform.isAndroid) { } else if (Platform.isWindows) { } else if (Platform.isLinux) { } else { } Material Design을 적용해 앱을 만들어서 각 OS에서 동일하게 보이게 만드는 경우도 있지만, OS 특성에 맞게 특화 UI를 구현하면 사용자 경험 측면에서 더 좋을 때도 있어서 그렇다. ​ 참고로 이..

IT 2022.12.30

[Flutter 앱 개발하기] enum 타입 SharedPreference 에 저장하기

플러터에서 enum 타입의 값을 SharedPreference에 저장하고 싶을 때가 있다. ​ enum OrderByOptions { byCreatedAtDescending, byCreatedAtAscending, } ​ 하지만 SharedPreferences는 Int 나 String 같은 기본형 타입만 저장이 가능하다. ​ 이런 경우에는 enum 타입의 index를 이용해 Int 형식으로 저장해 사용하면 된다. ​ 먼저, SharedPreferences에는 아래와 같이 저장할 수 있다. SharedPreferences prefs = await SharedPreferences.getInstance(); await prefs.setInt("orderBy", selectedOrderByOption.index..

IT 2022.12.30
728x90