라벨이 IOS인 게시물 표시

UINavigationController의 구성요소가 떠오르지 않는 사람을 위한 글

이미지
한 화면으로 이루어져 있는 앱을 만들다 보면, 다른 기능을 새로운 화면에 구성하고 싶은 생각이 듭니다. 이럴 때 필요한것이 화면 전화이죠. 화면 전환에는 여러가지 방법이 있으나, 그 중에 하나인, 가장 기본적이고 많은 기능을 제공하는 NavigationBar의 구성요소와 기능들에 대해 알아보도록 하겠습니다. 정의 및 구성요소 UINavigationBar 는 UINavigationController 라는 컨트롤러에 의해 제어됩니다. UIViewController 를 상속받아 구현되어 있기 때문에 UIViewController 가 가진 요소들을 가지고 있습니다. 가장먼저 UINavigationController 에 대해 먼저 알아보겠습니다. class UINavigationController : UIViewController UINavigationController 는 하나의 뷰 컨트롤러가 아닌 여러개의 뷰 컨트롤러의 계층을 만들고 관리 해주는 컨트롤러 입니다. 사용자가 상세화면이나 상위에 있는 화면이라고 생각하게 만들어주죠. 아래의 이미지를 보면서 생각해봅시다. 첫 화면에서 General 버튼을 누르면, General 페이지로 이동됩니다. 그려먼 화면의 타이틀이 바뀌고, 이전 페이지로 돌아갈 수 있는 버튼이 생기죠. 실제 화면이 쌓이고, 사라지는 순서를 관리하는 navigation stack 이 있습니다. 네비게이션의 첫 뷰 컨트롤러는 스택의 root인 root view controller 가 됩니다. 즉 네비게이션 컨트롤러는 root view controller 인 뷰컨트롤러가 필요하죠. 화면의 순서는 stack이 관리하지만, 사용자가 이 스택을 조종하기 위한 인터페이스로 UINavigationBar 가 있습니다. UINavigationBar 의 구성 요소는 위의 그림과 같습니다. 일반적으로 화면의 가장 상단에서 화면의 계층을 나타내 줍니다. 이전화면은 어디서 왔는지, 내가 할 수 있는 행동은 무엇인지, 이 페이지가 어디인지를 타이틀 등을

UIkit introduction - User Interface Objects 살펴보기

이미지
UIkit introduction - User Interface Objects 살펴보기 OverView iOS 앱을 처음 개발하면, 무엇인지도 모르고 공부하기전에 먼저 써보게 됩니다. 알고 쓰는 것보다, 쓰고나서 알아가는게 더 좋다고도 생각합니다. 그래도 어떤 것들이 있고 그래서 무엇을 해주는 것인지 정리해보려 합니다. UIKit에 대한 사용경험이 있다고 전제하여, 작성되었습니다. 없으시다면 TableView를 만들어 보거나, NavigationController를 사용해 보는 것을 추천드립니다. 제가 공부하는 방식은 일단 많이 만들어보고, 좀 더 자세하게 공식문서를 읽으면서 정리하고, 다시 사용하면서 내것으로 만드는 것 입니다. UIkit은 iOS개발에 필요한 기본적인 것들을 제공 해 줍니다. 화면을 그리는데 필요한 것들과 사용자의 이벤트를 처리하는데 필요한 것들이죠. 예를들면 터치 이벤트와 같은 것들입니다. 다음은 UIKit을 사용하는데 종요한 내용입니다. 지금당장은 이해가 되지 않아도 알고 있으면 언젠가 깨달음을 얻을 수 있습니다. 특별한 경우를 제외하고는 앱의 main thread 혹은 main dispatch queue 에서만 UIKit을 사용하세요. 이러한 제한사항은 특별히 UIResponder에서 만들어지거나 어떤식으로든 앱의 사용자 인터페이스를 조작하는 것과 관련된 클래스에 적용됩니다. 기본적으로 AppIcon, Launch screen storyboard가 제공됩니다. 이 두가지는 앱을 구성하는 필수 요소이기 때문에 빈화면으로 제공되지만 다른 앱들과 구분할 수 있도록 제공해야 합니다. Info.plist에는 앱의 Meta data들이 들어있습니다. 여러 설정값들을 이 파일을 수정하여 적용할 수 있습니다. UIKit의 코드는 MVC 패턴으로 되어있습니다. 간단하게 설명드리자면, 아래의 구조와 같습니다. 데이터들은 모델링을 통해 어플리케이션에서 사용될 수 있습니다. 모델링이 왜 필요한지는 없이 앱을 만들어보시면, 보다 명확함을

[Swift-30-Projects] 05. IOS 클론코딩 Artistry

이미지
테이블뷰와 셀프 사이징 테이블뷰을 활용한 간단한 앱입니다. 엄청 간단한 앱이라 금방 만들겠네 했었는데, 생각보다 모르는 부분이 많아서 이번 기회에 배운 내용들을 하나씩 정리 하려고 합니다. 구현을 하면서 막혔던 이슈들에 대한 정리로 서술됩니다. 전체 코드는 이곳 에 있습니다. 먼저 앱이 동작하는 것을 보시고, 아 이런 건 이렇게 만들어야지가 바로 떠오르신다면 이 글을 볼 필요가 없습니다! 앱의 동작은 이곳 에 있습니다. 앱의 구조 앱은 크게 2개의 화면으로 되어있습니다. 하나는 아티스트들을 나열하는 테이블 뷰와 클릭 했을 때 상세 내용을 보여주는, 상세 테이블 입니다. 상세 페이지로 이동하기 위해서 네비게이션 바에 넣어주었습니다. 커스텀 네비게이션 바 앱의 가장 첫 화면에서 보이는 네이게이션 바를 그리면서 문제가 생겼습니다. 스토리보드에서 navigationBar의 스타일 옵션중에 prefersLargeTitles 을 true로 설정하고 배경색을 주고 폰트까지 설정한다음 화면을 보니. 원하는 모습이 나오지 않았습니다. 원래 원했던 것은 위까지 다 차있는 모습이었는데, navigationBar 부분만 색상이 찼습니다. 당연히 navigationBar의 부분의 배경색만 바뀌는게 맞습니다. 내가 원하는대로 바꾸려면 커스터마이징을 해주어야 합니다. 그리고 그 커스터 마이징을 하기 위해서는 UINavigationBarAppearance 를 공부해야했습니다. 자세한 정리는 아래에 참고에 써 놓도록 하겠습니다. 블로그에 정리하는 것도 좋지만 잘 정리된 내용을 정독하는 방법도 개인적으로는 효율적이라고 생각합니다. let myColor = UIColor(red: 118.0 / 255.0 , green: 158.0 / 255.0 , blue: 71.0 / 255.0 , alpha: 1.0 ) let appearance = UINavigationBarAppearance() appearance. backgroundColor = myColor app

[Swift-30-Projects] 04. IOS 클론코딩 TodoTDD

이미지
30개의 프로젝트를 만들고 있다가, 중간에 멈춰버린 프로젝트입니다. 이유는 간단했습니다. 테스트 코드를 어떻게 짜야하는지도 모르는데 TDD로 프로젝트를 시작했다가 낭패를 보았습니다. 이 프로젝트를 진행하면서 Test는 어떻게 할 수 있는 것이고 어느 부분을 할 수 있는지 나중에 공부하기로 미뤄두었습니다. 메인페이지 Test 페이지를 뺴면 그리 복잡한 앱은 아닙니다. 가장 메인에 테이블 뷰 하나를 만들어 줍니다. 그리고 우측 상단에 새로운 TodoList의 아이템을 추가할 수 있는 뷰를 하나 추가해주고, 마지막으로 투두 리스트를 눌렀을 때, 상세 내역이 보이도록 하는 디테일 뷰가 필요합니다. 기능 구현 추가는 원래 서버에 저장하고 잘 불러오는지에 대해서도 추가해야 하지만, 간단하게 앱내의 저장영역에 저장했습니다. 너무 길어지다 보니 애정도 떨어지고, 개발에 대한 흥미도 떨어지면서 완성을 제대로 하지 못했습니다. 나중에 기회가 된다면 다시 잘 만들고 싶은 앱 입니다. 테이블 뷰 이 이전 앱 부터 테이블 뷰를 쓰는 방법은 익혀왔고, 딱히 이 앱에서 더 특별한 것은 없어서 이렇게 간단히 구현하고 앱 구현을 마칠까 합니다.

iOS 개발자가 되어버린 데이터 분석가의 2020년 회고

이미지
iOS 개발자가 되어버린 데이터 분석가의 2020년 개인적으로 많은 변화들과 도전들이 있었던 한 해 였습니다. 많은 시행착오를 통해 나가아갸 할 방향을 정하는데 있었던 일들을 정리 해 두도록 하겠습니다. 저와 같은 커리어를 고민하시는 분들에게 도움이 되었으면 좋겠고, 또한 무지한 저를 깨우쳐 주시거나 가르쳐 주실 댓글도 환영입니다 ㅎ _ㅎ. 커리어 전환 첫 회사에서 데이터분석가로 일을한지 3년차가 되면서, 많은 한계를 느꼈습니다. 더 이상 흥미가 느껴지지 않기도 하고, 한 가지 이유보다는 여러가지 복합적인 이유와 iOS개발자로 커리어 전환할 수 있는 계기가 생겨서 도전하게 되었습니다. 물론 여태까지 쌓았던 커리어를 포기하는 것은 아깝지만 스스로 이 일을 하고 싶지 않다 라는 결론에 도달하며 미련없이 전환 했습니다. 아무 기반지식이 없었고, 오히려 개발자로서 역량이 부족했기에 좀 더 두려워 하면서 전환했으면 좋았을 텐데라는 아쉬움이 남았습니다. 예를 들면 기본적인 협업도구의 사용방법, 배포 전략에 대한 이해, 업무 분담의 방법, 테스트 및 QA 진행방법에 대한 지식이 부족한 상태에서의 커리어 전환은 너무나 큰 리스크 였지만 그 당시에는 알지 못했기에 하마터면 어쩔 뻔 했나 라는 생각에 지금도 등골이 서늘합니다. 관련 링크 개발자로 랜딩하기 가장 먼제 apple 생태계를 이해하는 것 부터 난관이었습니다. 인증서관리, 개발도구, 라이브러리 관리 등, 생각지 못한 부분들을 공부하는 것에도 시간을 많이 쏟았습니다. 가장 중요한 기초체력인 개발 언어를 한 번은 빠르게 다 공부하고 계속 이해하도록 시간을 쏟았어야 하는데 그러지 못하고 SDK 및 API에 너무 많은 시간을 할애 한 부분이 아쉬웠습니다. 지금이라도 한 언어를 깊게파 기초 체력을 다지는 중 입니다. 그 다음은 많이 만들어 보는 것 이었습니다. 개발자가 된다는 것은 말 그대로 개발을 하는 것 이었습니다. 많은 앱들을 보고 어떻게 구현했을까 고민하고 전체가

[iOS] GCD와 Operation Queue

이미지
[iOS] GCD와 Operation Queue GCD를 공부하던 중 정리가 잘 되지 않아 정리 해 보려고 합니다. 그리고 같이 공부할 키워드로 떠오른 Operation Queue와는 어떤점이 다른지 정리 하려고 합니다. GCD(Grand Central Dispatch)는 멀티 코어 하드웨어에서 코드 동시 실행을 지원합니다. 코드의 동시실행을 이해하려면, 실행의 단위를 잘 알아야 합니다. 코드를 작성하면, 어떠한 기능을 하는 파일이 됩니다. 이를 프로그램 이라고 합니다. 이 프로그램은 운영체제의 메모리에 올라가며, 프로그램의 인스턴스를 생성합니다. 이를 프로세스 라고 합니다. 프로세스는 운영체제로 부터 독립된 자원을 할당 받습니다. 그리고 그 프로세스에서 여러가지의 일을 실행하는 단위를 쓰레드 라고 합니다. 쓰레드는 프로세스가 할당 받은 자원 중 독립적으로 스택만 새로 할당 받고, 나머지 자원들은 쓰레드끼리 공유합니다. 정래 해보면 코드로 프로그램을 실행하고, 그 프로그램이 하나 실행되면 하나의 프로세스가 생성됩니다. 그리고 그 프로세스 안에서 흐름의 단위가 쓰레드 입니다. 멀티 프로세스 와 멀티 쓰레드 이름으로 부터 의미를 유추 해 보도록 하겠습니다. 멀티 프로세스란 하나의 프로그램 안에 어려가의 프로세스가 동작할 수 있도록 하는 것 이겠군요. 그렇다면 하나의 프로그램 안에서 각각의 독립적인 자원을 할당받은 프로세스들이 기능을 할테니, 프로세스끼리 영향을 주지 않아 독립적으로 사용할 수 있어서 좋겠습니다. 하지만 반대로 공유하는 자원이 없어서, 데이터를 전송하고 받아야겠네요. 멀티 쓰레드란 하나의 프로세스에서 여러개의 쓰레드를 사용하는 방법 일 것 입니다. 멀티 프로세싱의 방법과 반대로, 공유하는 자원이 있으며, 데이터를 전달하는 방법이 간단할 것 같습니다. 하지만 공유하는 자원이 있따는 것은 잘 못 관리하면 의도하지 않았던 데이터의 왜곡이 일어나서 버그를 만들기 쉽겠습니다. 동시성 과

[iOS] Prefetching으로 프레임드랍 막기

이미지
[iOS] Prefetching으로 프레임드랍 막기 필요한 이유 컬렉션 뷰에서 cellForRowAt 메소드로 데이터를 가져와서 컬렉션 뷰를 그릴 경우, 셀을 구성하는 작업은 메인 쓰레드에서 진행 될 것입니다. 많은 셀을 메인 쓰레드에서 진행한다면, 프레임 드랍이 일어날 수 있고 결과적으로 매끄러운 스크롤링이 불가능합니다. 이런 작업을 돕기 위해 Prefetching이 추가되었습니다. 사용 필요 요건은 다음과 같습니다. iOS 10.0+ Xcode 11.3+ 비교 그럼 그냥 컬렉션 뷰만 쓸 때와는 어떤점이 다를까요? 사실 이미지나, 서버에 요청해서 데이터를 받아오지 않아서인지 큰 차이를 느끼지 못했습니다. 하지만 구현 해놓고 브레이킹 포인트를 걸고, 출력을 해 보면서 차이를 느낄 수 있었습니다. 가장 먼저 제가 다름을 느낀 곳은 같은 화면을 구성하는데 프리패칭 프로토콜을 채택해서 구현 했느냐, 아니냐에 따라 데이터의 fetching 갯수가 다른 것 이었습니다. 왜냐하면 cellForRowAt에서는 셀을 그리기 위한 작업만을 해서 그런지 그리기 위한 데이터만 가져오는 것 처럼 보였습니다. 하지만 프리패칭 프로토콜을 채택하면, 디스플레이 영역이 아닌, 프리패칭의 영역의 데이터를 미리 가져옵니다. 그렇기 때문에 가져오는 데이터의 갯수가 다릅니다. 화면에 6개가 그려져야 할 때, Prefetching 없이 컬렉션 뷰로 그리게 되면 일단 화면에 그려지는 6개의 셀의 데이터만 가져오고 아래로 스크롤 할 때 새로운 데이터를 로드 합니다. 하지만 이 갯수가 중요한게 아닙니다. 이 그림을 그리는 작업이 어디서 이루어지고 있는지가 핵심입니다. 셀을 그리고 있는 cellForRowAt작업은 메인 스레드에서 이루어지는데 해야 할 일들이 많아지면 다 처리하지 못하고 프레임 드랍이 일어날 수 있다. 이 작업 중 일부가 백그라운드에서 일어나게 되면 메인 쓰레드에 걸리는 부하가 줄어들고 프레임 드랍

[iOS] ViewController의 화면전환 방법 정리

이미지
[iOS] 화면전환 방법 어떤 버튼을 눌러 다른 페이지로 이동 시키는 일은 항상 헷갈립니다. 이번 기회에 정리해 두고 가려고 합니다. 일단 버튼을 하나 만들고 눌러서 내가 원하는 페에지와 실제 페이지가 잘 나타나는지 정리하겠습니다. 이런 버튼이 하나 있고 화면을 전환 해 보도록 하겠습니다. 스토리 보드 가장 쉬운 방법이라고 생각합니다. 내가 액션을 줄 컴포넌트를 클릭하고 컨트롤 + 드래그로 원하는 페이지에 드롭합니다. 선이 생기면서 어떻게 보여줄 것인지 segue action을 선택하면 됩니다. 일단은 present modally를 선택합니다. 버튼을 누르면 모달 창이 새로 생기죠? 아주 쉽고 간편하답니다! viewController present @IBAction func buttonClick(_ sender: Any) { let viewControllerName = self.storyboard?.instantiateViewController(withIdentifier: "SecondViewID") if let view = viewControllerName { self.present(view, animated: true, completion: nil) } } 다음과 같은 코드를 작성해줍니다. 스토리 보드에 만들어 준, 뷰컨트롤러의 스토리보드 아이디를 설정 해줍니다. 저는 SecondViewID 로 설정 해주었습니다. 버튼에 IBAction을 설정 해 준다음에 스토리 보드에서 스토리 보드에서 설정했던 ID를 가지고 옵니다. 그리고 가져온 뷰컨트롤러를 self에서 present 해줍니다. viewControllerName?.modalTransitionStyle를 설정하여 모달의 전환을 설정할 수 있습니다. @IBAction func buttonClick(_ sender: Any) { let viewController

[iOS] 버튼 클릭해서 이미지 돌리기

이미지
[iOS] 클릭해서 이미지 돌리기 앱을 만들다가, 더 보기 ^ 를 눌렀을 때 아래로 화살표가 돌아가면서 목록들이 나타나는 것을 구현할 일이 있었습니다. 위로 향하는 이미지를 누르면 아래로 향하는 이미지로 바뀌도록 코딩을 하려고 했는데 이미지를 돌릴 수 있다는 것을 알고 정리해 두려고 합니다. 버튼으로 상하 반전하기 이 방법은 어떤 버튼을 눌렀을 때 이미지를 상하로 회전시키는 방법입니다. CGAffineTransform을 이용하여 이미지를 뒤집습니다. private var isUpside: Bool = false @IBAction func turnArroundButtonClicked(_ sender: Any) { arrowImageView.transform = CGAffineTransform(scaleX: 1, y: isUpside ? 1 : -1) isUpside = !isUpside } 이미지의 x좌표 y좌표를 변경해여 이미지가 돌아간 것 처럼 할 수 있었습니다. 원래 scaleX, Y로 이미지를 늘려주는 것 이지만, y좌표를 음수를 할당 해 이미지에 반전을 주었습니다. 90도 만큼 돌리기 버튼을 눌러 이미지를 돌리다 보니, 시계방향, 반 시계방향으로 돌리고 싶을 때는 어떻게 해야하나 찾아보다가 발견한 방법입니다. 좋은 방법인지는 잘 모르겠으니, 더 좋은 방법을 아시는 분은 댓글로 달아주세요! private var count: Int = 0 @IBAction func clockWiseButtonClicked(_ sender: Any) { count += 1 arrowImageView.transform = CGAffineTransform(rotationAngle: .pi * 0.5 * CGFloat(self.count)) } @IBAction func reverseClockWiseButtonClicked(_ sender: Any) { cou

[iOS] Kingfisher 둘러보기

이미지
[iOS] Kingfisher 둘러보기 이미지 서버에서 이미지를 가져다 표시해줄 때 항상 쓰던 라이브러리 입니다. 어떤 기능이 있는지 살펴보기 전부터 웹에서 주소로 이미지를 가져올 때는 항상 써서, 이미지를 불러오는 라이브러리 인 줄 알았습니다. 하지만 본래의 목적은 이미지 캐싱이라는 것을 알게 되었고, 이번기회에 어떤 기능이 있는지 살펴보겠습니다. 내용은 Cheat Sheet 를 참고했습니다. 이미지 로딩 저도 이 기능 때문에 사용하는 줄 알았던 이미지 로딩입니다. 사용법은 굉장히 간단합니다. 이미지 뷰를 포함해(NSImageView, UIButton and NSButton)에 Extension 으로 구현되에 있기 때문에 setImage 를 사용해 이미지를 설정하면 됩니다. import Kingfisher let url = URL(string: "https://example.com/image.png") imageView.kf.setImage(with: url) 내부의 동작과정은 다음과 같습니다. url.absoluteString 로 캐싱된 이미지가 있는지 확입합니다. 만약 이미지가 캐싱되어 있어서 찾으면(메모리, 디스크 중), imageView.image에 나타냅니다. 만약 찾지 못한다면, url로 요청을 날려 이미지를 다운받습니다. 다운받은 데이터를 UIImage object로 변환합니다. 변환한 이미지를 메모리나 티스크에 캐싱합니다. 이미지 뷰에 표시합니다. 이미지 다운로드 이미지뷰이 이미지를 설정할 때 캐싱이 되어있지 않으면 다운로드 합니다. case .network(let resource): let downloader = options.downloader ?? self.downloader let task = downloader.downloadImage( with: resource.downloadURL, options: opti

[iOS] swift lint를 코코아 팟 없이 사용하기

이미지
[iOS] swift lint를 코코아 팟 없이 사용하기 스위프트로 프로그래밍을 하면서 swift 코딩스타일 에 맞춰서 코딩을 하도록 도와줄 장치를 찾아보니 swiftLint를 만나게 되었습니다. 사용 방법에 대한 설명을 공식문서 에 제일 잘 나와있기 때문에 첨부만 해 놓겠습니다. 기존의 프로젝트와는 다르게 코딩의 규칙은 설치되어 있어야 하기 때문에 $ brew install swiftlint 로 설치 해줍니다. Xcode를 실행해서 타겟에 새로운 "Run Script"을 눌러서 추가해 줍니다. if which swiftlint >/dev/null; then swiftlint else echo "warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint" fi 설치 후 실행하면 에러나 워닝들이 빡! autocorrect 옵션을 추가해주면, 빌드 했을 때 autocorrect 해줍니다. if which swiftlint >/dev/null; then swiftlint autocorrect else echo "warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint" fi 빈 파일을 추가해 줍니다. 이름은 반드시 .swiftlint.yml 여야 합니다. 그리고 추가한 파일 안에 규칙들을 적어놓습니다. 규칙 보러가기 # By default, SwiftLint uses a set of sensible default rules you can adjust: disabled_rules: # rule identifiers turned on by default to exclude from running - colon - co

[iOS] Firebase Realtime Database 에 데이터 넣어보기

이미지
[iOS] FirebaseDatabase 파이어 베이스를 이용해서 데이터 저장하고 읽어오기 앱을 만들다보니, 데이터를 저장하고 저장된 데이터를 읽어서 보여주어야 하는 상황에 놓이게 되었습니다. 처음에는 변수나 더미 데이터를 만들어서 저장하고 불러왔지만, 결국에는 서버를 셋팅 해야하나 라는 고민을하게 되었습니다. 그러다가 발견한 파이어 베이스의 기능 중 하나인 Database를 간단하게 사용한 방법에 대해 정리해 놓겠습니다. install 파이어 베이스를 사용하기 위해서는 패키지를 설치 해 줘야합니다. 공식 문서를 보고 설치하면 어렵지 않습니다. 귀찮으신 분들을 위해 간략히 적어놓자면, Xcode의 SwiftPackageManager를 사용해 https://github.com/firebase/firebase-ios-sdk.git 를 추가하면 됩니다. 그 중에서도 FirebaseDatabase 를 꼭 설치해주세요. Firebase에서 새 프로젝트를 만드신 후에 iOS프로젝트를 추가 해 줍니다. 설명을 따라 진행하면 어렵지 않게 완료할 수 있습니다. 핵심은 번들ID를 잘 입력 해주는 것과 GoogleService-Info.plist 파일을 잘 다운받아 내 프로젝트에 넣어주는 것 입니다. Data firebaseDatabase는 JSON 형식의 데이터를 지원합니다. 간단히 JSON을 설명 드리면, 키 - 밸류 로 이루어진 데이터 포맷입니다. 우리는 간단한 JSON형식의 데이터를 작성해 볼것 입니다. 예제 데이터는 아래와 같이 생겼습니다. { user { age : 31, married : false name : "hyunho" } } Data Write 데이터 베이스가 비어있으니 일단 쓰는 기능부터 구현해 보겠습니다. import Firebase let testItemsReference = Database.database().referen

Xcode에서 storyBoard없이 개발하기 - Tabbar 만들기

이미지
Xcode에서 storyBoard없이 개발하기 - Tabbar 만들기 개인적으로는 스토리보드를 가지고 개발하는 것이 좋다고 생각합니다. 하지만 스토리 보드 없이 개발을 하면 완벽하게 어떤 과정이 UI적인 storyBoard를 통해서 동작하는지 알 수 있기 때문에 만들면서 공부하면서 기록을 남겨놓습니다. 스토리 보드없이 개발 할 수있는 환경을 구축했다면, Tabbar를 사용해서 2개의 tabbarItem을 가진 앱을 만들어 봅시다. 구조 스토리 보드가 없기 때문에 어떤 구조를 가지고 있는지 머리에 명확히 가지고 시작해야 합니다. 우리가 만들 앱의 큰 틀은 하나의 tabbar에 2개의 view가 각각 navigationController로 조작을 하는 구조입니다. tabbarController 추가 window?.rootViewController 부분에 rootViewController를 설정해주어야합니다. 우리는 tabbar를 컨트롤 할 tabbarController 를 할당해 주겠습니다. let tabbar = UITabBarController() UITabBar.appearance().tintColor = .systemGreen tabbar.viewControllers = [네비게이션컨트롤러1, 네비게이션컨트롤러2] window?.rootViewController = tabbar 이렇게 2개의 네비게이션 컨트롤러를 tabbar에 추가해 줄 수 있습니다. 각 view추가 tabbar를 만들었으니 이제 각 탭을 넣었을 때, 호출할 view들을 추가해줍니다. // first tabBarItem let searchVC = SearchVC() searchVC.title = "search" searchVC.tabBarItem = UITabBarItem(tabBarSystemItem: .search, tag: 0) UINavigationController(rootViewCont

[IOS] How to delete macOS App, tvOS App 1.0 Prepare for Submission

이미지
[IOS] How to delete macOS App, tvOS App 1.0 Prepare for Submission appstoreconnect에서 실수로 macOS App, tvOS App의 1.0 버전을 만들어 버렸습니다. 괜찮겠지 싶어서 그냥 내버려 두었더니 심사요청할 때, 관련 정보들을 채우라는 경고문이 나와서 지우는 방법에 대해 기록으로 남겨둡니다. 앱 심사요청 바로 직전 단계라면 간단합니다. 마우스를 버전에 올려보면 빨간 삭제 버튼이 나타납니다. 버튼을 눌러 삭제 해 줍시다. 하지만 문제는 이 버튼이 나타나지 않을 경우입니다. 여러가지 이유로 나오지 않을 수 있을텐데 제가 경험한 부분은 앱의 생성이나 삭제 권한이 없을 때 새로 출시 할 버젼이 없을 때 였습니다. 1번의 경우에는 관리자에게 권한을 받아 삭제하시면 됩니다. 2번의 경우, 출시 할 새로운 버젼을 추가 하시고 다시 마우스를 가져가 보시면 빨간 버튼이 생기고 삭제를 할 수 있게됩니다.

[IOS] 어플리케이션의 생명 주기 - Life Cycle of Application

이미지
[IOS] Application Life Cycle 앱의 생명주기는 앱의 사용과정 중 가지는 상태값 입니다. foreground, background을 오가며 앱의 상태값이 바뀝니다. 크게 5개의 상태를 가지고 개발자가 상태에 맞게 개발할 수 있도록 인터페이스를 제공합니다. 상태 Not Running(Terminated) : 앱이 시스템에 의해 완전히 종료된 상태입니다. 혹은 아직 실행되지 않았을 때도 Not Running 상태입니다. Inactive(Foreground) : 앱이 실행 중인 상태입니다. 하지만 이벤트를 받지는 않습니다. Active 상태로 넘어가기 전에 앱은 반드시 이 상태를 거칩니다. 알림 같은 특정 알림창이 화면을 덮어서 앱이 event를 받지 못하는 상태가 여기에 해당됩니다. Active(Foreground) : 앱이 실행 중이고 이벤트를 받을 수 있는 상태입니다. Foreground 상태에 있는 앱들은 보통 이 상태입니다. Background : 앱 사용중에 다른 앱을 실행하거나 홈 화면으로 나갔을 때 상태입니다. 백그라운드에서 동작하는 코드를 추가하면 suspended 상태로 넘어가지 않고 백그라운드 상태를 유지하게 됩니다. 처음부터 background 상태로 실행되는 앱은 inactive 대신 background 상태로 진입합니다. 음악을 실행하고 홈 화면으로 나가도 음악이 나오는 상태가 이 경우에 해당됩니다. Suspended : 앱이 background 상태에서 추가적인 작업을 하지 않으면 곧바로 suspended 상태로 진입합니다. 앱을 다시 실행할 경우 빠른 실행을 위해 메모리에만 올라가 있습니다. 메모리가 부족한 상황이 되면 iOS는 suspended 상태에 있는 앱들을 메모리에서 해제시켜서 메모리를 확보합니다. OverView 전체적인 그림을 놓고 봤을 때 Not Running 상태에서 Inactive 전환되기까지 거치는 단계가 있다. 그리고 Inactive에