반응형

FlutterFire는 Flutter 앱으로 Firebase를 연동하는 Flutter 플러그인 세트 입니다. 기본은 macos 개발을 위한 정보 확인 중에 찾은 자료라서 플랫폼 별로 모두 설정 확인을 하도록 해보겠습니다.

주의) 1주일 가까이 firebase와 씨름을 한 거 같습니다. 상황이 m1 맥미니를 구입한지 얼마 안되었고, flutter 2.0에 깜짝 발표된 뒤라, 먼가 정리되지 않은 상태에서 버전 이슈라고만 생각을 했었는데... ㅠ,.ㅠ

더보기

기본 시스템 환경

Mac Mini 2020 M1 (8core CPU, 8core GPU, 8GB Ram), macOS Big Sur 11.2.2

Flutter 2.0.2 / Dart 2.12.12 / CocoaPods 1.10.1
Android Studio 4.1.2
Xcode 12.4

설치

firebase 사이트는 iOS, android, Web 앱 설정만 있습니다. 저는 Flutter로 데스크탑 앱을 만들고 있는 중이라, 저의 개인적인 요구에 따라서 macOS 연동을 목표로 정리를 합니다. 하지만 iOS와 설정이 거의 동일하기 때문에 되도록 같이 설명을 하겠습니다.

로컬 머신에서 flutter 프로젝트를 생성하고, Firebase Console에 프로젝트 생성 혹은 기존 프로젝트에서 앱 추가를 합니다.

Cloud Firestore 앱 추가

iOS 앱 추가 - macos 와 공통으로 사용해야할 앱

iOS 번들 ID 확인 (혹시 이미 만들어 놓은 프로젝트에서 번들 ID를 모르신다면 참조하세요)

os(macos)/Runner.xcworkspace 프로젝트를 Xcode로 열고, 최상단 Runner 선택 후 General 탭 > Identity 영역 > Bundle Identifier 항목 확인.

Android Studio 에서 프로젝트 생성을 할때, Project Name을 입력한 다음 페이지에 Package name이 번들 ID 입니다. flutter create [project]로 직접 생성했다면, com.example.project가 기본 번들ID로 생성됩니다.

iOS/macOS 설정 및 소스 일부 변경 (Xcode 활용)

구성 파일 다운로드

GoogleService-Info.plist 파일 다운로드 및 Xcode에 추가

Runner 선택 및 오른쪽 버튼 클릭 > Add Files to "Runner" 클릭 > (Copy items if needed 옵션 선택) > GoogleService-Info.plist 선택 추 (* Runner 폴더 밑으로 추가를 해주셔야 합니다)

Firebase Emulator Suite 사용 설정

Firebase Emulator Suite는 빠르고 복잡하지 않은 설정을 지원하기 위해서 암호화 되지 않은 네트워킹 연결을 사용합니다. macOS는 기본으로 암호회된 네트워킹 연결을 요구합니다. 로컬 머신에서 개발하는 동안 Firebase Emulator Suite를 사용하려면, 작업 중인 macOS 앱에 보안이 되지 않는 로컬 네트워크 서비스에 연결하도록 허용해야 합니다.

ios(macos)/Runnder/Info.plist 에 아래 설정을 추가합니다.

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsLocalNetworking</key>
    <true/>
</dict>

Deployment Target 변경

iOS 9.0 > 10.0, macOS 10.11 > 10.12

# macos/Podfile
platform :osx, '10.12'

# ios/Podfile
platform :ios, '10.0'

AppDelegate.swift

# 추가 코드
import Firebase

FirebaseApp.configure()
    
# 적용 예
import Cocoa
import FlutterMacOS
import Firebase

@NSApplicationMain
class AppDelegate: FlutterAppDelegate {
  override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
    FirebaseApp.configure()
    return true
  }
}

iOS/ macOS 빌드 시간 개선 (Podfile 변경)

현재 Firebase iOS SDK는 Xcode로 빌드시 5분 이상 걸릴 수 있는 약 500k 줄 짜리 c++ 코드에 의존하고 있습니다. 빌드 시간을 크게 단축하기 위해서, ios/Podfile에 1줄을 추가해 프리컴파일된 버전을 사용하도록 합니다.

# ios(macos) /Podfile 추가
pod 'FirebaseFirestore', :git => 'https://github.com/invertase/firestore-ios-sdk-frameworks.git', :tag => '6.26.0'

// 추가 위치
# ...
target 'Runner' do
  pod 'FirebaseFirestore', :git => 'https://github.com/invertase/firestore-ios-sdk-frameworks.git', :tag => $FirebaseSDKVersion
# ...
end

FirebaseSDKVersion 변수는 아래 Native SDK 버전 정의를 참조하세요.

추가로 cocoapods를 1.9.1 이나 그 이상 버전으로 업그레이드 힙니다. gem install cocoapods
(참조 : https://github.com/FirebaseExtended/flutterfire/issues/2751)

저의 경우에는 2021-03-13 현재, 1.10.1로 업그레이드가 되었습니다.

Native SDK 버전 재정의

최상단 platform 정의 바로 밑에 추가해주세요.

# ios(macos)/Podfile

# Override Firebase SDK Version
$FirebaseSDKVersion = '6.33.0'

pod install 실행

실행 테스트

오류 팁

 % flutter run -d macos
Changing current working directory to: /Volumes/Data/Study/flutter/nativeappmaker
Launching lib/main.dart on macOS in debug mode...
Running pod install...                                           1,775ms
In file included from /Users/websniper/Development/flutter/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.16.0+1/macos/Classes/FLTFirebaseFirestorePlugin.m:9:
/Users/websniper/Development/flutter/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.16.0+1/macos/Classes/Private/FLTFirebaseFirestoreUtils.h:42:4: error: expected a type
+ (FIRFirestoreSource)FIRFirestoreSourceFromArguments:(NSDictionary *_Nonnull)arguments;
   ^                                                                    

FirebaseSDKVersion = '7.4.0'

참조 사이트 : firebase.flutter.dev/docs/overview/

 

 

 

반응형
블로그 이미지

센스쟁이 프로그래머 비트센스

뷰파인더로 보는 프로그래머의 세상 페이스북 @bitsense 트위터 @picory 스카이프 picory MSN drawhalf@dreamwiz.com

댓글을 달아 주세요

반응형

하나의 StatefulWidget에서 상태 값을 관리하는 방법은 setState()를 사용하는 것입니다. setState() 없이 상태 값을 관리할 수도 있는데, ValueNotifier를 사용하는 것입니다. ValueNotifier가 좋은 것은 다른 위젯에서 변경한 상태값을 적용할 수 있습니다.

setState() 없이 상태값을 변경하는 예제

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final ValueNotifier<int> _counter = ValueNotifier<int>(0); // ValueNotifier 변수 선언
  final Widget goodJob = const Text('Good job!');
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title)
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text('You have pushed the button this many times:'),
            ValueListenableBuilder(
              valueListenable: _counter, // 사용할 변수를 지정. _counter가 변경 되면 자동 호출
              builder: (BuildContext context, int value, Widget? child) {
                // value = _counter 로 적용
                return Row(
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  children: <Widget>[
                    Text('$value'),
                    child!, // child는 아래 지정된 위젯으로 치환됨
                  ],
                );
              },
              child: goodJob,
            )
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.plus_one),
        onPressed: () => _counter.value += 1, // _counter.value 값이 수정되면 자동 호출
      ),
    );
  }
}

ValueNotifier로 수정한 값을 다른 위젯에서도 사용하고 싶을때

ValueNotifier가 영향을 미치는 범위는 ValueListenableBuilder() 내 입니다. 전체 위젯에 값을 적용하기 위해서는 setState()를 사용해야 하나 그럴 경우 오류가 발생합니다. build가 완료되기 전에 setState()를 호출하게 되면 빨간 화면을 마주하게 됩니다.

이 오류를 피하면서 setState()를 사용하는 방법은 WidgetsBinding.instance.addPostFrameCallback() 입니다.

addPostFrameCallback()는 페이지 빌드 후에 비동기로 콜백함수를 호출하기 때문에 빨간 화면을 피할 수 없습니다.

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final ValueNotifier<int> _counter = ValueNotifier<int>(0); // ValueNotifier 변수 선언
  final Widget goodJob = const Text('Good job!');
  
  int _count = 0;
  
  void setCount(int counter) {
    setState(() {
      _count = counter + 1;
    });
  }
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title)
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text('You have pushed the button this many times:'),
            ValueListenableBuilder(
              valueListenable: _counter, // 사용할 변수를 지정. _counter가 변경 되면 자동 호출
              builder: (BuildContext context, int value, Widget? child) {
                // setState() 가 있는 함수를 호출
                WidgetsBinding.instance.addPostFrameCallback((_) {
                  setCount(value);
                });
                
                // value = _counter 로 적용
                return Row(
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  children: <Widget>[
                    Text('$value'),
                    child!, // child는 아래 지정된 위젯으로 치환됨
                  ],
                );
              },
              child: goodJob,
            ),
            Container(
              child: Text('$_count')
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.plus_one),
        onPressed: () => _counter.value += 1, // _counter.value 값이 수정되면 자동 호출
      ),
    );
  }
}
반응형
블로그 이미지

센스쟁이 프로그래머 비트센스

뷰파인더로 보는 프로그래머의 세상 페이스북 @bitsense 트위터 @picory 스카이프 picory MSN drawhalf@dreamwiz.com

댓글을 달아 주세요

반응형
logo

Xamarin.Forms가 아쉬운 것이 여러가지 있지만, 디자인 결과를 보기 위해서 매번 컴파일 해야 한다는 것입니다. 그걸 해결해줄 녀석이 하나 있네요. 아직 베타버전이기는 하지만 고릴라 플레이어 입니다.


고릴라 플레이어 사이트

고릴라 플레이어 다운로드 페이지







이녀석을 사용하는 데 꽤나 애를 먹었습니다. 난독증이 있는지, 이해력이 떨어지는지... ㅠ,.ㅠ;; 한참 헤매다가 겨우 알아 먹었습니다.


사용방법


시뮬레이터에 고릴라 플레이어 설치


1. 고릴라 플레이어를 설치하면 "Gorilla Player by UXDivers" 창이 뜹니다. 없다면 트레이 아이콘에서 "Getting Started Walkthrough"를 선택하여 실행합니다.



2. 두번째 탭(2-Installing Gorilla Player on your devices)에서 [Opening Player.sln...](빨간색 버튼)을 선택하여 솔루션 소스를 오픈 합니다.


3. 소스가 로드 되었다면 그대로 다시 컴파일을 합니다. 그러면 시뮬레이터에 설치가 되겠죠?? Gorillar 라는 앱이 설치 됩니다.


이제 기본적인 준비는 끝났습니다. 저도 이제부터 어떻게 하는지 헤깔렸습니다.


작업 중인 프로젝트를 열거나 새로 프로젝트를 만들어서 Xamarin Studio를 실행합니다.


시뮬레이터에서 고릴라 플레이어 사용 방법


1. 도구 > Gorilla Player > Connect to Gorilla 를 선택합니다. 별다른 반응은 없습니다.


2. Xamarin.Forms 파일을 추가 합니다. 추가한 xaml 파일에서 오른쪽 버튼으로 메뉴를 오픈합니다. Stick Gorilla to this를 선택합니다.


3. 먼저 앱을 컴파일해서 시뮬레이터를 실행합니다. 이게 먼가 싶죠? 저도 여기서 헤맸습니다. 앱이 실행이 되면 앱을 종료합니다.


4. 시뮬레이터에서 조금 전에 설치한 Gorilla 앱을 실행합니다. 자동으로 현재 앱에 연결되어 선택된 페이지가 로딩됩니다.


5. 이제 xaml 파일을 수정하고 저장해 봅니다. 다른 파일도 추가해서 Stick Gorilla to this로 랜더링할 페이지를 변경해 봅니다.


잘 되나요? ^^


[추가]

아직 문제점은 있습니다.

페이지를 삽입하는 경우 인식을 못하고 오류를 냅니다. 예로들면 MasterDetailPage에서 master나 detail에 다른 페이지를 요청하면 오류가 납니다. 아주 붉게~

하지만 단일 페이피지 랜더링은 잘됩니다. 제가 아직 쪼랩이라서 그렇겠지요~!!


컴파일 시간이 보통 1분 이내로 끝나긴 하지만 디자인 하나를 보기 위해서 여러번 컴파일을 하다보면 시간적인 낭비가 상당합니다. 이부분에 있어서 높이 평가해 주고 싶네요~~ ^^

반응형
블로그 이미지

센스쟁이 프로그래머 비트센스

뷰파인더로 보는 프로그래머의 세상 페이스북 @bitsense 트위터 @picory 스카이프 picory MSN drawhalf@dreamwiz.com

댓글을 달아 주세요

반응형
logo

c#을 잘 모릅니다. 그래도 몇년 전에 사 놓은 책이 몇 권 책장을 차지하고 있네요. 안봐서 문제겠지만요. xamarin도 익히 들었지만 솔직히 잘 모릅니다. 모바일 개발에 적용해 보려고, 그동안 해보고 싶었지만 월 $25의 가격정책은 높은 벽으로 넘기 어렵웠습니다. "공부하려고 하는데 돈을 내야 하다니..." 게다가 이래 저래 치여서 살다보니 짬이 안나는 시간도 문제였습니다. 머... 다들 그러시잖아요?? ㅠ,.ㅠ;;

그러다 얼마 전 MS가 xamarin을 인수하고, 감사하게도 무료로 풀었다는 반가운 소리에, 다시 힘을 얻어서 이것 저것 만져 본지도 벌써 석달이 되어 갑니다. 공부할 짬을 낼 수 없는 현실이 문제라고 하소연을 해 보지만... 역시 아무 것도 모르는 초보자에게 새로운 언어와 툴은 장벽입니다.

게다가 영어로 된 가이드들은..., 분명 자기네들 끼리는 쉽다고 만든 거 같은데... 어렵게만 느껴지는 이 기분은... ㅠ,.ㅠ;; 꼭 무슨 시험보는 듯한... 어흑... xamarin 열풍?이라고 하는데, 정작 국내 사이트 중에서 xamarin 강좌를 본격적으로 하는 곳도 없고, 실제 번역본이나 한글 개발서적이 거의 전무한 상태다 보니 의지할 곳이 없어서 더 힘든 것 같습니다.

2016년 5월 9일 현재 인터넷 서점에는 Xamarin 관련 서적이 거의 없네요.

그래서 허접한 내용이라도 공유를 해보고자 합니다. 제가 먼가를 만드는 것은 어렵고, 그러니 가장 최근 xamarin 서적인 "Creating Mobile App With Xamarin.Forms"[링크]Xamarin 공식 Blog 사이트[링크]에 소개된 샘플 소스들을 중심으로 분석한 내용을, 혹시 저처럼 맨땅에 헤딩하는 듯한 느낌으로 검색창을 두드려 보는 초보자님에게 공유해 보려고 합니다. 제가 c#도, xamarin도 잘 모릅니다. 모바일 용어들은 더더군다나 모릅니다. 영어도.. 무지... 한.. 켁...

대부분은 구글과 네이버를 기초한 단어 직역?과 체험을 근거로한 추측성 멘트? (이런 거 같다. 내가 해보니 이렇드라..) 가 위주가 될 것입니다. 머 그게 불만이시라면, 정확한 용어를 알려 주세요. 마음을 다해 감사하겠습니다. ^^;; 여튼, 몇개 분석한 내용을 중심으로 해서 지속적으로 만들어 보도록 하겠습니다.

참고로 해당 내용은 되도록 개별적인 스터디 모임에서 활용하기 위한 내용이기도 합니다.

현재까지 분석된 내용에 대해서 말씀을 드리면

1. ZXing 모듈을 이용한 바코드 스캐너
2. Xamarin.Facebook을 이용한 페이스북 로그인
3. Json 파서를 활용한 데이터 바인딩
4. 기타 등등 디자인 관련 자질구레한 용어 및 몇가지 트러블 슈팅 ??

음... 머 한게 없네.. 이런... =_=;;

반응형
블로그 이미지

센스쟁이 프로그래머 비트센스

뷰파인더로 보는 프로그래머의 세상 페이스북 @bitsense 트위터 @picory 스카이프 picory MSN drawhalf@dreamwiz.com

댓글을 달아 주세요

반응형

WWDC 2012에서 iOS 6를 발표하고, 많은 분들이 iOS6가 언제 나오나 궁금할 것으로 보입니다.

애플 개발자센터에는 아래 그림처럼 SDK beta 버전 배포를 준비 중이네요.

무척 기대스럽네요..


반응형
블로그 이미지

센스쟁이 프로그래머 비트센스

뷰파인더로 보는 프로그래머의 세상 페이스북 @bitsense 트위터 @picory 스카이프 picory MSN drawhalf@dreamwiz.com

댓글을 달아 주세요