Flutter

2023년 9월 8일 수정

이 글은 Flutter의 간단한 설명 및 관련된 글들을 정리한다.

Flutter

Flutter(플러터)는 Dart라는 한 가지 언어로 iOS, macOS, Android, Web 등 다양한 플랫폼 용 앱을 하나의 코드로 개발하기 위한 UI 툴킷 겸 프레임워크다.

작은 주제 모음

Flutter Channels

안정 버전을 쓰거나 개발 버전 테스트를 할 때 SDK 스위칭을 쉽게 하기 위해 채널 기능이 제공된다.

flutter channel

위의 명령으로 채널 목록을 얻어올 수 있으며 워 명령 뒤에 채널 이름을 붙이면 해당 채널로 스위칭이 된다.

flutter channel beta

위 명령은 베타 채널로 변경시킨다.

채널을 바꾸면 상황에 따라 업그레이드가 필요할 수도 있다.

flutter upgrade

Flutter SDK 다운그레이드

특정 버전을 쓰고 싶다거나 최신 버전에 문제가 있어서 다운그레이드를 할 때를 위해 downgrade 명령이 지원된다.

flutter downgrade xx.yy.zz

뒤의 xx.yy.zz 는 버전이다. 다만 꼭 해당 버전으로 변하는 것은 아닌 것 같고 상황에 따라 알아서 해당 버전과 가까운 버전을 골라주는 것 같다.

Flutter 개발 관련 작은 팁들

잠시 멈추기(Sleep 혹은 Delay)

await Future.delayed(const Duration(seconds: 3));

.delayed() 의 두 번째 파라미터로 핸들러도 구현할 수 있으니 참고하자.

동기 코드라면 sleep() 을 쓸 수도 있다.

import 'dart:io';

sleep(Duration(seconds:3));

디버그 혹은 릴리즈 모드 확인

import foundation;
...
if (kReleaseMode) {
  ...
} else if (kDebugMode) {
  ...
}

Flutter Widgets 개인적인 메모

Padding

EdgeInsets.only(top: 16, bottom: 16, left: 32, right: 32)
EdgeInsets.symmetric(horizontal: 16.0, vertical: 16.0)
EdgeInsets.symmetric(horizontal: 16)

FittedBox

Scales and positions its child within itself according to fit.

FittedBox(
  alignment: Alignment.center,
  fit: BoxFit.contain,
  child: MyWidget(),
)

Conditional, ConditionalSwitch (flutter_conditional_rendering)

if - else pattern:

Conditional.single(
  context: context,
  conditionBuilder: (BuildContext context) => someCondition == true,
  widgetBuilder: (BuildContext context) => Text('The condition is true!'),
  fallbackBuilder: (BuildContext context) => Text('The condition is false!'),
),

switch-case pattern:

ConditionalSwitch.single<String>(
  context: context,
  valueBuilder: (BuildContext context) => 'A',
  caseBuilders: {
    'A': (BuildContext context) => Text('The value is A!'),
    'B': (BuildContext context) => Text('The value is B!'),
  },
  fallbackBuilder: (BuildContext context) => Text('None of the cases matched!'),
),

문제 해결

macOS에서 개발자 인증 문제

Catalina 등 최신 macOS에서 flutter CLI 도구를 사용하는 중 이런 오류가 나면서 커맨드가 동작하지 않는 경우가 있다.

Flutter "idevice_id" cannot be opened because the developer cannot be verified

위의 예는 idevice_id 를 실행시켜서 발생한 메시지고, 이 외에 여러 커맨드에서 이런 오류가 발생할 수 있다.

이 오류는 아래와 같은 커맨드로 해결할 수 있다.

sudo xaddr -d /flutter_path/bin/cache/artifacts/libimobiledevice/idevice_id

이런 식으로 문제되는 커맨드의 개발자 사인 체크를 해제할 수 있다. 문제가 되는 커맨드 전부 이 명령을 실행시켜 주면 문제를 해결할 수 있다. 물론 보안 장치를 해제하는 명령이기 때문에 믿을 수 있는 커맨드에만 사용하자.

가장 좋은 해결 방법은 구글 Flutter 개발팀이 애플의 인증을 받는 건데 왜 안 할까?

프레임워크 iOS 아키텍처 오류

run 커맨드로 실행 시 여러 iOS 플랫폼 용으로 빌드를 하다 보면 이상하게 아래와 같은 오류가 나면서 빌드가 실패하는 케이스를 수 차례 겪었다.

error: Building for iOS Simulator, but the linked and embedded framework 'App.framework' was built for iOS. (in target 'Runner' from project 'Runner')

원인은 에러 대로 해당 프레임워크가 필요한 아키텍처 지원이 빠진 채로 빌드 되었다는 어처구니 없는 오류인데 아직 자동으로 해결하는 방법은 모르겠다.

수작업으로 해결하려면 위의 문제의 프레임워크를 그냥 지워버리면 된다.

rm -rf ios/Flutter/App.framework

이후 다시 run 시켜보면 문제는 해결된다.

참고로 문제가 발생하는 프레임워크는 App.framework 뿐만 아니라 다양하다. 사용하는 모듈에 따라 다를 수 있으니 그 경우에도 비슷하게 대처하자.

현재는 이 버그는 해결된 것 같아서 신경쓰지 않아도 될 것 같다.

Dart DevTools exited with code 255

어느날 vscode를 이용해 flutter 프로젝트를 열었는데 이런 오류가 갑자기 발생했다. 정확한 원인은 모르겠으나 아래 조치로 해결이 가능했다.

일단 flutter를 최신 버전으로 업그레이드 한다. 이미 최신 버전이라면 생략해도 된다.

flutter upgrade

다음 devtools를 활성화시킨다.

pub global activate devtools

만약 이미 activate된 상태라면 친절하게 알려주니 위 커맨드에서 activate 대신 deactivate 로 비활성화 한 다음에 다시 activate 를 시도해보자.

이후 devtools가 빌드되었고 vscode를 실행시키니 문제가 사라졌다.