기어가더라도 제대로

iOS 주요 등장 인물들 본문

UIKit 기초

iOS 주요 등장 인물들

Damagucci-juice 2022. 7. 8. 15:50

iOS 주요 등장 인물들

공식 문서를 보면서 중요하다고 생각되는 부분을 정리하였습니다. 독해가 수월하시면(수월하지 않아도) 공식문서를 보시는 걸 추천드립니다.

App and Environment

UI Scene의 생명주기를 관리하고, 당신의 앱이 어떤 환경에 있는지에 대한 정보를 얻으세요.

  • iOS 13 버전 이후로는 사용자가 app UI 를 여러개 생성하고 관리할 수 있음
  • App Switcher 라는 것을 통해서 그 사이를 전환할 수 있다.

여러 UI의 인스턴스

  • 앱은 노트앱 하난데 두개의 UI 인스턴스를 띄운 모습

Managing Your App's Life Cycle

앱이 foreground로 나오거나 background 로 들어갈 때 시스템 노티피케이션에 반응하고, 다른 중요한 시스템에 관련된 이벤트를 핸들링하세요.

  • 앱의 현재 상태가 그 앱이 무엇을 할 수 있고 할 수 없는지를 결정한다.
  • Foreground 상태에 있는 앱은 시스템 자원에 우선권을 갖는다.
  • Background 상태에 있는 앱은 가능한한 최소한의 일만을 해야한다.
  • 당신의 앱은 이러한 상태 변화에 대응해야한다.
  • iOS 13 부터 UISceneDelegate 라는 객체를 앱에 생명주기 이벤트에 반응하기 위해 사용하세요.
    • 12 혹은 이전 버전은 UIApplicationDelegate 객체에서 앱의 생명주기 이벤트를 관리하세요.

Scene 기반의 생명 주기 이벤트에 반응하기

  • Scene : 디바이스에서 작동하는 앱 UI의 인스턴스
    • 위의 사진에서 Scene 은 두개다.
  • Scene 마다 각자의 생명주기를 가지고 있으며, 한 앱에 여러 Scene을 가지는 것도 가능하다.
  • Scene 의 생명주기 (이하 Scene == 씬)
  1. 사용자나 시스템이 앱의 새로운 씬을 요청하면, UIKit 이 새로운 씬을 만들고, 이를 "unattached state"에 놓는다.
  2. 사용자 요청 씬은 즉시 Foreground 로 가고, 시스템 요청 신은 사건만 처리하도록 backgroud로 간다.
  3. 사용자가 Scene을 dismiss(해산, 해고?) 하면 UIKit 이 씬을 백그라운드 상태로 보냈다가, 결국엔 "suspend" 상태로 보낸다.
  4. UIKit은 background 나 suspend 된 언제나 씬의 자원을 회수 할 수 있으며, 반환된 씬은 unattached state 로 보내진다.

Scene-base life cycle

다른 중요한 이벤트에 반응

* 메모리 경고
* 보호 받는 데이터를 잠금 / 잠금 해제(사용자 lock)
* 시간 변경
* URL Open

Responding to the Launch of Your App

  • 사용자가 앱 아이콘을 클릭하면, 시스템이 앱을 시동시킨다.
  • 시스템 자체가 시동을 걸 수도 있는데 이 경우 백그라운드 상태에서 작동한다.
  • 모든 앱은 UIApplication 이라는 객체로 대표되는 비슷한 처리 절차를 가지고 있다.
  • Scene 기반의 앱들은 앱의 런치나 종료 같은 근본적인 이벤트에 대응하기 위해 AppDelegate를 사용한다.
  • 런치시에 UIKit 은..
    • UIApplication 객체 생성
    • App Delegate 생성
    • 앱의 메인 이벤트 루프를 시작한다.

런치 스토리 보드를 사용하세요

  • 앱이 처음 시동걸리면 보여지는 첫화면

앱의 데이터 구조체들을 시작하세요.

  • 구체적인 경로에 파일 생성
  • 앱이 사용하는 중요 서비스들에 연결

오래 걸리는 작업들은 메인 스레드로 옮기세요.

  • UIKit 은 application(_ :didFinishLaunchingWithOptions:) 가 반환되기 전까진 UI를 띄우지 않는다.
  • application(_ :willFinishLaunchingWithOptions:) 메서드에서 오래 걸리는 작업을 구성할 경우 사용자가 화면을 보기 까지 시간이 오래 걸려 앱이 느려보인다.
  • 앱이 즉시 필요로 하지 않는 데이터들을 위의 메서드에서 생성하는 것을 막으세요.
  • 중요하지만 오래 걸리는 작업들은 global dispatch queue 에서 비동기적으로 실행하세요.

UIApplication

  • 앱당 하나의 UIApplication 인스턴스를 갖는다.
  • 앱이 시작하면 시스템이 UIApplicationMain(::::) 메서드를 호출한다.
    • 이 메서드가 싱글턴 객체인 UIApplication 을 생성한다.
  • 유저 이벤트의 초기 라우팅을 담당
  • 컨트롤 객체로부터 UIApplication 으로 온 액션 메세지들을 적절한 타깃 객체들에게 전파
  • UIWindow 의 목록을 가지고 있다.
    • UIWindow 위에 UIView를 그릴 수 있다.
  • UIApplicationDelegate 프로토콜을 준수하는 대리자를 정의한다.
  • UIApplication 은 중요한 런타임 사건들에 대해 Delegate 에게 알린다.
    • 앱의 시작
    • 저 메모리 경고
    • 앱 종료
  • 알리므로써 적절하게 대응할 기회를 제공한다.

UIApplicationDelegate

  • 앱의 공유 행위들을 관리
  • 앱의 Root 객체
  • 시스템과 상호작용을 관리하기 위해 UIApplication 과 함꼐 일한다.
  • UIApplication 처럼 항상 존재하도록 UIKit 이 앱의 시작에 생성한다.
  • 주로 하는 일
    • 앱의 데이터 구조체들을 생성
    • 앱의 씬들을 구성
    • 앱 외부에서 온 알림들에 대응
      • 저 메모리 경고
      • 다운로드 완료
    • 특정 VC나 View, Scene 이 아닌 앱 자체를 타깃으로 온 이벤트에 대응
    • Apple Push Notification 과 같은 필수 서비스들을 앱이 시작할 때 등록
  • iOS 12 나 그 이전엔 앱이 foreground, background 로 상태 변화할 때 처리할 메서드도 관리

Preparing Your UI to Run in the Foreground

  • UI 가 화면에 나타나는 것을 대비
  • 유저 액션에 반응하기 위해서가 대부분
  • UI를 구동하기 위한 자원 준비
  • 유저 요청을 다루기 위해 필요한 서비스 시작
  • 모든 상태 전환은 결국 UIKit 이 적절한 대리인 객체로 알림을 보내게 된다.
    • iOS 13 과 그 이후 - UISceneDelegate
    • iOS 12 와 그 이전 - UIApplicationDelegate
  • 앱이 둘 다를 지원할 경우 우선적으로 UISceneDelegate로 알림을 보낸다.

Foreground 로 들어갈 때 데이터 모델을 업데이트

  • Foreground 로 진입하기전에 앱은 Inactive 상태에 있다.
  • 시작시 필요한 일을 처리하기위해 "launch-time" 메소드를 사용
  • 백그라운드 상태에 있는 앱의 경우에, UIKit 이 다음의 메서드 중 하나를 사용해 앱을 Inactive 상태로 보냄
    • Scene 기반 앱 - sceneWillEnterForeground(_:)
    • 그 외 앱 - applicationWillEnterForeground(_:)
  • 이 메서드들은 자원을 디스크로부터 로드하고 네트워크로부터 데이터를 fetch 해옴

UI 와 활성화 시에 초기 Task 구성

  • UI를 띄우기 전에 즉시 앱을 Active 상태로 보낸다.
  • 따라서 Activation 상태는
    • UI 구성과 런타임 행위를 하기에 좋은 때다.
      • 필요하다면 window 를 나타내기
      • 필요하다면 현재 볼 수 있는 VC를 변경하기
      • 뷰와 상태들의 값을 업데이트
      • 일시 정지 상태의 게임을 재개
      • 실행 Task를 하기위해 사용하는 Dispath Queue 를 시작하거나 재개
      • Datasource 객체를 업데이트
      • 주기적인 Task를 위한 타이머 시작
    • 이런 설정 업무들을
      • Scene 기반앱 - sceneDidBecomeActive(:_) 메서드에 정의하세요.
      • 그 외 앱 - applicationDidBecomeActive(:_) 메서드에 정의하세요.
  • UI 작업을 마무리 하기 위한 때다.
  • Activation 메서드를 막을 우려가 있는 코드를 실행하지 마세요.
  • 예를들어 데이터가 자주 변화하는 작업의 경우, 앱이 백그라운드 상태에 있을 때 네트워크 요청작업을 하고, 포어그라운드로 진입하세요.
  • 아니면 변화 데이터를 fetch 해오는 것을 비동기적으로 하는 동안 이미 가지고 있는 데이터를 보여줄 준비를 하세요.

"View Appear" 할 때 UI에 특화된 Task 시작하기

  • VC의 viewWillAppear(:_) 같은 메서드를 활용하세요.
    • UI 애니메이션 작업
    • 미디어 파일 재생
    • 그래픽 작업

Preparing Your UI to Run in the Background

Prepare your app to be suspended

  • suspend 상태로 가기 전에 background 상태에서 마지막 마무리를 준비
  • 가능한 일을 안하는게 좋다.
  • 그래도 해야한다면 ...
    • 하던일 멈추기
    • 공유 자원 릴리즈 하기
  • UIKit 이 다음으로 알림을 보냅니다.
    • iOS 13 - UISceneDelegate 객체
    • iOS 12 - UIApplicationDelegate 객체

Deativation 상태

  • 사용자가 앱을 종료
    • background 상태로 가기 전에 Deactivation 상태에 잠시 머무름
  • 시스템이 잠시 중단 할 수 있다.
    • alert를 띄우려고
      • 사용자가 경고 창을 내리면 시스템이 앱을 다시 reactive하게 한다.
  • Scene 을 지원하는 앱 - sceneWillResignActive(_:)
  • 그 외 앱 - applicationWillResignActive(_:)
  • 필요하다면 중요 작업을 멈추기 위해 다음의 일을 수행하세요
    • 열려 있는 파일 닫기, 유저 정보 저장
    • Dispatch Queue, Operation Queue 중단
    • 실행을 위한 새로운 작업 스케쥴 금지
    • 타이머 무효화
    • 게임 일시 정지

Background 에 들어서면 자원 릴리즈

  • 백그라운드 상태에 들어가면 보유하고 있던 공유 자원과 메모리를 릴리즈하세요.
  • 메모리 해제가 특히 중요
  • 포어그라운드일 때 잡고 있던 메모리를 백그라운드 상태에 가면 놓아야한다.
  • 앱이 더 이상 포어그라운드 상태에 있지 않는다면, 가능한 자원을 적게 소모하도록 다음의 항목들을 체크하세요.
    • 파일에서 직접 읽은 이미지나 미디어 파일 폐기(메모리에서 놓아주기)
    • 메모리가 큰 객체 해제
    • 카메라나 공유 하드웨어 자원 해제
    • UI의 유저 중요 정보 가리기(PW)
    • alert 와 다른 일시적인 UI 해산
    • DB 와 연결 끊기
  • asset 에 이름을 등록한 이미지는 폐기할 필요 없습니다.
  • 비슷하게 Cache 객체를 사용하여 관리히는 NSDiscardableContent 도 별도 해제할 필요 없습니다.
  • 백그라운드에 가서도 카메라 같은 공유 자원을 여전히 잡고 있으면 시스템이 앱을 terminate 시켜버립니다.

App Snapshot 준비하세요.

  • 앱의 현재 UI 상태를 스냅샷 뜹니다.
  • 그 결과 나온 이미지를 App Switcher 에 띄웁니다.
    • 어떤 민감정보도 나타나면 안됩니다.(은행앱을 생각해보세요)

Background 에서 중요 이벤트에 대응하세요.

백그라운드 상태에 가면 일을 안하는게 맞으나, 몇몇 경우엔 시간-민감한 일을 처리해야할 경우가 있습니다.

  • AirPlay, Picture
  • Location- 민감한 서비스
  • Voice over IP
  • 외부 장치와 커뮤니케이션
    • 블루투스
  • 서버로 정기적인 업데이트
  • APN(Apple Push Notification) 지원

screen captures

UIWindowScene

  • 앱의 UI 인스턴스 하나를 관리하는 객체

  • 여러 윈도우를 포함할 수 있음

  • 포함 관계

    • UIWindowScene : UIWindow = 1 : N
  • WindowScene 객체

    • Window 의 디스플레이를 관리
    • Scene 의 생명주기를 관리
  • 대리인이 UIWindowSceneDelegate 이다.

  • screen captures

  • 한 화면을 채우는 것도 씬

  • 하나의 윈도우를 나타내는 것도 씬

  • 용어 정리가 필요하다.

UIWindowSceneDelegate

  • UI의 인스턴스의 생명주기를 관리
  • UISceneDelegate 프로토콜 채택
  • Scene 이 포어 그라운드에 진입했는지, 백그라운드로 들어갔는지, 등을 알림을 받는다.
  • 앱이 놓인 환경에 대한 알림을 받음
    • 유저가 창의 사이즈를 줄였다는 알림을 받는 것도 이 곳
    • 적합한 사이즈로 화면 크기를 조정해야한다.

Scene 대신 WindowScene

UIScene

  • UIKit 은 앱의 UI 의 인스턴스 마다 Scene 을 생성한다.

  • UIKit 은 UIScene 대신 UIWindowScene 을 생성한다.

    • Scene 의 속성이나 메서드에 접근하기 위해 UIWindowScene 클래스를 사용한다.

      public class UIWindowScene: UIScene {}
  • 모든 Scene 은 각자 연관된 Delegate 를 가지고 있는데 이것이 UISceneDelegate 이다.

  • Scene 의 상태 변화가 일어나면, Scene 이 Delegate 에게 알리고, 등록한 옵저버 객체에게 적합한 알림을 전달한다.

    • Scene 의 상태변화에 대응하기 위해 Delegate 객체나 노티피케이션을 사용하세요

UISceneDelegate

  • UI 인스턴스의 생명 주기 이벤트를 관리하기 위해 사용
  • Scene의 상태변화에 대응하는 메서드가 정의되어 있음
  • 예시
    • Scene -> Foreground
    • Scene -> Background
      • 핵심적인 Task 를 완료하거나 앱을 종료

UI 계층도

Comments