Preserving Your App's UI Across Launches

Panther·2021년 8월 13일
0

https://developer.apple.com/documentation/uikit/view_controllers/preserving_your_app_s_ui_across_launches

"Return your app to its previous state after the system terminates it."

시스템 종료 후 앱을 이전 상태로 되돌립니다.

Overview

앱의 UI를 보존하는 것은 앱이 항상 작동하고 있는 착각을 유지하는 데 도움이 됩니다. iOS 기기에서 인터럽션은 빈번히 발생할 수 있고, 인터럽션이 길어지는 것은 시스템이 리소스 확보를 위해 앱을 종료시킬 수도 있게 합니다. 그러나 사용자는 앱이 종료되었는지 알 수 없고 앱애 변경된 상태임을 기대하지 않을 것입니다. 대신 사용자는 앱에서 빠져나왔을 때도 같은 상태로 있을 것임을 기대할 것입니다. 상태 보존 및 복원은 앱이 다시 launch 되었을 때 이전 상태로 되돌아가는 것을 보장해줍니다.

적합한 시점에 UIKit은 앱의 뷰와 뷰 컨트롤러 상태를 디스크에 있는 암호화된 파일에 저장합니다. 앱이 종료되었다가 이후에 다시 launch 되면, UIKit은 보존된 데이터로부터 뷰와 뷰 컨트롤러를 재구성합니다. 보존 및 복원 과정은 자동으로 초기화되지만, 이와 같은 과정을 지원하려면 몇 가지 특정 작업을 수행해야 합니다.

  • 상태 보존 및 복원에 대한 지원을 활성화합니다.
  • 보존하고자 하는 뷰 컨트롤러에 복원 아이덴티파이어를 할당합니다.
  • 복원 시점에 필요한 경우 뷰 컨트롤러를 재생성합니다.
  • 뷰 컨트롤러를 이전 상태로 복원하는 데 필요한 커스텀 데이터를 인코딩 하고 디코딩합니다.

인터페이스 전체를 스토리보드에서 정의하는 경우 UIKit은 뷰 컨트롤러를 재생성할 방법에 대해 알고 있습니다. 그리고 자동으로 이를 수행합니다. 스토리보드를 사용하지 않거나 뷰 컨트롤러의 생성 및 초기화를 더 제어하길 원한다면, 뷰 컨틀로러르 스스로 직접 생성할 수 있습니다.

상태 보존 및 복원에 대한 예시는 Restoring Your App’s State를 살펴보시기 바랍니다.

Restoring Your App’s State
https://developer.apple.com/documentation/uikit/uiscenedelegate/restoring_your_app_s_state

Enable State Preservation and Restoration for Your App

앱 딜리게이트의 application(_:shouldSaveApplicationState:), application(_:shouldRestoreApplicationState:) 메소드 구현을 통해 상태 보존 및 복원을 선택할 수 있습니다. 두 메소드는 관련 프로세스가 발생해야 하는지 여부를 나타내는 불리언 값을 반환하며, 대부분의 경우 단순하게 true를 반환하면 됩니다. 그러나 앱의 인터페이스 복구가 적합하지 않은 경우에 대해서 false를 반환할 수도 있습니다.

UIKitapplication(_:shouldSaveApplicationState:) 메소드를 호출할 떄, true를 반환하는 것과 더불어 데이터를 저장할 수도 있습니다. 복원 과정 동안 사용하길 의도한 데이터를 저장하게 될 것입니다. 예를 들어 Listing 1은 앱의 현재 버전 넘버를 저장하는 예시를 보여줍니다. 복원 시점에 application(_:shouldRestoreApplicationState:) 메소드가 아카이브에서 버전 넘버를 확인하고, 기대되는 버전과 일치하지 않는 경우 복원 발생을 막습니다.

Listing 1 Declaring support for state preservation and restoration

func application(_ application: UIApplication, 
            shouldSaveApplicationState coder: NSCoder) -> Bool {
   // Save the current app version to the archive.
   coder.encode(11.0, forKey: "MyAppVersion")
        
   // Always save state information.
   return true
}
    
func application(_ application: UIApplication, 
            shouldRestoreApplicationState coder: NSCoder) -> Bool {
   // Restore the state only if the app version matches.
   let version = coder.decodeFloat(forKey: "MyAppVersion")
   if version == 11.0 {
      return true
   }
    
   // Do not restore from old data.    
   return false
}

복원을 막는 경우에도 여전히 앱 딜리게이트의 application(_:didFinishLaunchingWithOptions:) 메소드에서 앱의 인터페이스를 설정할 수 있습니다.

Assign Restoration Identifiers to Your View Controllers

복원 아이덴티파이어 할당을 통해 어떤 뷰 컨트롤러를 보존할 것인지에 대해서 UIKit에게 명시적으로 알려줘야 합니다. 복원 아이덴티파이어는 코드 작성 혹은 인터페이스 빌더로 뷰 컨트롤러에 할당하는 고유한 스트링입니다. 뷰 컨트롤러 클래스의 이름은 보통 적합한 복원 아이덴티파이어이지만, 다른 스트링을 사용해도 됩니다. 스토리보드 파일에서 뷰 컨트롤러에 해당 스트링을 추가하거나 런타임에 뷰 컨트롤러의 restorationIdentifier 속성에 해당 스트링을 할당해야 합니다.

Figure 1 Specifying a restoration identifier in the storyboard

보존 시점에 UIKit은 앱 윈도우의 루트 뷰 컨트롤러 보존을 시도합니다. 복원 아이덴티파이어를 갖는 각각의 루트 뷰 컨트롤러에서 UIKit은 아카이브 속에 커스텀 데이터를 인코딩해야 함을 해당 뷰 컨트롤러에게 요청합니다. 컨테이너 뷰 컨트롤러는 커스텀 데이터의 일부로써 자식 뷰 컨트롤러에 레퍼런스를 인코딩할 수 있습니다. 만약 그렇게 하는 경우, 그리고 해당 뷰 컨트롤러가 복원 아이덴티파이어 역시 갖고 있는 경우, UIKit은 자식 뷰 컨트롤러 및 자식 뷰 컨트롤러의 컨텐츠 보존을 시도합니다. 이 과정은 재귀적으로 계속되며, 모든 뷰 컨트롤러가 저장되거나 무시될 때까지 하나의 뷰 컨트롤러로부터 다음까지의 연결에 따라 계속합니다..

모든 뷰 컨트롤러에 복원 아이덴티파이어 할당이 필요하진 않습니다. 어떤 경우에 모든 뷰 컨트롤러의 보존을 원하지 않을 수도 있습니다. 예를 들어 앱이 일시적인 로그인 스크린을 표시하는 경우 스크린이 보존되지 않길 원할 것입니다. 대신 복원 시 표시 여부에 대해 결정하길 원할 것입니다. 이 경우 로그인 스크린 뷰 컨트롤러에 복원 아이덴티파이어를 할당하지 않아야 합니다.

어떤 것이 보존되는지에 대한 더 자세한 정보는 About the UI Preservation Process를 살펴보시기 바랍니다.

About the UI Preservation Process
https://developer.apple.com/documentation/uikit/view_controllers/preserving_your_app_s_ui_across_launches/about_the_ui_preservation_process
https://velog.io/@panther222128/About-the-UI-Preservation-Process

Encode and Decode Custom Information for Your App

보존 과정이 진행되는 동안 UIKit은 각각의 보존된 뷰 및 뷰 컨트롤러의 encodeRestorableState(with:) 메소드를 호출합니다. 뷰 혹은 뷰 컨트롤러의 현재 상태를 되돌리는 데 필요한 정보를 보존하기 위해 이 메소드를 사용하시기 바랍니다.

  • 뷰 및 컨트롤의 시각적 상태에 대한 세부사항을 저장해야 합니다.
  • 보존하길 원하는 자식 뷰 컨트롤러에 대한 레퍼런스도 저장해야 합니다.
  • 사용자의 데이터에 영향을 미치지 않고 버려질 수 있는 정보를 저장해야 합니다.
  • 앱의 영구 저장소에 이미 존재하는 데이터를 포함시키지 않아야 합니다. 대신 해당 데이터를 이후에 위치시키는 데 사용할 수 있는 아이덴티파이어를 포함시켜야 합니다.

상태 보존은 앱 데이터를 디스크에 저장하는 것에 대한 대체재가 아닙니다. UIKit은 재량에 다라 상태 보존 데이터를 버릴 수 있으며, 이는 앱을 기본값 상태로 되돌릴 수 있도록 해줍니다. 현재 선택된 테이블의 행과 같은 앱의 UI 상태에 대한 정보를 저장하기 위해 보존 프로세스를 사용해야 합니다. 해당 테이블에 포함된 데이터 저장을 위해 사용해서는 안 됩니다.

Listing 2는 first name과 last name을 수집하는 텍스트 필드를 갖는 뷰 컨트롤러의 예시를 보여주고 있습니다. 만약 텍스트 필드 중 한 가지가 저장되지 않은 값을 포함한다면, 메소드는 저장되지 않은 값과 어떤 텍스트 필드가 값을 포함하고 있는지에 대한 아이덴티파이어를 저장합니다. 이 경우 저장되지 않은 값은 앱의 영구 데이터의 부분이 아닙니다. 이는 필요한 경우에 따라 버려질 수 있는 일시적인 값입니다.

Listing 2 Encoding the state of a view controller

override func encodeRestorableState(with coder: NSCoder) {
   super.encodeRestorableState(with: coder)
        
   // Save the user ID so that we can load that user later.
   coder.encode(userID, forKey: "UserID")

   // Write out any temporary data if editing is in progress.
   if firstNameField!.isFirstResponder {
      coder.encode(firstNameField?.text, forKey: "EditedText")
      coder.encode(Int32(1), forKey: "EditField")
   }
   else if lastNameField!.isFirstResponder {
      coder.encode(lastNameField?.text, forKey: "EditedText")
      coder.encode(Int32(2), forKey: "EditField")
   }
   else {
      // No editing was in progress.
      coder.encode(Int32(0), forKey: "EditField")
   }
}

UIKit이 앱의 뷰, 뷰 컨트롤러, 상태 정보를 어떻게 보존하는지에 대한 더 많은 정보는 About the UI Preservation Process를 살펴보시기 바랍니다.

About the UI Preservation Process
https://developer.apple.com/documentation/uikit/view_controllers/preserving_your_app_s_ui_across_launches/about_the_ui_preservation_process
https://velog.io/@panther222128/About-the-UI-Preservation-Process

Create View Controllers When Asked

만약 보존된 상태 정보가 앱 launch 시점에 사용 가능하다면, 시스템은 보존된 데이터를 사용해 앱의 인터페이스 복구를 시도합니다.

  1. UIKit은 앱 딜리게이트의 application(_:shouldRestoreApplicationState:) 메소드를 호출해서 복원이 진행되어야 하는지를 결정합니다.
  2. UIKit은 뷰 컨트롤러를 재생성하기 위해서 앱의 스토리보드를 사용합니다.
  3. UIKit은 각 뷰 컨트롤러가 갖는 상태 정보 복원을 위해 각 뷰 컨트롤러의 decodeRestorableState(with:) 메소드를 호출합니다.

UIKit은 초기에 스토리보드로부터 뷰 컨트롤러 및 뷰 컨트롤러의 뷰 모두를 로드합니다. 해당 객체들이 로드되고 초기화된 후, UIKit은 상태 정보 복원을 시도합니다. 뷰 컨트롤러를 이전 상태로 되돌리기 위해 decodeRestorableState(with:) 메소드를 사용하시기 바랍니다.

Listing 3은 Listing 2에서 인코딩 했었던 상태를 디코딩하는 메소드에 대해 보여주고 있습니다. 이 메소드는 보존된 사용자 ID로부터 뷰 컨트롤러의 데이터를 복원합니다. 텍스트 필드가 편집되고 있었다면, 이 메소드는 진행중이었던 값을 복원하고, 해당 텍스트 필드에 대한 키보드를 표시할 수 있도록 상응하는 텍스트 필드를 첫 번째 리스폰더로 만듭니다.

Listing 3 Decoding the

override func decodeRestorableState(with coder: NSCoder) {
   super.decodeRestorableState(with: coder)
   
   // Restore the first name and last name from the user ID
   let identifier = coder.decodeObject(forKey: "UserID") as! String
   setUserID(identifier: identifier)

   // Restore an in-progress values that was not saved
   let activeField = coder.decodeInteger(forKey: "EditField")
   let editedText = coder.decodeObject(forKey: "EditedText") as! 
                         String?

   switch activeField {
      case 1:
         firstNameField?.text = editedText
         firstNameField?.becomeFirstResponder()
         break
            
      case 2:
         lastNameField?.text = editedText
         lastNameField?.becomeFirstResponder()
         break
            
     default:
         break  // Do nothing.
  }
}

스토리보드에서 뷰 컨트롤러를 정의하는 것은 상태 복원을 관리하는 가장 쉬운 방법이지만 유일한 방법은 아닙니다. 다른 방법을 통해 뷰 컨트롤러를 재생성하는 것에 대한 더 많은 정보는 About the UI Restoration Process를 살펴보시기 바랍니다.

About the UI Restoration Process
https://developer.apple.com/documentation/uikit/view_controllers/preserving_your_app_s_ui_across_launches/about_the_ui_restoration_process
https://velog.io/@panther222128/About-the-UI-Restoration-Process

Topics


Process Details

About the UI Preservation Process

UIKit 상태 보존 프로세스를 커스터마이징 하는 방법에 대해 알아봅니다.

https://developer.apple.com/documentation/uikit/view_controllers/preserving_your_app_s_ui_across_launches/about_the_ui_preservation_process
https://velog.io/@panther222128/About-the-UI-Preservation-Process

About the UI Restoration Process

UIKit 상태 복원 과정을 커스터마이징 하는 방법에 대해 알아봅니다.

https://developer.apple.com/documentation/uikit/view_controllers/preserving_your_app_s_ui_across_launches/about_the_ui_restoration_process
https://velog.io/@panther222128/About-the-UI-Restoration-Process


0개의 댓글