반응형
반응형

https://apps.apple.com/us/app/otter-transcribe-voice-notes/id1276437113

 

‎Otter: Transcribe Voice Notes

‎OtterPilot™ your meetings with AI. Get a meeting assistant that records audio, writes notes, automatically captures slides, and generates summaries. Otter transcribes all your meetings, interviews, lectures, and everyday voice conversations in real ti

apps.apple.com

Zoom, Google Meet, Microsoft Teams 등을 위한 자동 회의 메모. 집에서 일할 때 연결 상태를 유지하고 협업하세요.

OtterPilot™ AI와의 회의. 오디오를 녹음하고, 메모를 작성하고, 슬라이드를 자동으로 캡처하고, 요약을 생성하는 회의 도우미를 받으세요.

 

Otter는 모든 회의, 인터뷰, 강의 및 일상적인 음성 대화를 실시간으로 기록하므로 토론에 집중할 수 있습니다. 대면, Zoom, Google Meet 및 Microsoft Teams에 대한 자동 메모를 받으세요. 모든 메모는 검색 및 공유가 가능합니다. Otter.ai는 웹에서도 사용할 수 있습니다. 영어만 가능합니다.

 

많은 용도

• 회의 메모를 자동으로 작성하고 팀원과 공유하여 모두 동기화 상태 유지

• 인터뷰, 강의, 팟캐스트, 비디오, 웨비나, 기조연설을 녹음하고 필사합니다.

• 청각 장애인 커뮤니티, ESL 학습자 및 접근성이 필요한 모든 사람에게 실시간 자막 제공

 

실시간 녹음 및 전사

• 위젯과 바로가기를 사용하여 탭 한 번으로 즉시 녹음

• 높은 정확도로 실시간(온라인일 때) 기록

• 나중에 검토할 핵심 사항 강조표시

• 화이트보드 토론, 슬라이드 등의 사진을 삽입합니다.

• 내장 마이크 또는 블루투스 장치를 통해 오디오 입력

 

AI로 메모 강화

• 단락을 자동으로 구두점, 대문자 및 구분

• 화자 식별(일부 교육 후)

• 워드 클라우드 및 요약 키워드를 생성합니다. 단어를 탭하면 말한 곳으로 이동합니다.

• 가상 회의 중 자동화된 슬라이드 캡처

• 모든 회의 후 자동 요약

 

공유 및 협업

• 그룹 내에서 녹음을 시작하여 대본을 실시간으로 공유

• 그룹 구성원을 초대하여 함께 보고 편집하고 강조 표시합니다. 모든 하이라이트는 Takeaways 패널에서 캡처됩니다.

• 요점 패널 내에서 의견을 추가하고 작업 항목을 할당합니다.

• 링크를 통해 외부에 공유

 

검색 및 재생

• 전체 오디오를 스크러빙할 필요가 없도록 텍스트 검색

• 조정 가능한 속도로 재생

• 오디오가 재생되는 동안 강조 표시된 단어를 따라가세요.

• 단어를 탭하면 오디오가 해당 지점으로 이동합니다.

 

편집 및 강조 표시

• 텍스트를 편집하여 오류를 수정하십시오.

• 화자에게 태그를 지정하여 단락에 라벨을 지정하고 Otter가 화자를 식별하도록 교육

• 탭 한 번으로 문장 강조 표시

 

구성 및 내보내기

• 대화를 개인 폴더로 정리

• 클립보드에 복사하거나 다른 앱에 직접 공유

• PDF, TXT, SRT, MP3로 내보내기

 

가져오기 및 동기화

• 오디오 및 비디오 파일 가져오기

• Zoom 계정을 동기화하여 클라우드 녹음 기록

• 다른 통화 녹음 앱에서 업로드

• 캘린더를 동기화하여 회의를 기록하고 메모에 자동 제목을 지정하도록 알림

• 간편한 공유를 위해 연락처 가져오기

 

iOS에 최적화

• Siri 바로가기 및 홈 위젯으로 녹음 시작/중지

• AirPods를 통해 녹음

• iOS 캘린더, 연락처 및 카메라와 동기화

• 3D Touch로 대화 미리보기

• 얼굴/터치 ID로 잠금

• AirPrint를 통한 인쇄

• Dynamic Type으로 글꼴 크기 조정

 

수달 프로

• 재생 속도 향상 및 무음 건너뛰기

• 대량 내보내기

• 월별 청구를 선택하거나 연간 청구로 크게 절약

• 결제는 구매 확인 시 iTunes 계정으로 청구됩니다.

• 현재 기간이 종료되기 최소 24시간 전에 자동 갱신을 해제하지 않으면 구독이 자동으로 갱신됩니다.

• 현재 기간이 끝나기 24시간 이내에 계정에 갱신 비용이 청구됩니다.

• 설정에서 구독을 관리할 수 있으며 구매 후 계정 설정으로 이동하여 자동 갱신을 끌 수 있습니다.

• 무료 평가판 기간 중 미사용 부분은 제공되는 경우 구독 구매 시 자격이 상실됩니다.

"Otter.ai는 기록된 생각을 글로 옮기는 보석입니다" - Forbes 2023

"2019년 우리가 사랑하는 앱" – App Store

"2018년 최고의 앱 7개" – Mashable

"2018년 최고의 신규 앱 25개" – Fast Company

 

우리는 보안과 프라이버시를 중요하게 생각합니다. 귀하의 데이터는 기밀이며 제3자에게 전송되지 않습니다. 귀하는 귀하의 계정에서 귀하의 데이터를 삭제할 수 있는 모든 권한이 있습니다.

 

도움이 필요하다? 도움말 센터를 확인하세요: https://help.otter.ai

 

서비스 약관: https://otter.ai/terms-of-service

개인 정보 보호 정책: https://otter.ai/privacy-policy  

 

Automated meeting notes for Zoom, Google Meet, Microsoft Teams, and more. Stay connected and collaborative when you work from home.

OtterPilot™ your meetings with AI. Get a meeting assistant that records audio, writes notes, automatically captures slides, and generates summaries.

 

Otter transcribes all your meetings, interviews, lectures, and everyday voice conversations in real time, so you can focus on the discussion. Get automated notes for: in-person, Zoom, Google Meet, and Microsoft Teams. All notes are searchable, and shareable. Otter.ai is also available on the web. English only.

 

Many Uses

• Take meeting notes automatically, and share with teammates to keep everyone in sync

• Record and transcribe interviews, lectures, podcasts, videos, webinars, keynotes

• Provide live captioning to the deaf and hard-of-hearing communities, ESL learners, and anyone with accessibility needs

 

Record & Transcribe Live

• Record instantly in one tap, with widget and shortcut too

• Transcribe in real time (when online) with high accuracy

• Highlight the key points to review later

• Insert photos of whiteboard discussions, slides, etc.

• Input audio via built-in mic or Bluetooth device

 

Enrich Notes with AI

• Punctuate, capitalize, and break paragraphs automatically

• Identify speakers (after some training)

• Generate word clouds and summary keywords; tap on a word to jump to where it was said

• Automated Slide Capture during virtual meetings

• Automated Summary after all meetings

 

Share & Collaborate

• Start a recording inside a group to share the transcript live

• Invite group members to view, edit, and highlight collaboratively. All highlights will be captured in the Takeaways panel.

• Within the Takeaways panel, add comments and assign action items

• Share externally via links

 

Search & Playback

• Search the text so you don't have to scrub through the whole audio

• Playback at adjustable speeds

• Follow along the highlighted word as the audio is playing

• Tap on any word to jump the audio to that spot

 

Edit & Highlight

• Edit the text to correct any errors

• Tag the speakers to label the paragraphs and train Otter to identify speakers too

• Highlight sentences in one tap

 

Organize & Export

• Organize conversations into personal folders

• Copy to clipboard, or share directly to other apps

• Export as PDF, TXT, SRT, MP3

 

Import & Sync

• Import audio and video files

• Sync your Zoom account to transcribe cloud recordings

• Upload from other call recording apps

• Sync your calendars to be reminded to record your meetings and auto-title your notes

• Import your contacts for easy sharing

 

Optimized for iOS

• Start/Stop recording with Siri Shortcut & home widget

• Record via AirPods

• Sync with iOS Calendar, Contacts & Camera

• Preview conversations with 3D Touch

• Lock with Face/Touch ID

• Print via AirPrint

• Adjust font size with Dynamic Type

 

Otter Pro

• More playback speeds and skip silence

• Bulk export

• Choose either monthly billing or save big with yearly billing

• Payment will be charged to your iTunes Account at confirmation of purchase

• Subscription automatically renews unless auto-renew is turned off at least 24-hours before the end of the current period

• Account will be charged for renewal within 24-hours prior to the end of the current period

• You can manage your subscriptions in Settings and auto-renewal may be turned off by going to your Account Settings after purchase

• Any unused portion of a free trial period, if offered, will be forfeited when you purchase a subscription

“Otter.ai Is A Gem For Transcribing Your Recorded Thoughts Into Writing” - Forbes 2023

"Apps We Love 2019" – App Store

"7 Best Apps of 2018" – Mashable

"25 Best New Apps of 2018" – Fast Company

 

We take security and privacy seriously. Your data is confidential and will not be transferred to third parties. You have full control to delete your data from your account.

 

Need help? Check out our Help Center: https://help.otter.ai

 

Terms of Service: https://otter.ai/terms-of-service

Privacy Policy: https://otter.ai/privacy-policy

반응형

'프로그래밍 > App' 카테고리의 다른 글

Flutter and Clean Architecture(I)  (0) 2023.08.29
[Flutter] Flutter vs React Native  (0) 2023.08.11
[Flutter] What is Flutter Impeller?  (0) 2023.08.03
What’s new in Flutter 3.10  (0) 2023.08.03
Flutter Web in 2023 — is it good for you?  (0) 2023.07.14
반응형

멀쩡한 앱을 Flutter 앱으로 다시 짠 이유 - 일본 1위 배달 앱, 두 번째 Recode

https://engineering.linecorp.com/ko/blog/demaecan-2nd-recode-kmm-to-flutter

 

멀쩡한 앱을 Flutter 앱으로 다시 짠 이유 - 일본 1위 배달 앱, 두 번째 Recode

안녕하세요, LINE+ ABC Studio에서 앱을 개발하고 있는 김종식, 남상혁입니다. 저희 팀은 현재 일본에서 운영하는 배달 서비스 '데마에칸(Demaecan, 出前館)' 프로덕트를 개발하고 있습니다. '데마에칸(

engineering.linecorp.com

Flutter를 선택한 이유

데마에칸 서비스는 고유한 디자인으로 개발됐기 때문에 모바일 개발자 모두가 공통 UI 코드까지 작성할 수 있는 기술을 고민했습니다. 모바일 멀티 플랫폼 기술 중 온전히 앱 개발이 가능한 기술로는 대표적으로 RN과 Flutter가 있습니다.

Google Trends - Flutter vs React Native(in Japan) 

그 중 두 번째 Recode를 위한 기술로 Flutter를 선택한 이유는 다음과 같습니다.

  • Flutter는 최근 모바일 앱뿐 아니라 PC와 웹 개발도 가능하게 돼 플랫폼 확장성을 확보할 수 있었고, 기술 공개 후 빠르게 발전하고 있어서 필요한 정보를 보다 수월하게 획득할 수 있을 것이라고 판단했습니다.
  • 공통 코드로 UI를 구성할 수 있으며 자유도가 높았습니다. 특히 KMM 개발 당시 Android Compose UI 개발 만족도가 높았던 터라 선언형 UI 패러다임으로 완전히 전환하고자 했던 저희 목적에 부합했습니다.
  • 네이티브 대비 성능 부분에서 위험성이 낮았고, 네이티브 기능을 개발할 때는 MethodChannel을 활용하면 크게 제약 받는 부분이 없었습니다.
  • 통합 개발 환경(IDE) 부분에서 팀 원 모두에게 익숙한 Android Studio를 활용할 수 있었습니다(참고). 


Flutter로 다시 갈아엎자 ㅆ (←웃는 눈 모양입니다)

Flutter는 Dart 언어를 사용합니다. 따라서 Dart 언어에 익숙해지지 못하면 Flutter로 제대로 개발할 수 없습니다. 이때 Dart tour 문서를 참고하면 언어 특징을 빠르게 훑어보기 좋습니다. Dart 언어의 상세한 부분까지 잘 소개한 문서입니다. Dart 언어를 개략적으로 이해한 후에 Flutter Codelab 페이지를 읽어보면 Flutter를 보다 쉽게 이해할 수 있습니다.

Recode는 Dart 언어를 익히고 Flutter에 익숙해지는 것으로 시작해서 시작부터 출시까지 약 3개월 정도 진행했습니다. 제한된 기간 내에 1.0과 3.0 모드를 모두 제공해야 했으므로 공식 문서를 보며 Dart와 Flutter를 학습하면서 동시에 스펙 - 뷰 상태 - 로직을 잘 분리해 나가며 학습과 개발을 동시에 진행했습니다. Recode 시작 당시에는 Flutter SDK 3.0.2이었고, 출시할 즈음에는 Flutter SDK 3.0.5로 개발했습니다.

Flutter는 선언형 UI 개발을 하기 때문에 가장 큰 고민 거리는 UI 상태 관리입니다. 상태 관리와 관련해서 provider bloc, getx 등의 패키지가 있는데요. 처음 Recode를 시작할 때 패키지 학습 비용 및 패키지 의존성으로 인한 부담 때문에 직접 구현하는 형태로 진행했습니다. 상태 변경을 위해서 ChangeNotifier를 활용했고, 상태 집단은 StateModel로 관리했습니다. 제품 개발에 반드시 필요한 패키지(예를 들어 FlutterFire, google_maps_flutter 등)가 아니라면 가급적 직접 구현하는 것을 원칙으로 정했습니다.

 

KMM과 비교해 구현 난이도가 높았던 사례

Flutter로 갈아엎으면서 KMM과 비교해 구현 난이도가 높았던 부분도 있었습니다. 권한 획득이나 푸시 수신 시나리오 같은 경우 각 플랫폼에서 제안하는 개발 가이드라인에 차이가 있는데요. KMM 때는 네이티브 영역을 각각 구현해 코드 복잡도가 높지 않았는데 Flutter로 변환하면서 하나의 코드로 작성하다 보니 플랫폼에 따른 분기 코드가 종종 발생해서 코드 가독성을 저해하는 부분이 있었습니다. 아래는 Flutter로 변환한 후 Android와 iOS 앱 실행 후 흐름입니다. 

  • Android 앱 실행 흐름

  • iOS 앱 실행 흐름

플랫폼별로 SDK나 패키지 작동이 달랐던 사례

플랫폼별로 SDK나 패키지 작동이 기대와는 조금씩 달랐던 경우도 있었습니다. 예를 들어 앱 내 진동 효과를 발생시키는 코드를 플랫폼별로 다르게 구현해야 하는 경우입니다. Android는 Vibration 패키지에서 제공하는 인터페이스를, iOS에서는 Flutter SDK에서 제공하는 인터페이스를 사용하는 것이 요구 사항에 가장 적합하게 작동했습니다. 스펙에는 진동이 300ms, 500ms, 1000ms와 같은 방식으로 정의돼 있었는데 플랫폼별로 작동에 차이가 있어서 이를 구현할 때 분기가 필요했습니다. 

de_theme_effect.dart

void _vibrate300() async {
    if (PlatformUtils.isAndroid) {
        if (await Vibration.hasVibrator() == true) {
            Vibration.vibrate(duration: 300);
        }
    } else if (Platform.isIOS) {
        HapticFeedback.lightImpact();
    }
}
 
void _vibrate500() {
    /// implements
}
 
void _vibrate1000() {
    /// implements
}
Dart

위와 같은 코드는 Recode 출시 후 단계적으로 추상화하며 플랫폼별 구현체로 리팩토링하고 테스트 코드를 작성하면서 보다 가독성이 높고 유지 보수하기 좋은 형태로 변경하고 있습니다. 아래는 위 코드를 개선한 결과입니다.

de_theme_effect.dart

// The interface is reused.
void _vibrate300() => VibrationHelper.vibrate(VibrationEffect.effect300);

...

enum VibrationEffect { effect300, effect500, effect1000 }

class VibrationHelper {
	// vibration only support Android, iOS platform.
	static void vibrate(VibrationEffect effectType) {
		// Note) PlatformUtils also an abstract class of each platform implementations.
		if (PlatformUtils.isAndroid) {
			_vibrateAndroid(effectType);
	    } else if (PlatformUtils.isIOS) {
			_vibrateIOS(effectType);
    	} else {
			log('${effectType.name} vibrate fail, Unsupported platform type');
		}
	}

	static void _vibrateAndroid(VibrationEffect effectType) async {
    	// implementation as a vibration package.
		if (await Vibration.hasVibrator() == true) {
			switch (effectType) {
				case VibrationEffect.effect300:
					Vibration.vibrate(duration: 300);
				break;
				case VibrationEffect.effect500:
					Vibration.vibrate(duration: 500);
          		break;
		        case VibrationEffect.effect1000:
          			Vibration.vibrate(duration: 1000);
		        break;
			}
		}
	}

	static void _vibrateIOS(VibrationEffect effectType) {
		// implementation as a flutter(default) package.
		switch (effectType) {
			case VibrationEffect.effect300:
				HapticFeedback.lightImpact();
			break;
			case VibrationEffect.effect500:
				HapticFeedback.mediumImpact();
			break;
			case VibrationEffect.effect1000:
				HapticFeedback.heavyImpact();
			break;
		}
	}
}
Dart

트러블 슈팅 사례

두 번째 Recode 과정 중에 경험한 주요 트러블 슈팅 사례를 소개하겠습니다. 

Google 지도 관련 이슈

먼저 Google 지도와 관련해서 발생한 두 가지 이슈를 소개하겠습니다.

의존 관계 업데이트 후 사이드 이펙트로 앱 성능 저하

배송원 앱에서는 배송원 위치와 가맹점 위치, 고객 드위치를 지도 위에 마커로 표시합니다. 지도는 Google 지도(google_maps_flutter) 패키지를 사용하고 있고, Google 지도를 사용하기 위해 아래와 같이 pubspec.yaml에 Caret 문법를 활용해 의존 관계를 추가해 놓았습니다. 그런데 어느 순간 앱 성능이 급격히 저하되는 이슈가 발생했고, 확인 결과 google_map_flutter 버전이 올라가면서 각 플랫폼 구현체 의존 관계가 업데이트된 것을 확인할 수 있었습니다. 이슈 발생 전후 pubspec.lock을 비교해 보면 아래와 같습니다. 

정상 작동 시 pubspec.lock

google_maps_flutter:
  dependency: "direct main"
  description:
    name: google_maps_flutter
    url: "https://pub.dartlang.org"
  source: hosted
  version: "2.1.9"
google_maps_flutter_platform_interface:
  dependency: transitive
  description:
    name: google_maps_flutter_platform_interface
    url: "https://pub.dartlang.org"
  source: hosted
  version: "2.2.1"
YAML

성능 이슈 발생 후 pubspec.lock

google_maps_flutter:
  dependency: "direct main"
  description:
    name: google_maps_flutter
    url: "https://pub.dartlang.org"
  source: hosted
  version: "2.2.0"
google_maps_flutter_android:
  dependency: transitive
  description:
    name: google_maps_flutter_android
    url: "https://pub.dartlang.org"
  source: hosted
  version: "2.3.0"
google_maps_flutter_ios:
  dependency: transitive
  description:
    name: google_maps_flutter_ios
    url: "https://pub.dartlang.org"
  source: hosted
  version: "2.1.11"
google_maps_flutter_platform_interface:
  dependency: transitive
  description:
    name: google_maps_flutter_platform_interface
    url: "https://pub.dartlang.org"
  source: hosted
  version: "2.2.2"
YAML

이슈 발생 원인은 google_map_flutter가 2.2.0으로 버전이 올라가면서 google_map_flutter_android 패키지 의존 관계가 업데이트돼 발생한 사이드 이펙트였습니다. 이슈를 해결하기 위해 pubspec.yaml에 선언한 google_maps_flutter 패키지 버전을 caret 문법 대신 고정된 버전을 사용하는 것으로 수정했습니다. 

pubspec.yaml

# AS-IS: Performance degradation due to version-up
dependencies:
	google_maps_flutter: ^2.1.3 // It means '>=2.1.3 <3.0.0'

# TO-BE: Specify as fixed version
dependencies:
	google_maps_flutter: 2.1.9
YAML

네이티브 영역에서 크래시 발생

Google 지도와 관련해 발생한 또 한 가지 이슈가 있습니다. 출시 후 Android 버전에서 crash-free(* 특정 기간 동안 비정상 종료가 발생하지 않은 사용자 비율)가 약 96~97%로 불안정한 상태가 지속됐습니다. Crashlytics 로그에서는 ByteBuffer나 Thread 등 네이티브 영역에서 크래시가 발생한 것으로 나타나 정확한 원인을 파악하기 힘든 상황이었는데요. 크래시 발생 시 생성된 로그를 분석한 결과 강제 로그아웃이 발생해 로그인 화면으로 전환될 때 이런 상황이 발생하는 것을 확인할 수 있었습니다. 배송원 앱은 로그인에 성공하면 Google 지도를 화면에 표시하는데 이때 화면 전환 등으로 지도가 표시되는 화면이 사라질 때 크래시가 발생하는 것으로 예상됐습니다.

이 이슈는 Google MapView의 Rendering 옵션을 LATEST로 사용하면 해결할 수 있는 것으로 알려져 있었습니다(참고). 이를 참고해서 Android 네이티브 소스 코드를 수정해 crash-free를 99% 이상으로 안정화할 수 있었습니다. 현재 google_maps_flutter_android 패키지 2.4.0 버전부터는 LATEST 렌더링 옵션을 제공하도록 개선돼(참고) Flutter 소스 코드에서도 렌더링 옵션을 수정할 수 있도록 업데이트됐습니다(이와 관련해 google_maps_flutter에 등록된 이슈를 참고하시기 바랍니다).

제스처 미작동 이슈

아래 화면은 배송원 앱의 주문 상세 확인 화면입니다. 이 화면에서는 크게 좌우로 스와이프해 페이지 닫기, PageView 내에서 좌우로 스와이프해 탭 화면 이동, Google 지도 내에서 핀치 줌(pinch zoom) 제스처가 가능합니다. 그런데 Android 기기에서 Google 지도 내 핀치 줌이 작동하지 않는 이슈가 발생했습니다.

   

제스처와 관련해 발생하는 문제는 두 가지였습니다.

Gesture Arena에서 여러 제스처가 경쟁해 Google 지도 제스처가 제대로 작동하지 않음

Gesture Arena에서 좌우 페이지 스와이프 제스처, 페이지 백 제스처, 상하 스크롤 제스처, 지도 제스처 등 여러 제스처가 경쟁해 Google 지도 제스처가 제대로 작동하지 않는 경우가 발생했습니다. 이때 Gesture Arena에서 경쟁하지 않고 즉시 모든 터치 이벤트를 받을 수 있게 하려면 gestureRecognizers에 EdgarGestureRecognizer를 추가해야 합니다.

EdgarGestureRecognizer는 일반적으로 AndroidView.gestureRecognizers에서 전달되며 뷰 범위 내 모든 터치 이벤트를 내장된 Android View로 즉시 발송하기 때문에 Gesture Arena에서 경쟁하지 않고 모든 터치 이벤트를 즉시 발송하므로 모든 터치를 전달받을 수 있습니다. Google 지도와 같이 모든 이벤트를 즉시 받아야 하는 뷰의 경우 유용하게 사용할 수 있습니다.

PageView 이동 시 첫 번째 페이지의 Google 지도에서 멀티 터치가 제대로 작동하지 않음

이 문제는 viewportFraction이 기본 값인 1.0인 경우 페이지가 완전히 넘어갔다고 판단하지 않아서 포커스를 완전히 넘겨주지 않아 발생한 문제였습니다. PageView의 allowImplicitScrolling 프로퍼티 true로 설정해서 다음 화면 요소로 이동했다고 판단되면 포커스를 이동하도록 설정해 해결할 수 있었습니다.

텍스트 표시 관련 이슈

일본어 한자가 중국어 번체로 표시됨

iOS 기기 중 특정 기기에서 일부 문자가 일본어가 아닌 중국어(번체)로 표시되는 이슈가 발생했습니다. 예를 들어, '配達設定(배달설정)' 문구에서 일본어 한자('設')가 아닌 중국어 한자('設')로 표시되는 이슈로, 기기나 OS에서 제공하는 폰트마다 이런 이슈가 있을 것으로 예상했습니다. 

배송원 앱 설정 화면 > 중국어 한자 표시 이슈

이 이슈를 해결하기 위해 스타일 프로퍼티(TextStyle)에 locale 프로퍼티를 각 언어에 맞게 잘 설정해 줬지만 해결되지 않았습니다. 이에 iOS 기본 폰트에서 일본어 한자를 제대로 지원하지 않는 경우가 있다고 판단했고, iOS의 fontFamilyFallBack 프로퍼티를 [.AppleSystemUIFont', 'Hiragino Sans']로 설정해 해결할 수 있었습니다. 아래는 코드 실행 결과입니다.

폰트별 '配達設定(배달설정)' 문구 표시 차이

Chinese Japanese
   
...
Column(
	mainAxisAlignment: MainAxisAlignment.start,
    crossAxisAlignment: CrossAxisAlignment.start,
    children: <Widget>[
        Text(
			'配達設定 (배달설정)',
			style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)
		),
		Text(
            '配達設定 (배달설정)',
            style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)?.merge(TextStyle(
               fontFamilyFallback: Platform.isIOS ? const ['.AppleSystemUIFont', 'Hiragino Sans'] : null,
               leadingDistribution: TextLeadingDistribution.even,
            )
		),
	),
])
Dart

텍스트 크기를 최소 혹은 최대로 설정하면 화면이 제대로 표시되지 않음

iOS와 Android 앱은 기기 설정에서 디스플레이 및 텍스트 크기를 변경할 수 있습니다. 기기 설정에서 이 옵션을 최소 및 최대로 설정할 경우 화면이 제대로 표시되지 않는 이슈가 발생했습니다. 이를 수정하기 위해 디자인 팀과 논의해 MediaQuery 위젯을 이용해서 textScaleFactor를 0.7~1.4로 제한하고, 필요에 따라 고정된 텍스트 크기로 표시되는 위젯을 만들어 대응했습니다. 

DeWidgetLimitedScaleText

class DeWidgetLimitedScaleText extends StatelessWidget {
  final bool isScalable;
  final Widget child;

  const DeWidgetLimitTextScale({Key? key, this.isScalable = true, required this.child}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final mediaQuery = MediaQuery.of(context);
    return MediaQuery(
      data: mediaQuery.copyWith(textScaleFactor: isScalable ? min(1.4, max(0.7, mediaQuery.textScaleFactor)) : 1.0),
      child: child,
    );
  }
}
Dart

백그라운드 상태에서 FCM(Firebase Cloud Messaging) 수신 시 isolate 관련 이슈 

firebase_messaging 패키지를 이용하면 앱이 백그라운드에 있는 상태에서 FCM 푸시 수신 처리가 가능합니다(참고). 그런데 이때 SharedPreference에 접근할 경우 'When received, an isolation is spawned. Since the handler runs in its own isolate outside your applications context, it is not possible to update application state or execute any UI impacting logic.' 메시지와 함께 오류가 발생합니다. 

Dart 앱은 단일 스레드 프레임워크이며 스레드 대신 isolate에서 작동합니다. Isolate를 새로 만들고 서로 통신할 수는 있지만 각 isolate는 고유한 메모리 힙을 할당받기 때문에 공유하는 메모리는 없습니다. 백그라운드에서의 푸시 콜백은 새로운 isolate에서 전달하는 것이기 때문에 메인 isolate의 메모리 데이터를 사용할 수 없어서 위와 같은 오류가 발생합니다. 이 문제는 앱 디렉터리 하위에 JSON 형식의 파일로 데이터를 저장하고 관리할 수 있는 유틸리티를 만들어서 FCM 수신 시 로컬에 데이터 저장이 필요한 경우에는 이 유틸리티를 사용하는 것으로 해결했습니다. 

기술 변경으로 더욱 돈독해진 팀워크

두 번째 Recode 과정에서는 새로운 기술을 학습하면서 동시에 그 기술을 활용해 제품을 만들어 내는 과정을 진행했습니다. Flutter 기술을 완벽히 이해하고 있지 않아서 여러 가지 우려가 있었지만 결과적으로 긍정적인 피드백이 많았습니다. 두 번째 Recode 프로젝트 회고에서 KMM에서 Flutter로 전환한 결과 가장 좋았던 점으로 모든 분들이 공감해 주신 것은 동일한 소스 코드로 고민과 토론이 가능해졌다는 점이었습니다. 

KMM으로 개발할 때는 Android와 iOS, KMM 각 영역에서 개발자가 본인 업무에 해당하는 영역에서만 개발을 진행하면서 각자의 관심 기술에만 집중했고, 이는 결국 장기적인 관점에서의 협업 측면이나 기술 성장 측면에서 아쉬움을 남겼는데요. Flutter로 전환하면서 Flutter라는 기술과 Dart라는 언어를 이용해 함께 고민하고 학습하며 그 내용을 실제 프로덕트에 반영하는 기회를 얻었고, 그 과정에서 발생한 급박한 상황 역시 생각보다 더 긍정적으로 회고됐습니다. 저희와 같이 소수(3~4명) 인원이 하나의 앱을 개발할 때는 같은 언어로 함께 고민하며 프로젝트를 진행하는 게 성장과 협업 측면에서 더 큰 동기를 부여할 수 있다는 것을 느꼈습니다.

팀 전체 관점에서도 공감대가 넓어졌습니다. 데마에칸 서비스 중 배송원 앱뿐 아니라 가맹점 앱, 리테일 앱 역시 Flutter를 활용하고 있기에 팀 차원에서 기술 교류가 시작됐고, 각 앱에서 공통으로 사용하는 모듈도 개발 가능해져 협업 측면에서도 좋아졌습니다. IDE나 CI/CD 환경 혹은 각 프로젝트의 아키텍처를 공유할 수 있게 됐고, 리팩토링이나 테스트 코드 등도 함께 고민하고 공유할 수 있어서 개인은 물론 팀 전체가 함께 성장하는 데 큰 도움이 되고 있습니다(공통 모듈을 만들어 활용하고 있는 내용은 Flutter 패키지로 공통 모듈 리팩토링하기를 참고하세요).  🙂

마치며

모바일 앱 개발 기술로 Flutter를 고민하고 있다면 아래와 같은 이유로 추천합니다.

  • 한정된 자원으로 멀티 플랫폼 개발을 할 수 있습니다. Android와 iOS뿐 아니라 PC와 웹으로도 개발할 수 있어서 다양한 형태로 제품을 검증할 수 있고 QA 환경 구성에도 유리합니다.
  • 앱 개발자에게 멀티 플랫폼 기술은 네이티브 개발자에게 다음 단계를 도전하기 위한 큰 과제와도 같기 때문에 커리어를 쌓고 채용 시장에서 경쟁력을 높일 수 있는 좋은 기회라고 생각합니다.
  • 개인과 팀 모두 고민하고 성장하기 위한 환경을 고민하고 있다면 좋은 선택이라고 생각합니다. 

배송원 앱은 Recode 후 새로운 버전에서 사용자에게 더 좋은 가치를 안정적으로 제공하기 위해 Flutter로 모듈화하고 테스트 코드를 작성하는 것에 집중하고 있습니다. Flutter 개발자분들과 더 나은 상태 관리 방법과 효율적인 의존 패키지 버전 관리 방법, 보다 빠른 빌드 및 배포 자동화 구성 방법, 그리고 새로운 프로덕트를 더 잘 만드는 방법 등을 고민하고 있습니다(개발자라면 대부분 공감할 부분들이라고 생각합니다 🙂 ). 사용자에게 더 나은 서비스를 제공할 수 있다면 세 번째 Recode를 진행해야 할 상황이 오는 게 조금은 기다려지기도 한다고 생각하며 글을 마치겠습니다. 

반응형
반응형

news.heraldcorp.com/view.php?ud=20210103000134

 

“아이폰12 이 정도 일줄은…” 삼성폰 10년만에 점유율 20% 붕괴 [IT선빵!]

삼성전자의 글로벌 스마트폰 시장 점유율이 20% 아래로 떨어질 것으로 보인다. 2011년 10% 벽을 돌파한 뒤 줄곧 20~30%대를 차지해오던 점유율이, 10년 만에 처음으로 10%대로 주저앉았다. 특히 5세대(G

biz.heraldcorp.com

 

2020년 시장 점유율, 4분기부터 iOS 강세

아이폰12 나오고 아이폰 , 아이패드 보급형 나오면서 2020년 4분기부터 국내에서도 iOS 점유율이 높아졌다고함.

그런데 패드 비율이 아이패드 사용자가 많아져서 국내 iOS 점유율이 높아졌음. 

 

반응형
반응형

https://flutter.dev/

 

Flutter - Beautiful native apps in record time

Flutter is Google's UI toolkit for crafting beautiful, natively compiled applications for mobile, web, and desktop from a single codebase. Flutter works with existing code, is used by developers and organizations around the world, and is free and open sour

flutter.dev

 

[펌] https://medium.com/@keyhyuk.kim/flutter%EB%A1%9C-ios-android-%EC%95%B1-%EC%99%B8%EC%A3%BC%EA%B0%9C%EB%B0%9C%ED%95%98%EA%B8%B0-67bae199c9fe

 

Flutter로 IOS, Android 앱 외주개발하기

IOS, Android 앱 개발 외주를 Flutter로 진행하면서 느낀 부분들을 공유하려고 합니다. 특히 Mac이랑은 전혀 인연이 없는 윈도우 개발자가 Flutter로 IOS 개발 및 배포 과정을 정리해봤습니다.

medium.com

IOS, Android 앱 개발 외주를 Flutter로 진행하면서 느낀 부분들을 공유하려고 합니다. 

 

특히 Mac이랑은 전혀 인연이 없는 윈도우 개발자가 Flutter로 IOS 개발 및 배포를 어떤 방식으로 했는지도 정리해봤습니다. 

 

왜 Flutter를 선택했나요? 

크로스플랫폼 앱 개발 도구로 React native, Xamarin, Flutter 등의 선택지가 있습니다. 

 

Flutter, 충분히 성숙한 프레임워크인가요? 

개발 언어인 dart와 Flutter 프레임워크 자체는 충분히 성숙했다고 생각합니다. 

커뮤니티 측면에서 Stackoverflow에 등록된 react native 질문 수는 약 8만 (reactjs를 포함하면 30만 이상) , 

Flutter의 질문 수는 약 5만 건 정도로 3만 건의 차이가 납니다. 

 

Dart 언어, 배우기 어려운가요? 

언어 자체가 C#, JAVA와 매우 유사해서 배우기 쉽습니다. 

거기에 더해 Hot reload 지원, 퍼포먼스(애니메이션), 등 성능, 편의성 측면에서 좋은 부분들이 많이 있습니다. 

Dart에 대한 장점은 아래 링크에 잘 정리되어 있습니다. 

https://beomseok95.tistory.com/315

 

 

Flutter로 개발하면서 좋았던 부분 

Google이 공식 지원하는 프레임워크인 만큼 Google 에코시스템과 연동이 잘됩니다. 

특히 저는 Notification 기능 때문에 Firebase Cloud message를 꼭 사용해야 했는데, 문서화 및 샘플코드가 굉장히 잘 되어있고, 연동 과정이 굉장히 매끄러워서 구글 측에서 상당히 신경을 많이 썼다는게 느껴졌습니다. 

React native와 다르게 Javascript bridge가 없고, 

Skia rendering engine이 IOS, Android 위에서 UI를 그려주기 때문에 높은 성능을 기반으로 

플랫폼 간 완전하게 동일한 UI 개발이 가능합니다. 

또 Cupertino, material 두 UI 컴포넌트를 섞을 수도 있습니다. 

애니메이션, 화면 라우팅 등에서 느껴지는 체감 성능도 아주 좋았습니다. 

Flutter 게임 개발도 가능하다고 하니 일반 어플리케이션의 성능은 말할 것도 없습니다. 

 

Flutter로 개발하면서 안 좋았던 부분 

Flutter에는 개발 시간을 획기적으로 줄여줄 수 있는 다양한 플러그인들이 존재합니다. 

또 Flutter는 구글에서 공식으로 미는 프레임워크이므로 

구글에서 공식으로 Release하는 플러그인들이 다수 있습니다. 

구글 공식 플러그인을 사용하면서 크게 문제가 생긴 부분은 없었지만, 

버전이 아직 많이 낮아서 사용할 때 불안한 요소가 어느 정도 있다고 생각합니다. 

써드파티 플러그인의 경우, 플러그인 마다 완성도가 워낙 천차만별이라 따로 언급은 안 하겠습니다. 

 

만약 Flutter를 사용하실 계획이시라면 필요한 Plugin들의 버전 및 안정도를 미리 확인하시는 게 좋을 것 같습니다. 

 

윈도우에서 IOS 빌드하기 (불가능합니다 ^^;) 

 

youtu.be/LN668OAUrK4

 

반응형
반응형

Build amazing iOS and Android apps

with technology you already know


Open source framework for building truly native mobile apps

with Angular, TypeScript or JavaScript.


https://www.nativescript.org/



NativeScript 3.0 - Faster apps, built with JavaScript

 

.


반응형
반응형

https://github.com/driftyco/cordova-plugin-wkwebview-engine#installation-instructions


코르도바 WKWebView 엔진

이 플러그인은 Apache Cordova WKWebView 플러그인의 확장 입니다. 여기에는 몇 가지 DOM 예외 문제와 함께 XHR 요청을 둘러싼 일부 문제를 해결하기위한 개선 사항이 포함되어 있습니다. Ionic은 Cordova 팀과 협력하여 업데이트를 공식 Cordova 플러그인에 병합하는 최종 목표로 이러한 변경 사항을 완전히 테스트합니다. 베타 테스트 기간이 끝나면 WKWebView 플러그인을 Ionic 기본값으로 설정하여 모든 사용자가 UIWebView에 비해이 플러그인의 향상된 성능을 쉽게 이용할 수있게하는 것이 중요합니다.

이 플러그인은 iOS 9 이상 만 지원하며 iOS 8의 UIWebView로 대체됩니다.

WKWebView 플러그인은 iOS에서만 사용되므로 cordova-ios플랫폼이 설치 되어 있는지 확인하십시오 또한 cordova-ios플랫폼 버전이 같 4.0거나 커야합니다.

설치 지침

최신 Cordova CLI가 설치되어 있는지 확인하십시오 (Sudo가 필요할 수도 있음).

npm install cordova -g

ios플랫폼이 추가 되었는지 확인하십시오 .

ionic platform ls

iOS 플랫폼이 목록에 없으면 다음 명령을 실행하십시오.

ionic platform add ios

iOS 플랫폼이 설치되었지만 버전이 < 4.x인 경우 다음 명령을 실행하십시오.

ionic platform update ios
ionic plugin save           # creates backup of existing plugins
rm -rf ./plugins            # delete plugins directory
ionic prepare               # re-install plugins compatible with cordova-ios 4.x

WKWebViewPlugin 설치 :

ionic plugin add https://github.com/driftyco/cordova-plugin-wkwebview-engine.git --save

노트 :

이미 아파치 / cordova-plugin-wkwebview-engine을 설치 했다면 이 버전을 사용하기 전에 제거해야합니다.

ionic plugin rm cordova-plugin-wkwebview-engine

플랫폼 구축 :

ionic prepare

iOS 9 또는 10 기기에서 앱 테스트 :

ionic run ios

iOS에 WKWebView가 설치되었는지 확인하는 쉬운 방법은 window.indexedDB존재하는지 확인하는 것입니다. 예 :

if (window.indexedDB) {
   console.log("I'm in WKWebView!");
} else {
   console.log("I'm in UIWebView");
}

필요한 사용 권한

config.xml에 다음 내용이 포함되어 있지 않으면 WKWebView가 완전히 실행되지 않을 수 있습니다 (deviceready 이벤트가 실행되지 않을 수 있음).

config.xml

<allow-navigation href="http://localhost:8080/*"/>
<feature name="CDVWKWebViewEngine">
  <param name="ios-package" value="CDVWKWebViewEngine" />
</feature>

<preference name="CordovaWebViewEngine" value="CDVWKWebViewEngine" />


반응형

+ Recent posts