티스토리 뷰

iOS

iOS 13+ ) Restoring Your App’s State

Zedd0202 2020. 6. 25. 01:03
반응형

 

안녕하세요 :) Zedd입니다.

tmi지만...WWDC 키노트를 기다리며..이 글을 쓰고 있네요. 졸리지만 올해는 꼭 보겠어...

아무튼 오늘은...App state restoration에 대해 공부해보려고 합니다.

App state restoration이 모냐,...

내가 앱에서 특정 화면으로 간 상태야

근데 앱을 껐어

다시 켰을 때 그 특정화면부터 시작했으면 좋겠어!!!

할 때 

state restoration에 대해서 공부하시면 됩니다. 

https://developer.apple.com/documentation/uikit/uiviewcontroller/restoring_your_app_s_state

위 움짤에 있는 앱은 애플 샘플 코드입니다. 링크에 가시면 샘플 프로젝트를 다운로드 받으실 수 있어요! 

자 위 gif파일을 보시면,

앱을 껐다 다시 켰는데 내가 마지막으로 머물렀던(?) 화면부터 시작하는 것을 볼 수 있습니다!

이런걸 하려면 어떻게 해야할까요!?

 

시작해봅시다.

근데 시작하기전에 가장가장 중요한 사실이 있습니다!

상태 보존 방식이 2가지가 있다는 사실에요!

iOS13이상에서는 앱은 NSUserActivity객체를 사용해서 각 window scene의 상태를 저장하고

그 이전버전(iOS12이하)에서 앱은 ViewController의 configuration을 저장하고 복원하는 방식입니다.

 

흠 그럼 저는..일단 iOS13+ 에서 어떻게 하는지 보려고 합니다.

즉!! NSUserActivity객체를 사용해야겠네요~

 

 

시작하기 전에, 아마 이 글을 읽으시는 분들은 App state restoration을 앱에 적용시키려고 들어오셨겠죠..?!

적용시키기 전에, developer.apple.com/documentation/foundation/nsuseractivity

 

Apple Developer Documentation

 

developer.apple.com

이걸 자세히 읽어보고 시작하시는 것을 추천드립니다.

위 문서에 따르면,

NSUserActivity는 앱의 모든 작업을 추적하기 위한 것이 아니고,

작은 편집 또는 기타 사소한 변경에는 사용하지 않아야 한다고 나와있거든요.

중요한 체크포인트에서만 사용하라고 나와있습니다!

 

자 그럼 시작해보겠습니다. 

제가 오늘 만들앱은 이거에요!

 

애플 예제를 따라해봤습니다...

그냥 오른쪽 ViewController의 이름이..SecondViewController라는것만..알면 될 듯..

애플예제는 막 뭐 기능이 이것저것 있는데 그런거 다 빼고 그냥 상태 복원 어떻게 하는지만 간단하게 알아볼거에요.

저의 샘플 프로젝트는 github.com/Zedd0202/iOS13-StateRestoration

 

Zedd0202/iOS13-StateRestoration

Contribute to Zedd0202/iOS13-StateRestoration development by creating an account on GitHub.

github.com

에 있습니다!

 

하는 방법은 아까 애플 샘플 프로젝트 링크에 다 나와있습니다. 같이 따라해볼게요.

가장 먼저해야 할 작업은 Info.plist에 NSUserActivityTypes을 추가해주는 겁니다. 

이렇게 되어있으면 된겁니다.

 

Q : 왜 해줘야해?

A : 우리 NSUserActivity를 사용한다고 그랬죠?

NSUserActivity를 사용하려면 activity를 식별하는 문자열을 지정해야합니다.

이렇게요.

자세한 내용은 여기를 참고하세요. 

 

그럼 본격적으로 시작해봅시다.

 

1.Enable State Preservation and Restoration for Your App

가장 먼저 SceneDelegate에 가줍니다.

NSUserActivity객체를 이용해야한다고 그랬죠!? 

NSUserActivity객체를 제공하기 위해서 위 메소드를 구현해줘야합니다. 

이 메소드를 구현하면 시스템에 "이 앱은 상태복원을 지원해~"라고 알려주는거라고 생각하시면 됩니다.

 

2.Preserve and Restore the App State with an Activity Object

NSUserActivity객체는 현재 시점의 앱 상태를 캡쳐한다고 합니다. 

만약에 내가 특정 화면에 들어갔어요! 그리고 앱을 종료하거나 백그라운드에 나왔다고 생각해봅시다.

그럼 딱 그 직전이 앱의 마지막 상태일거잖아요? 그걸 캡쳐하면 되는거에요!!!!

그래서 sceneWillResignActive에서 userActivity를

SecondViewController의 detailUserActivity를 넣어줬습니다.

근데 아마 오류가 나실거에요! detailUserActivity가 없거든요...

 

3. SecondViewController에 가서 detailUserActivity만들어주기

 

다양한 방법이 있겠지만...그냥 애플 예제에 있는 코드 복붙한거임 

위 코드에서 가장 중요한건 addUserInfoEntries인데요.

여기에 내가 복원하고 싶은 정보(?)들을 넣어놓으면 됩니다. 저는 

이렇게 navigation title이 있었는데, 이걸 넣어줬어요.

 

4. Scene configure

자 그럼 제가 해당 화면에서 이탈하고 다시 켰을 때 마지막으로 있었던 화면에 가야하잖아요?

func scene(_ scene: UIScene, willConnectTo에서 configure작업을 해줍니다.

그리고 configure메소드에서 화면을 이동해줍니다! 

가장 중요한 메소드는 restoreUserActivityState겠죠? 

해당 activity로 복원을 해주는 메소드입니다. 여기서 해당 activity는 아까 SecondViewController에서 만들어준 

이친구겠죠? 

이제 실행하면..

이렇게 됩니다. 

참고로 sceneWillResignActive에서 userActivity를 가져오는 작업이 있기 때문에...

background로 가줘야합니다..

그래서 제가 SecondViewController로 간 다음에 홈으로 가준 다음에!!

빌드를 다시 한번 한거에요.

 

 

근데 지금 문제점이..!!!! 앱을 명시적으로 kill하면 restore가 안되고,..다시 빌드하면 되네요..

이게 왜 그러는지 모르겠어요 ㅠㅠㅠ...

애플 예제랑 다를게 없ㅁ는 것 같은데..애플예제는 되는데..이건 왜안되지..!!!

 

-> 왜 안되는지 알았어요.

문서에 나와있네요..역시 문서를 잘 읽어야해..

- 프로젝트를 디버깅 할 때 사용자가 앱을 강제종료하면

시스템이 앱의 보존 상태를 자동으로 삭제한다는 점에 유의하렴.

앱이 종료 될 때 보존된 상태를 삭제하는것은 안전 예방책임. 

그니까 앱의 상태복원 기능을 테스트하려면 디버깅중에 앱 전환기를 사용해서 앱을 종료하지마!!!1

(전 그러고있었음) 

그럼 어떻게 테스트? 

 

1. 홈버튼을 사용하여 앱을 suspend시킨다.

2. Xcode에서 디버거 중지. 

3. 앱 다시 launch

 

그러면 UIKit이 상태 복원 프로세스를 시작한다고 합니다.

 

그래서 kill하면 안되고 다시 launch하면 됐던거군요...

 

아무튼 

github.com/Zedd0202/iOS13-StateRestoration

 

Zedd0202/iOS13-StateRestoration

Contribute to Zedd0202/iOS13-StateRestoration development by creating an account on GitHub.

github.com

샘플코드는 올려놨으니 참고하시길 바랍니다..!! 

반응형

'iOS' 카테고리의 다른 글

iOS 14 +) Date / Color Picker  (3) 2020.07.17
iOS 14+ ) PHPicker  (7) 2020.06.28
iOS ) Share Extension (1)  (4) 2020.06.10
iOS ) UIKey  (0) 2020.05.16
iOS ) PHContentEditingInput  (0) 2020.05.05