▼ 맥 homebrew 를 이용한 설치 ▼ Ubuntu 리눅스 에서 apt 를 이용한 설치 ▼ devices 명령으로 설치 확인
API 호출을 통해 JSON 데이터를 파싱 하는 과정에서 플러터에서 한글 깨짐 문제가 생겼습니다. Chat GPT 코드를 그대로 사용했는데 발생한 에러라서 뭔가 GPT 가 코드를 잘못 만들었을 것이라고 생각해서 인터넷에 검색해보니 많은 사람들이 해당 케이스의 상황을 겪고 있더군요.▼ 한글이 깨질 경우 다음과 같이 utf8 디코딩이 필요하고 response.body가 아닌 response.bodyBytes 로 값을 변경해서 쓰면 됩니다. ▼ 실제 예제 코드입니다.
안드로이드에서 리스트 뷰를 생성할 때 Adapter를 통해서 데이터를 바인딩해서 생성하는 방법을 알아보았습니다. 이번에는 간단한 예제를 만들때 어댑터를 만들지 않고 XML을 구성하여 직접 리스트 뷰 entries 속성을 통해 바인딩하는 방법을 알아보도록 하겠습니다. res/values 에 새로운 파일을 추가해서 데이터를 XML로 구성합니다. name을 myarray로 지정합니다. LIST1 LIST2 LIST3 위에서 만든 XML 데이터를 바인딩하기 위해서 리스트 뷰 에 @array/myarray 로 android:entries 에 값을 대입합니다. MainActivity onCreate 함수에 리스트 뷰 이벤트만 추가해줍니다. override fun onCreate(savedInstanceState: ..
예전에는 안드로이드에서 뷰에 대한 참조를 하려면 findViewById를 사용해야 했습니다. 그런데 사용되는 XML의 참조 객체가 많아질 수록 사용하기 불편할 뿐더러 반복되는 코드가 지져분해지기 쉽습니다. Butter knife나 extension을 통해 불편함을 해소하긴 했지만 버전 3.6 이상 부터는 안드로이드 뷰 바인딩을 통해 좀 더 편리하게 뷰에 있는 객체에 참조할 수 있게 되었습니다. findViewById를 사용할 경우 단점 느린 속도 타입 캐스팅에 따른 예외 사용자 실수로 Null 참조 자동 생성되는 파일 만약 뷰 바인딩(View Binding)을 사용하게 된다면 다음과 같이 ViewBinding 을 구현하는 임의의 파일들이 생성됩니다. Activity 클래스와 매핑 되는 클래스로 별도로 작..
아이폰과 마찬가지로 모바일 환경에서 가장 많이 사용되는 형태의 UI가 리스트입니다. 안드로이드 리스트 뷰는 안드로이드에서 가장 많이 사용되는 컴포넌트 중에 하나로 다음과 같은 특징을 가지고 있습니다. 레이아웃과 같은 뷰 그룹에 속함 어뎁터(Adapter)를 통해 데이터와 리스트 뷰를 연결 오래전부터 사용 가능 했으며 API Level 1 부터 존재 프래그먼트를 사용할 경우 this 컨텍스트를 사용할 수 없기 때문에 getActivity() 함수를 사용 프래그먼트를 사용할 경우 LayoutInflater를 사용해 뷰를 가져옴 리스트 뷰 생성 아이디가 listview1 인 리스트 뷰를 선언한다. 데이터 정의 다음과 같이 데이터를 정의한다. class MainActivity : AppCompatActivity..
iOS Background Modes 아이폰 개발을 하다보면 백그라운드 설정이 필요할 때가 있습니다. 저전력 블루투스나 백그라운드 프로세싱등을 하려면 Backgroubnd 모드를 활성화해줘야 하는데 만약 해당 기능을 활성화하고 Plist에 특정 옵션을 추가하지 않으면 iOS 13이상에서 앱 제출시 문제가 될 수 있습니다. 만약 앱스토어에서 문제가 생기면 다음 옵션들을 만들어 수정해줘야 합니다. Missing Info.plist value. The Info.plist key 'BGTaskSchedulerPermittedldentifiers' must contain a list of identifiers used to submit and handle tasks when 'UIBackgroundModes' h..
Flutter 개발 설정 플러터를 설치하면 몇 가지 해줘야 하는 것들이 있습니다. 특히 처음 설치하면 main.dart 파일이 복잡하게 구현되어 있는데 이 부분부터 정리해보겠습니다. ▼ main.dart의 모든 코드를 제거하고 다음과 같이 main() 함수만 남깁니다. 그리고 stless를 추가하고 탭키를 누르면 Flutter Stateless Widget이 만들어지게 됩니다. stless ▼ 그리고 해당 클래스의 이름을 MyApp 으로 변경합니다. 물론 다른 이름으로 변경해도 괜찮습니다. MyApp의 경우 처음 플러터 프로젝트가 생성 될 때의 이름입니다. import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } clas..
https://docs.flutter.dev/get-started/install/macos 설치 환경 플러터를 개발하기 위한 환경의 조건은 다음과 같습니다. macOS 2.8GB의 저장 공간 (개발툴 저장 공간을 제외한 크기) git, Xcode 가 설치된 환경 만약 git이 설치되어 있지 않다면 Xcode를 설치하거나 직접 git을 설치해야 합니다. Xcode를 설치하면 자동으로 git이 설치되며 따로 git을 설치 않아도 되는 장점이 있습니다. 만약 homebrew를 통해 설치하려면 다음 가이드를 참고하시면 됩니다. https://git-scm.com/download/mac Git - Downloading Package Download for macOS There are several options ..
앱 시스템 설정 이동 iOS 앱을 개발하다보면 설정으로 이동할 일이 있습니다. 페이스 아이디를 켜주세요. 카메라 사진 권한을 허용해주세요. 등등 사용자가 확인하지 못한 부분을 개발자가 설정 페이지로 이동시켜서 유도하는 방법인데 prefs 값을 사용해서 이동 시킬 때 다음과 같은 애플의 리젝 메시지를 받을 수 있습니다. 이는 프라이빗 API를 사용에서 문제가 되는 겁니다. 때문에 prefs 로 열지 말고 UIApplication.openSettingsURLString 를 통해서 열어줍니다. Guideline 2.5.1 - Performance - Software Requirements Your app uses the "prefs:root=" non-public URL scheme, which is a pr..
시뮬레이터 다크모드 아이폰 개발을 하다보면 시뮬레이터를 자주 사용합니다. 최근 iOS 13 이후부터는 다크 모드를 지원하게 되는데요. 개발 초기에는 앱 개발 시 다크 모드를 포함하지 않는 경향이 있었지만 최근에는 다크모드를 지원하는 앱이 많아졌습니다. 일일이 시뮬레이터에 연결해서 다크모드를 테스트하는 것보다는 시뮬레이터에서 테스트하는 편이 훨씬 빠릅니다. 아이폰에서는 제어센터에서 손쉽게 변경할 수 있는데요. 시뮬레이터는 조금 귀찮긴 합니다. 그림 지금부터 시뮬레이터에서 다크 모드로 변경하는 법을 알아보겠습니다. ▼ 다음과 같이 앱 홈화면에 설정 메뉴를 선택합니다. ▼ 설정화면에서 아래쪽으로 스크롤해줍니다. ▼ 시스템 설정 마지막 부분에 개발자 메뉴를 선택합니다. ▼ Developer (개발자) 메뉴에서 ..
아이폰 앱을 만들면 무한 스크롤을 구현해야 하는 경우가 있습니다. 주로 서버에서 보내온 데이터가 페이징 처리가 되있는 경우에 무한 스크롤을 구현합니다. 더보기 버튼을 만들어서 구현할 수 도 있지만 더 보기 버튼 보다는 무한 스크롤로 테이블 뷰를 구현하는 것이 더 자연스럽습니다. 지금 부터 무한 스크롤을 위해서 필요한 것들과 방법에 대해서 알아보겠습니다. ViewModel 코드 (데이터 정의) ▼ 우선 통신하는 부분을 보겠습니다. 코드가 길어서 복잡해보이겠지만 단순합니다. totalPage, currentPage, isLoading 변수를 선언해줍니다. 데이터 통신이 끝나면 테이블 뷰 데이터에 기존 데이터를 포함해서 appendData를 해줍니다. 또한 통신이 시작하기 전에 isLoading 값을 true..
스위프트의 동적 멀티플라이어 오토레이아웃을 사용하다보면 동적으로 멀티플라이어 값을 동적으로 바꿔야 할 경우가 있습니다. 특히나 iPad iPhone을 동시에 개발 할 때 필요합니다. 해당 비율을 동적으로 주기 위해서는 NSLayoutConstraint에 multiplier를 적용해주면 되지만 몇 가지 생각해야 하는 것이 있습니다. 다음과 같이 Constraint를 removeConstraint로 삭제한 뒤에 다시 addConstraint를 이용해 추가해줘야 합니다. 또한 새로 화면을 업데이트 하기 위해서 layoutIfNeeded 함수를 호출해줘야 합니다. ▼ 우선 다음과 같이 extension을 사용해 constraintWithMultiplier라는 함수를 만들어줍니다. 내부적으로 하는 일은 그냥 새로..