[iOS] 델리게이트 활용(AppDelegate, SceneDelegate, UIApplication, LifeCycle Notification)

RudinP·2024년 2월 5일
0

Study

목록 보기
132/227

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{ //싱글씬인 경우 무조건 하나니까 .first로 접근하면 됨
            	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) {
    	//true가 리턴되면 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) {
    	//true가 리턴되면 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)
})
profile
곰을 좋아합니다. <a href = "https://github.com/RudinP">github</a>

0개의 댓글