Share
Sign In
[Swift - UIKit] UIViewController에서의 View life Cycle API
한결
UIViewController에서 View 객체를 로드하고 (그리고) 어떤 페이지로 전환되어 그 객체가 사라지는 과정을 관리하는 시스템을 내가 학습하기로는 View Life Cycle 이라고 한다. View 객체의 생명주기를 관리하는 UIViewController 클래스의 내장 오픈 메서드(API라고 부르겠다)는 여러가지가 있지만, 대표적으로 위 이미지의 5가지가 대표적일 것 같다.
viewWillAppear
viewIsAppearing
viewDidAppear
viewWillDisappear
viewDidDisappear
사실, API의 prefix에 붙은 키워드만 보더라도 View 객체가 어떤 상태일지에 따라 서로 다른 API가 동작한다는 것을 쉽게 유추해 볼 수 있을 것 같다. (will, -ing, did) 모달이나 페이지 전환에 따라 특정 View 객체가 어떤 생명 주기를 가지는지를 각 API에 print 구문으로 확인해봤다.
1.
XCode로 앱을 처음 빌드할 때.
UIController의 viewDidLoad가 가장 먼저 앱을 그리는 로직을 수행한다.
그리고 나서 순서대로 willAppear → isAppearing → didAppear API가 호출된다.
(prefix 만으로도 쉽게 유추가 가능하다.)
2.
버튼 액션으로 모달 페이지가 떠오를 때.
앱 화면 하단에서 떠오른 모달 페이지가 직전 View를 가리더라도, 해당 View 객체 생명 자체를 사라지게 하지 않는다.
즉, 이전 화면을 완전히 가리지 않는다면 해당 View는 생명선을 유지한다는 뜻이다. 해당 모달을 내리더라도 willAppear, isAppearing, didAppear API가 콘솔에 전혀 찍히지 않는다.
모달 페이지에서 특정 액션을 발생시켜서 뒤에 있는 View에 어떤 화면 전환이 필요하면, 그걸 처리하는 로딩 로직을 만들어야 할 것 같다.
3.
버튼 액션으로 페이지 자체가 전환될 때.
화면이 Push되어서 완전 새로운 화면이 이전 View를 가릴 경우, 해당 View 객체는 생명을 다한다.
순서대로 willDisAppear, didDisappear API가 호출된다.
즉, 화면이 전환될 경우는 화면이 꺼짐으로 발생하는 데이터 저장이나, 업데이트 로직이 해당 생명주기 API에서 처리되어야 할 것이다.
연결된 화면이 Push될 경우, 이전 View 객체는 생명을 다한다.
물론, 다시 화면으로 돌아오면 생명이 다시 붙는다.
Ha
/hankyeol
Subscribe
[Swift - UIKit] iOS에서의 기본적인 Notification System
알림센터나 사이드 푸쉬 등으로 특정 블록 형태의 UI가 뜨는 것을 Notification 이라고 한다. 카카오톡에서 친구가 채팅을 보냈을 때, 쿠팡에서 특가 상품이 떴을 때, 주변에 토스를 사용하는 사용자가 발견되었을 때와 같은 상황에서 주로 알림이 온다. 이런 기본적인 '알림'이라고 하는 것을 다룰 수 있는게 iOS Notification System이다. 내장된 User Notification Framework를 이용하여 쉽게 알림을 구현할 수 있다. 리모트 방식의 알림은 서버를 통해 인증된 유저에게만 보여줄 수 있기 때문에 APNs 라고하는 서비스를 거쳐야 한다. Notification System의 두 가지 방식 Notification 방식은 Local, Remote 형태가 있다. 이름에서 두 방식의 차이를 대강 알 수 있다. Local 알림에 전달할 내용이 전부 앱에 들어있다. 루틴한 내용이나 비슷한 컨텐츠를 전달해주는 용도로 사용된다. (디데이, 루틴, 투두 어플 등) Remote 서버단에서 보내는 알림을 컨트롤하는 형식. (푸시 알림이라고도 함) (서버에서 데이터가 오기 때문에) 유저가 알 수 없는 시간에 서로 다른 컨텐츠를 전달해주는 용도로 사용된다. 광고, 개인화된 추천, 채팅 알림(ex. 카카오톡 채팅별 알림) 등의 알림이 리모트 형식이다. Notification System에서 유의해야 할 점 Notification이 동작하기 위해서는 반드시 유저에게 권한 동의를 받아야 한다. 아이폰의 여러 앱을 써보면 알겠지만, 앱을 처음 실행할 때나 앱을 실행시키고 있는 도중에도 계속 '알림'에 대한 권한을 획득하려고 하는 뷰가 나타난다. 어떤 앱에서는 '권한이 어떤 시점에서 부여되지 않았다'는 사실을 알려주는 alert을 보여줄 때도 있다. 애플에서는 알림에 대한 유저 동의 여부를 강하게 체크한다. 무분별하게 알림을 내뱉는 앱은 앱의 사용 경험을 넘어서 아이폰의 사용 경험 자체를 헤칠 수 있기 때문에 애플에서 권한 획득을 중요하게 생각하는 것 같다. 커머스나 앱 자체로 비즈니스 가치가 발생하는 서비스들은 사용자에게 알림 권한을 획득하기 위해서 노력한다. 앱이 종료된 시점에도 우리 서비스가 있고, 우리 서비스를 통해 새로운 이점을 얻을 수 있다는 사실을 알림을 통해 간편하게 전달할 수 있기 때문이다.
한결
[Swift - UIKit] UIViewController 위에 여러 Protocol을 적용하여 동작하는 다양한 뷰 만들기
코드 베이스로 뷰를 그리는 연습을 하기 전, SB + Outlet 코드로 뷰를 그리는 연습을 하면서 최종적으로 만들어 본 TravelProject에 대한 정리 글입니다. 전체 코드는 해당 링크에서 볼 수 있습니다. Swift를 학습하면서 정말 다양한 뷰를 직접 만들어보고 있다. 24년 5월 27일부터 30일까지 스토리보드 기반으로 UIViewController 위에서 코드로 여러 화면을 그리는 연습을 했다. 그 과정에서 나 스스로 '이건 꼭 기록으로 남겨봐야겠다.' 하는 점들이 있어서 남겨본다. 1. UIViewController 위에 커스텀한 TableView 올려보기 (with. XIB) UIViewController에 UITable을 핸들링하기 위한 Delegation, Datasource 프로토콜을 적용해준다. *Protocol을 통해 delegation을 위임하는 것에 대한 내용은 요 링크로 짧게 작성해봤다. UITable에 들어갈 커스텀한 TableCell을 작업하기 위해 Swift 파일과 XIB 파일을 함께 생성해준다. XIB에서 작업한 커스텀 셀을 재사용이 가능한 셀로 만들기 위해 정확한 Identifier를 지정해줘야 한다. 이 부분 역시 UITableViewCell 클래스를 상속받는 클래스들이 identifier라는 멤버 변수를 가질 수 있도록 protocol + extension 조합으로 코드를 미리 작성해두면 편하다. UIViewController 위에 올려진 UITableView의 인스턴스에 커스텀한 Cell을 연결하고, 어떤 행에 어떤 셀을 어떻게 보여줄 것인지를 위임받은 코드에 설정해준다. 코드로 한 번 보자. 위 코드 형태가 Swift에서 테이블 뷰를 그리는 가장 기본적인 방법이다. cellForRowAt 에서 커스텀하게 생성한 TableViewCell 클래스의 인스턴스를 as 키워드로 정확하게 캐스팅 해줘야 해당 클래스 내부에 구현한 멤버 요소들을 불러와 사용할 수 있다. 2. 연결된 VC에 데이터 넘겨주기 테이블 뷰에서 특정 셀을 터치하여 선택할 경우, 연결된 페이지 뷰(UIViewController)로 데이터를 전달해야하는 경우가 있다. 여러 방법이 있겠지만, 가장 쉽다고 생각하는 방법은 해당 VC의 멤버 변수(Outlet 변수 포함)에 값을 할당하는 것이다. 테이블의 특정 셀이 선택되어 연결된 VC 인스턴스가 Present되기 전에 반드시 데이터 자체를 VC의 내부 멤버들에 할당하는 코드가 반영되어야 한다.
한결
[Swift - System] Swift의 Sandbox 시스템과 UserDefaults.
App Sandbox 시스템 App Sandbox 시스템은 유저의 데이터를 보호하는 목적으로 커널 레벨에서 앱 자체의 데이터 접근을 제어할 수 있는 기술이다. (말이 좀 어렵다.) Swift는 기본적으로 C언어 - Objective-C 언어를 기반하기 때문에 다른 가상 머신 없이 바로 커널에 명령을 쏠 수 있다. 이 과정에서 앱이 동작하는데 필요한 특정 목적의 데이터(ex. 유저의 개인 정보라던지, 네트워크 연결성 등)를 위험에서 보호한다. 위험은 다양할 수 있는데, 앱 규모가 커질수록 더 많은 위험에 노출될 수 있겠다. 샌드박스에 보관하는 데이터를 앱과 어떻게 상호작용 할지를 개발자단에서 컨트롤 하면서, 유저로부터 올 수 있는 문제를 사전에 컨트롤 할 수 있다. 이 데이터를 앱이 사용한다는 것을 유저에게 특정 *인지 이벤트로 인식시키고, 앱이 그 데이터만 활용한다는 명확성을 부여해야 하는 시스템이 샌드박스 시스템이다. 명시적으로 허락 받지 않은 접근은 런타임이 차단한다. *내가 이해한 인지 이벤트는 다음과 같다. 우리가 앱을 설치하고 처음 켰을 때, 런치 스크린 이후에 각종 동의를 받는 경험을 했을 것이다. 이런 데이터에 대한 접근 및 활용 동의가 샌드박스를 이용해 인앱에서 데이터를 관리할 수 있는 권한을 부여한다고 볼 수 있다. - 위치 기반 데이터 활용 동의 - 사진 데이터 접근 및 활용 동의 우리가 앱스토어에서 특정 앱을 설치하면 iOS는 해당 앱을 위한 샌드박스 영역을 생성한다. 위 이미지처럼 Bundle, Data, iCloud 를 위한 공간이 생성된다. 쉽게 생각해서 유저의 의도와는 상관없이 앱의 운영을 위해 읽기, 쓰기를 위한 문서 저장 공간(애플은 데이터 파일을 Documents라고 한다 보통)을 만드는 것이다. 외부 다른 앱이나 사용자가 접근하기 힘든 공간을 이용해서 앱의 보안을 높이는 시스템이라고 볼 수 있다. 앱을 실행하면, 앱은 iOS 전체 파일관리 시스템에서 자기자신의 샌드박스를 바라본다. 샌드박스에서 필요한 데이터를 활용한다. (읽고, 쓰고, 업데이트하고 다 한다) 앱을 종료한다. 해당 앱을 위한 샌드박스 위치를 자체적으로 변경한다. 앱을 다시 실행한다. 해당 앱을 위한 변경된 샌드박스 위치를 바라볼 수 있게 한다. 즉, 특정 앱을 위한 샌드박스가 늘 같은 위치에 있는 것이 아니다. User Defaults 샌드박스 내부에 해당 앱을 위한 user's defaults database가 생성된다. 이 데이터베이스는 문서형 NoSQL 데이터베이스처럼 데이터를 키-값 형태로 저장한다. 정해진 여러 필드가 있고, 하나의 데이터가 해당 필드의 값들을 가지는 관계형 데이터베이스 형태는 아니다. UserDefaults로 관리되는 데이터는 앱이 가동되거나 어떤 이벤트를 처리할 때, 기본적인 상태들을 관리한다. (공식 문서에 따르면 - determine an app’s default state at startup or the way it acts by default.) 핵심 사용 방식은 공식 문서의 다음 문장으로 정리될 것 같다. UserDefaults 클래스가 데이터를 바라보고 있다가 캐싱을 통해 데이터를 앱에 필요하게 세팅한다. 당연히 서비스 레이어에 민감하게 적용될 수 있는 데이터나 처리는 좋지 않다. At runtime, you use UserDefaults objects to read the defaults that your app uses from a user’s defaults database. set 메서드를 통해서 키-값 형태로 값을 저장하고, UserDefaults 클래스의 인스턴스를 생성해서 저장한 값을 키로 조회할 수 있다. Dictionary를 사용하는 방식과 뭔가 비슷하다.
한결