OS : MAC

Terminal명령어 정리

더보기

파일 생성 : touch [파일명]   / echo "문자열" > [파일명]   문자열을 넣음과 동시에 파일을 생성함

파일 옮기기 : mv [origin] [target]    -r : 파일 이동 보임,   -i : 덮어씌울 시 메시지 보임,   -f : 확인 메시지 없이 옮김

현재 디렉토리 보기 : pwd

move file(파일 옮기기) : 

tab보기 : swipe down to top three finger on pad

환경변수 : export   / export만 쓰면 모든 환경 변수 출력, export HOME 하면 HOME변수의 path값을 볼 수 있음

환경변수 삭제 : unset   / unset 변수명

바탕화면 dmg파일 : cmd + E 마운트 제거

 

grep [옵션] [패턴] [파일]

-i: 대소문자를 구분하지 않습니다.
-n: 검색된 행의 번호를 출력합니다.
-c: 검색된 행의 개수를 출력합니다.
-v: 패턴과 일치하지 않는 행을 출력합니다.
-E: 확장된 정규 표현식을 사용합니다.
-e: 여러 개의 패턴을 지정합니다.

 

 

새로운 MAC에 다시 Flutter SDK경로를 설치하면서 글로 정리해보려고 합니다.

flutter pub get
flutter pub upgrade
flutter clean
...
..
.

 

다양한 'flutter ~ '로 시작되는 명령어가 있습니다.

해당 명령을 사용하기 위해서는 Flutter SDK를 설치해주어야 하고, 설치한 이후 CLI(커맨드창, 쉘창, 명령어창.. 검은창)에서 사용하기 위해 경로를 설정해주어야 합니다. 

 

Download Flutter SDK execute File

https://docs.flutter.dev/

 

위의 링크를 통해 플러터 공식 사이트에 접속합니다.

좌측(사이드바)의 'Set up Flutter'를 클릭해주세요.

 

 

현재 Mac환경으로 진행 중 이니 'mac OS'를 클릭해주세요.

 

 

다음으로 어떤 OS의 앱을 만들 것인지 선택하는 항목이 나오는데요.

처음 포켓몬 고르듯이 어려워 마시고 'iOS'를 선택해주세요.

추후 모든 OS에서 빌드가 가능합니다.

 

쭉~ 스크롤해서 내려가다보면 'Install the Flutter SDK'가 보이실 겁니다.

본인의 Mac환경에 맞게 설치해주시면 됩니다.

만약에 왼쪽인지 오른쪽인지 도저히 모르겠다면, 좌측 상단 사과 표시를 클릭하시고,

'이 Mac에 관하여'를 클릭하세요.

 

그리고 '칩' 정보를 보면 M으로 시작하면 Apple Silicon

그 외에는 좌측의 Intel Processor를 선택해서 다운로드 해주세요.

 

 

뒤에 '.zip'이라고 되어있는데요. 그것은 파일이 현재 압축된 상태를 뜻합니다.

압축되어 있으면 사용을 할 수 없기 때문에 압축된 파일을 풀어주도록 합니다.

다운로드 받은 파일을 열어주시면 자동으로 압축이 해제됩니다.

 

압축을 해제하면 'flutter'라는 폴더와 함께 여러 파일이 리스트에 보여지게 됩니다.

압축해제가 잘되었습니다.

 

 

이제부터가 어려울 수 있습니다. 집중해주세요.

Spotlight검색을 하셔서 'Terminal'을 입력하여 터미널 창을 실행해주세요.

 

(화면이 흰색, 회색, 검은색이든 상관 없답니다. 문제가 생긴 것이 아니니 안심하세요^^)

지금부터 작성되는 글은 계속 터미널 화면에 명령어를 치면 되겠습니다.

 

'export'라고 입력하면, 현재 Mac에 설정된 환경을 볼 수 있습니다.

user@user-Mac ~ % export

 

우리는 '.zshenv'라는 파일을 만들어야 합니다. 그리고 'export'로 확인했을때 보였던 'PATH=~~'로 이루어진 내용을 '.zshenv'파일안으로 이동시켜야 합니다. 

학교에서 선생님이 칠판에 여러 문장을 적었지만, 시험에 나온다고 노트에 필기하라고 하는 것을 따로 말씀해주듯이 우리는 칠판(export)안에 있는 내용 중에 시험에 나오는 내용(PATH=~ ~ )본인의 노트(.zshenv)에 적는다고 생각하시면 됩니다.

 

그리고 옮길 때 아까전에 설치했던 Flutter SDK를 압축해제하고 생겼던 폴더로 잠시 이동해주세요.

정말 어렵게 느껴질 수 있지만 알고나면 별 것 아니랍니다. 조금만 더 힘내주세요.

flutter폴더 내부 'bin'폴더의 경로를 확인해주세요.

 

자, 그럼 이제 다시 터미널 창으로 돌아와서 명령어를 입력하겠습니다.

user@user-Mac ~ % echo PATH=$HOME/donguran/tool/flutter/bin:$PATH > ~/.zshenv

 

(해석)

PATH를 설정해주는데 $PATH는 기존 PATH입니다. 그 앞에 Flutter SDK의 bin폴더를 추가해주고 마지막 '>'로 우측 파일로 해당 문장을 입력한다는 것 입니다. .zshenv파일이 만약에 없다면 새로 생성되면 해당 문장이 입력됩니다.

 

그리고 다시 Visual Studio 또는 Android Studio로 돌아와서 (만약에 켜져있었다면 껐다 키기)

flutter ~ 명령어를 실행하면 정상적으로 실행되는 것을 확인할 수 있습니다.

 

 

궁금한 점을 댓글 달아주시면 빠른 시간 내로 답변드리도록 하겠습니다.

 

감사합니다.

 

 

@DONGURAN

안녕하세요! 

LoadingProgressbar Widget을 소개해드리려고 합니다.

 

 

어떤 위젯인가?

- 로그인, 파일 다운로드, 비동기작업 등을 하실 때 아주 간편하게 표현할 수 있는 위젯입니다.

 

일반적으로 로딩 프로그레스바를 표현하려면 새롭게 위젯을 구성해주어야 하죠?

Stack ~ Center ~ CircularProgressIndicator... 등 여러개의 위젯을 구성해주고,

해당 프로그레스바 위젯을 보여주기위해 setState를하여 isVisible = ture/false처리를 해줍니다.

 

간단해보이지만 은근히 처리하기 귀찮고 까다로운게 바로 로딩프로그레스바입니다.

추가로 현재 프로그레스바가 얼마나 진행했는지도 표현하려면 값도 넣어주어야 하죠.

 

이 모든걸 한 번에 해결할 수 있는 것이 바로 LoadingProgressbar Widget입니다.

 

 

사용법을 설명드리기 앞서 먼저 라이브러리를 추가하는 방법을 알려드리겠습니다.

install : https://pub.dev/packages/loading_progressbar/install

 

yaml

dependencies:
  ...
  loading_progressbar: <last_version>

 

shell

flutter pub add loading_progressbar

 

 

어떻게 사용하는가?

Progress 표현이 필요한 부모 위젯을 감싸주기만 하면 됩니다.

 

예시를 들어볼게요.

HomeScreen이라는 위젯이 있고, Scaffold로 구조되어 있다고 가정하겠습니다.

class HomeScreen extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body:Center(
        child: Text("Home Screen"),
      )
    );
  }
}

 

 

HomeScreen에서 Progressbar를 표현하고 싶다면 ScaffoldLoadingProgressbar 위젯으로 감싸주시면 됩니다!

import 'package:loading_progressbar/loading_progressbar.dart';

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return LoadingProgressbar(
      controller: ...,
      progressbar: (context, progress) => ...,
      
      child: Scaffold(
        body: Center(
          child: Text("Home Screen"),
        ),
      ),
    );
  }
}

 

정말 간단하죠?

 

추가로 필수 파라메터를 만들어주어야 합니다.

controller와 progressbar입니다.

 

controller : LoadingProgressbar를 컨트롤할 수 있는 클래스

progressbar : LoadingProgressbar위젯에서 표현할 Progress위젯

 

LoadingProgressbar위젯만 덜렁~ 있으면 스스로 동작하지 않겠죠~?

당연히 신호를 주어야 동작할 것 입니다.

 

그런 신호를 주고 받을 수 있는 것이 LoadingProgressbarController클래스입니다.

LoadingProgressbarController인스턴스를 생성해주고 LoadingProgressbar위젯의 controller파라메터에 장착시켜주면 되겠습니다.

 

그리고 마지막으로 'progressbar' 파라메터에 표현하고 싶은 프로그레스 위젯을 설정해주세요!

final LoadingProgressbarController controller = LoadingProgressbarController();

@override
Widget build(BuildContext context) {
  return LoadingProgressbar(
    controller: controller,
    progressbar: (context, progress) => CircularProgressIndicator(),
    child: Scaffold(
      body: Center(
        child: Text("Home Screen"),
      ),
    ),
  );
}

 

 

그리고 이제 controller의 함수를 사용해서 정의한 프로그레스바 위젯을 표현하시면 되겠습니다 !

버튼을 눌렀을 때 예제코드는 다음과 같습니다.

ElevatedButton(
  onPressed: () {
    controller.show();
  },
  
  child: Text("Progressbar Visible"),
),

 

 

더욱 자세한 건 패키지 설명서를 확인해보세요 ! 

https://pub.dev/packages/loading_progressbar

 

loading_progressbar | Flutter package

Flutter LoadingProgressbar Widget. You can pull out the progressbar Widget Whenever you want.

pub.dev

 

 

 

감사합니다.

먼저 Radio<TYPE>으로 라디오 버튼을 만들어준다.

 

각 라디오가 서로 그룹임을 알려주려면 하나의 인스턴스를 서로 바라보고 있으면 된다.

int number = 0;

@override
Widget build(BuildContext context) {
  return Column(
    children: [
      Radio<int> (
        value: 0,
        groupValue: number,
      ),
      
      Radio<int> (
        value: 1,
        groupValue: number,
      )
    ],
  )
}

 

 

value는 각 라디오가 가지고 있는 고유 값을 뜻하며, 라디오 버튼을 클릭했을 때 onChanged함수를 통해서 값이 전달된다.

 

 

색상

activeColor를 넣어주어야 isChecked와 기본 색상이다.

 

 

 

https://api.flutter.dev/flutter/material/Radio-class.html

 

Radio class - material library - Dart API

A Material Design radio button. Used to select between a number of mutually exclusive values. When one radio button in a group is selected, the other radio buttons in the group cease to be selected. The values are of type T, the type parameter of the Radio

api.flutter.dev

 

 

Hello Flutter Worldwide.

Today I introduce one of the indie flutter packages.

It is name `flutter_logcat`

 

This package will be incredibly helpful to all of you.
If you make good use of logs, it will make development much more convenient.

 

In Flutter, logs are displayed in the console without any distinguishing colors.
However, by using this package, you can view messages in the console with colors that you define.
Additionally, you can configure it so that logs are hidden in debug mode, and you can also set it to display tags, file paths, and timestamps.

 

 

Usage is very simple!

 

Try it!

 

 

https://pub.dev/packages/flutter_logcat

 

flutter_logcat | Flutter package

You can view messages in the console with colors that you define. Also set it to display tags, file paths, and timestamps

pub.dev

 

랜덤하게 숫자를 받아야 한다. 그것을 '난수'라고 부른다.

1부터 10까지 랜덤하게 숫자를 받고 싶은 경우 Random을 사용한다.

 

Import

import 'dart:math';

 

Create Instance

var random = Random();

// 1 ~ 10
int result = random.nextInt(10) + 1;

 

+1을 해주지 않으면 0부터 9까지 숫자를 갖게 된다.

 

 

double형태로 받고 싶은 경우 (0.0 ~ 1.0)

double resultDouble = random.nextDouble();

 

 

Boolean형태로 받고 싶은 경우

bool resultBool = random.nextBool();

 

 

Color로 받고 싶은 경우

// Random from 'dart:math'
Color currentColor = Color((Random().nextDouble() * 0xFFFFFF).toInt());

try ~ catch란? "예방", "방어"의 의미로 볼 수 있다.

 

코드를 작성하다보면 정말 다양한 경우의 수를 만나게 된다.

내가 받아야하는 결과값이 모호한 경우 try ~ catch문을 사용한다.

 

기본 사용법

  try {
    int result = int.parse("Occur Error!");
    print("result:$result");
  } catch (e, stackTrace) {
    print("Error:$e");
  }

 

String타입을 int타입으로 변환(형변환)하려는 코드이다.

에러메시지는 다음과 같이 표출된다.

Error:FormatException: Occur Error!

 

 

에러 추적 하는법

catch안에는 사실 두 개의 파라메터가 존재하다.

e만 있는 것이 아닌 stackTrace도 정의해주면 에러가 어떻게 발생되었는지 그 과정을 볼 수 있다.

  try {
    int result = int.parse("Occur Error!");
    print("result:$result");
  } catch (e, stackTrace) {
    print("Error:$e");
    print("StackTrace:$stackTrace");
  }

 

 

 

'on'키워드 사용

Error의 메시지를 보면 FormatException이 발생한 것을 알 수 있다.

상황에 따라서 여러 예외상황이 발생했을때 다르게 분기처리를 해주어야 하는 경우도 있을 것이다.

그런 경우를 위해 'on' 키워드를 사용해서 예외를 분리한다.

  try {
    int result = int.parse("Occur Error!");
  } on FormatException {
    print("Implement.. FormatException");
  } catch (e) {
    print("Error:$e");
  }
}

 

if문처럼 조건이 맞으면 다음 catch문은 읽지 않기 때문에 상황에따라 적절하게 구현하면 될 것이다.

추가로 on FormatException이라고 분리해준뒤 catch문을 사용해서 어떠한 에러인지 왜 발생했는지 추적할 수 있다.

  try {
    int result = int.parse("Occur Error!");
  } on FormatException catch(e, stackTrace){
    print("Implement.. FormatException.. Error:$e");
  } catch (e) {
    print("Error:$e");
  }

 

 

finally키워드

try ~ catch문을 사용한 이후 어떠한 작업이 이루어져도 무조건적으로 실행해주는 동작을 뜻한다.

에러가 발생해도 무조건 실행해주는 동작, 이라고 이해하면 쉽다.(당연히 정상적인 동작이 되어도 실행해준다)

  try {
    int result = int.parse("Occur Error!");
  } on FormatException catch(e, stackTrace){
    print("Implement.. FormatException.. Error:$e");
  } catch (e) {
    print("Error:$e");
  } finally{
    print("Finally Exit Casting Operate String to Integer..");
  }

 

 

rethrow 고급 문법

try ~ catch내부에 또다른 try ~ catch가 있는 경우 rethrow키워드를 사용해서 상위 try ~ catch문에 Exception을 전달하는 것이다. 예외를 발생하는 것을 상위 try ~ catch문으로 다시 던지는 것이라고 보면 된다.

 

File - New - New Flutter Project - Package

 

pubspec.yaml 설정

name: [라이브러리 이름]
description: [설명]
version: 1.0.1 //버전
homepage: [홈페이지 주소]
repository: [코드 저장소 주소]

 

 

example 폴더 생성

- 생성시 pub.dev에서 example란에 표시됨

flutter create example

 

- android, ios만 생성하고 싶은 경우

flutter create --platforms android,ios -a kotlin -i swift example

 

 

example yaml에서 본인 라이브러리를 사용하는 방법

path: ../ 추가

dev_dependencies:
  flutter_test:
    sdk: flutter

  [라이브러리 이름]:
    path: ../

 

 

코드 정렬

dart format .

 

점검, 확인

flutter pub publish --dry-run

 

올리기

flutter pub publish

 

 


Pub Cache경로 설정

https://dart.dev/tools/pub/cmd/pub-cache

User에 대한 사용자 변수이름 : PUB_CACHE경로 : D:/src/Pub/Cache- 컴퓨터 다시 시작을 해야 잘 적용된다

 

 

특정 OS만 가능하도록 설정

: 아래 사항을 표시하지 않으면 모든 OS에서 사용이 가능함을 뜻함

flutter:
  plugin:
    platforms:
      android: ^2.3.0
      ios: ^3.0.0

 

 

플러그인 

전체 추가 명령

- 아무 플랫폼도 없거나 해당 플랫폼 빌드가 안되면 플러터에서 알려줄 것이다.

flutter create .

 

개별 추가 명령

- android, ios, web, macos, window

flutter create --platforms -android .

 

flutter create --org com.example --template=plugin --platforms=android,ios,linux,macos,windows -a kotlin hello

 

다음과 같이 실행해주어야 '플러그인'이 생성된다.

$ flutter create --org com.donguran --template=plugin --platforms=android,ios -a kotlin -i swift torch

 

 

그리고 gitignore에 다음을 꼭 명시해준다.

* 8 checked-in files are ignored by a `.gitignore`.
  Previous versions of Pub would include those in the published package.

  Consider adjusting your `.gitignore` files to not ignore those files, and if you do not wish to
  publish these files use `.pubignore`. See also dart.dev/go/pubignore

  Files that are checked in while gitignored:

  .idea/.gitignore
  .idea/inspectionProfiles/Project_Default.xml
  .idea/libraries/Dart_SDK.xml
  .idea/libraries/Flutter_Plugins.xml
  .idea/misc.xml
  .idea/modules.xml
  .idea/torch.iml
  .idea/vcs.xml


* D:\donguran\dev\flutter\app\torch\CHANGELOG.md doesn't mention current version (0.1.1).
  Consider updating it with notes on this version prior to publication.
Package validation found the following hint:
* You're about to publish a package that opts into null safety.
  The previous version (0.1.0) isn't opted in.
  See https://dart.dev/null-safety/migration-guide for best practices.

아래는 이미 버전이 있다는 말..

 

패키지 우측 이미지 넣기

ref : bloc패키지 참조

screenshots:
  - description: torchx logo.
    path: screenshots/logo.png

 

 

해당 패키지 admin에서 publisher를 수정할 수 있다.

 

2024-04-23-화 : 패키지 경로를 설정할 때

export: "pacakge:..." 로 시작하지 않고,

내부 경로로 설정해주어도 괜찮다.

 

그리고 'show'키워드를 통해서 사용할 기능만 등록할 수 있다.

 

 

패키지 우측 이미지 넣기

ref : bloc패키지 참조

screenshots:
  - description: torchx logo.
    path: screenshots/logo.png

 

 

해당 패키지 admin에서 publisher를 수정할 수 있다.

 

2024-04-23-화 : 패키지 경로를 설정할 때

export: "pacakge:..." 로 시작하지 않고,

내부 경로로 설정해주어도 괜찮다.

 

그리고 'show'키워드를 통해서 사용할 기능만 등록할 수 있다.

 

 

플러터 폴더명 관례

'src'라는 이름으로 폴더를 만들면 외부에서 접근할 수 없게 된다.

'assets'라는 이름으로 폴더를 만들어야 앱에 번들로 포함되어 빌드된다.

assets하위의 폴더이름은 자유롭게 해도 상관없지만, 

  • json → data
  • 이미지 → images
  • 폰트 → fonts

 

직접 깃 저장소에 있는 라이브러리를 불러서 편집해보기

git clone https://github.com/b3lon9/loading_progressbar.git

 

yaml

dependencies:
  loading_progressbar:
    path: /download/git/loading_progressbar

인터넷 연결이 되어있는지 확인하기위해서 다음 패키지를 사용한다.

 

Add

flutter pub add internet_connection_checker

 

Usage

import 'package:internet_connection_checker/internet_connection_checker.dart';

bool isInternetConnected = await InternetConnectionChecker().hasConnection;

 

 

 

여러번 확인을 하기 위해 'StreamBuilder'를 사용한다.

그리고 10초마다 확인하기위한 Steam함수를 작성한다.

Stream<bool> checkInternetConnectedPeriodically() async* {
  bool isConnect = await checkInternetConnect();
  
  while (!isConnect) {
    yield await checkInternetConnect();
    
    isConenct = await checkInternetConnect();
    await Future.delayed(const Duration(seconds: 10));
  }
  
  yield isConnect;
}
Future<bool> checkInternetConnected() async {
  return await InternetConnectionChecker().hasConnection;
}

 

Use StreamBuilder

@override
Widget build(BuildContext context) {
  stream: checkInternetConnectedPeriodically(),
  builder: (context, AsyncSnapshot<bool> snapshot) {
    if (snapshot.data == true) {
      return Home();
    } else {
      return LoadingProgressbar();
    }
  }
}

Flutter에서 Android의 Fragment처럼 동작되는 위젯을 구현해보았다.

만들 예제는 하나의 기본 화면이 Container안에 있고 추가적으로 다른 위젯을 대체시키고, 뒤로가기가 가능하여 앞의 위젯이 다시 표출되도록 만들것

 

우선, Fragment처럼 사용할 위젯들을 담아내는 Container를 하나 만든다.

List<Widget> container = [];

 

(StatefulWidget으로 setState함수로 UI를 갱신시킬 것이다)

 

 

Android에서 Fragment를 보여주려면 FrameLayout라는 레이아웃안에 넣어 보여준다.

FrameLayout을 '액자'라고 생각하고 Fragment'사진'이라고 생각하면 쉽다.

 

'액자'역할을 해줄 위젯을 만든다. 뒤로가기시 Fragment화면의 동작의 유연함도 고려해야하기 때문에,

'PopScope'위젯으로 전체를 감싸준다.

그리고 FragmentIndexedStack위젯안에 위젯들을 쌓는 형식으로 표현한다.

@override
void initState() {
  super.initState();
  
  container.add(
    SomethingOneWidget()
  );
}

 

 

container리스트 안에 1개이하로 있을때는 PopScope가 정상적으로 동작하고,

2개 이상이 있다는건 Fragment처럼 사용된 위젯들이 IndexedStack안에 쌓여있기 떄문에, 직접 뒤로가기 설정을 해준다.

@override
Widget build(BuildContext context) {
  return PopScope(
    canPop: container.length <= 1,
    onPopInvokedWithResult: (didPop, result) {
      if (!didPop) {
        onBackPressed();
      }
    }
    
    child: ...
  );
}

void onBackPressed() {
  if (container.length > 1) {
    setState(() {
      container.removeLast();
    });
  }
}

 

 

PopScope의 child파라메터 설정

  PopScope(
    ...
    
    child: IndexedStack(
      index: container.length - 1,
      children: container.map((page) {
        return Navigator(
          onGenerateRoute: (settings) {
            return MaterialPageRoute(builder: (context) => page);
          }
        );
      }).toList(),
    )
  );

 

 

 

FirebaseCore패키지를 추가해준다.

flutter pub add firebase_core

 

+ Recent posts