AppDelegate
- func applicationWillTerminate(_ application: UIApplication)에서 저장을 하거나 리소스를 정리하는 것은 권장되지 않으므로 해당 메소드를 구현하는 경우는 거의 없다.
application(_:didFinishLaunchingWithOptions:)
- 앱에 필요한 파일이 다운로드 되어있지 않았을 때 최초로 한 번 다운로드 하는 경우 여기에 구현
- 서드파티 앱 로그인을 위한 초기화도 여기에 구현
SceneDelegate
scene(_:willConnectTo:options:)
- 멀티 윈도우를 지원하지 않는 경우 구현.
- 스토리보드 사용하지 않는 경우,
- 윈도우 생성 작업
- 뷰 컨트롤러 생성 후 루트뷰 컨트롤러 지정 여기서 구현
sceneDidDisconnect(_:)
- scene에서 사용하지 않는 리소스 정리
- 저장되지 않은 데이터 저장때 구현
- 다만 위의 둘은 그때그때 하는게 좋기 때문에 여기서 구현하는 것은 추천하지 않음
sceneWillResignActive(:), sceneDidBecomeActive(:)
- 다른 앱으로 넘어갔을 때 sceneWillResignActive에서 상태를 저장 후, 다시 앱으로 돌아왔을 때 필요한 작업을 sceneDidBecomeActive에서 구현
- ex) 게임을 하다가 전화가 와서 받으면 sceneWillResignActive에서 현재 게임 상태를 저장하고 정지, 전화가 끝나고 게임으로 돌아오면 sceneDidBecomeActive에서 다시 복구 후 재생하도록 구현
- ex) sceneWillResignActive에서 타이머 정지, sceneDidBecomeActive에서 다시 시작도 가능
sceneDidEnterBackground(_:)
- 리소스 반납에 사용
- 카메라나 GPS 사용 시 여기서 사용 중지
- 네트워크 연결, 데이터베이스 연결 여기서 닫기
- 파일 입출력도 여기서 닫기
sceneWillEnterForeground(_:)
- 위의 반대
- 리소스 요청, 카메라 등 사용 요청, 네트워크 연결 등등
자주 사용되는 코드 패턴
- 델리게이트 패턴에서 첫번째 파라미터는 반드시 델리게이트를 호출한 객체
- 보통 공유객체의 이름은
shared
, standard
, default
로 짓는다.
ViewController에서 어플리케이션 인스턴스에 접근하기
class ViewController: UIViewController{
override func viewDidLoad(){
UIApplication.shared
}
}
AppDelegate에서 전체 공유되는 속성 만들기
- 필요한 데이터를 하나 만들고 앱 전체에서 공유가 가능하다.
- AppDelegate는 하나니까 가능하다.
@main
class AppDelegate: UIResponder, UIApplicationDelegate{
var sharedData = 0
...
}
class ViewController: UIViewController{
override func viewDidLoad(){
UIApplication.shared.delegate as? AppDelegate {
appDelegate.sharedData
}
}
}
SceneDelegate에서 전체 공유되는 속성 만들기
class SceneDelegate: UIResponder, UIWindowSceneDelegate{
var sharedData = 0
...
}
1. 모든 씬을 대상으로 작업, 특정 씬 검색 원하는 경우
class ViewController: UIViewController{
override func viewDidLoad(){
if let sceneDelegate = UIApplication.shared.connectedScenes
.first.delegate as? SceneDelegate{
sceneDelegate.sharedData
}
}
}
2. 뷰 컨트롤러에서 접근하고 싶은 경우
- 현재 뷰의 연관된 scene에 접근 가능
- 그러나 뷰가 표시된 후에만 접근 가능하다.
- viewDidLoad는 화면이 표시되기 전에 호출되기 때문에 아래의 코드는 실패할 것이다.
class ViewController: UIViewController{
override func viewDidLoad(){
if let sceneDelegate = view.window?.windowScene?.delegate as? SceneDelegate{
sceneDelegate.sharedData
}
}
}
UIApplication 사용 예제
디바이스를 서버에 등록할 때(ex: 카톡)
UIApplication.shared.registerForRemoteNotifications()
화면이 자동으로 어두워지는 현상 막기
- 배터리 소모가 심해지기 때문에 꼭 필요한 경우만 사용
UIApplication.shared.isIdleTimerDisabled = false
다른 앱을 실행하는 기능
기본 브라우저 실행(url 전달)
func openBrowser(){
guard let url = URL(string: "https://velog.io/@rudin_/posts") else {return}
if UIApplication.shared.canOpenURL(url) {
UIApplication.shared.open(url)
}
}
- 추가 내용은 "iOS URL scheme으로 앱 실행"
setting 열기
func openBrowser(){
guard let url = URL(string: UIApplication.openSettingURLString) else {return}
if UIApplication.shared.canOpenURL(url) {
UIApplication.shared.open(url)
}
}
- 앱이 지도나 카메라를 이용한다면 자동으로 해당 권한을 조정할 수 있는 설정탭으로 열어짐.
- 그게 아니라면 기본적으로 초기 설정 화면으로 이동
LifeCycle Notification
- AppDelegate, SceneDelegate 내에서만 LifeCycle에 관여할 수 있는 건 아니다.
- Notification을 사용하면 된다.
ex) didActivateNotification
- iOS 13 이전에는 didBecomeActiveNotification이었다.
NotificationCenter에 옵저버 등록
NotificationCenter.default.addObserver(forName: UIScene.didActivateNotification , object: nil, queue: .main) { _ in
print(UIScene.didActivateNotification)
})