applicationDidBecomeActive 처리- "뷰 컨트롤러가 앱이 활성화되는 것에 어떻게 대응할 수 있습니까?"


179

나는이 UIApplicationDelegate으로 내 주요 AppDelegate.m 클래스에서 프로토콜을 applicationDidBecomeActive정의하는 방법.

응용 프로그램이 백그라운드에서 돌아올 때 메서드를 호출하고 싶지만 메서드가 다른 뷰 컨트롤러에 있습니다. applicationDidBecomeActive메서드에 현재 표시되는 뷰 컨트롤러를 확인한 다음 해당 컨트롤러 내의 메서드를 호출하려면 어떻게해야합니까?

답변:


304

응용 프로그램의 모든 클래스는 응용 프로그램의 다른 알림에 대한 "관찰자"가 될 수 있습니다. 뷰 컨트롤러를 생성 (또는로드) 할 때이를 관찰자로 등록하고 UIApplicationDidBecomeActiveNotification해당 알림이 애플리케이션으로 전송 될 때 호출 할 메소드를 지정해야합니다.

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(someMethod:)
                                             name:UIApplicationDidBecomeActiveNotification object:nil];

자신을 정리하는 것을 잊지 마십시오! 시야가 멀어지면 관찰자로 자신을 제거하십시오.

[[NSNotificationCenter defaultCenter] removeObserver:self 
                                                name:UIApplicationDidBecomeActiveNotification
                                              object:nil];

알림 센터 에 대한 추가 정보 .


우수한. 을 사용하려고 생각하지 않았습니다 NSNotificationCenter. 감사합니다!
Calvin

3
해당 코드 줄에 오타가 있습니다 ( 'name'누락) : [[NSNotificationCenter defaultCenter] addObserver : self selector : @selector (someMethod :) name : UIApplicationDidBecomeActiveNotification object : nil];
Johnus

3
Reed의 답변에 추가하려면 호출되는 메소드 (이 예제에서는 someMethod)가 NSNotification 매개 변수를 승인해야합니다. 따라서 someMethod의 메소드 서명은-(void) someMethod : (NSNotification *) notification {// 여기에 뭔가를하십시오}
Aaron

2
@Aaron 그것은 가능하지만 요구 사항은 아닙니다. 그래도 훌륭한 통찰력입니다. 감사!
리드 올슨

환상적인! NSTimer를 담당하는 뷰 컨트롤러 / 기타 개체에서 NSTimer 인스턴스를 무효화 / 재 작성하는 가장 좋은 방법입니다. 그것을 사랑하십시오!
idStar

68

스위프트 3, 4 상당 :

관찰자 추가

NotificationCenter.default.addObserver(self,
    selector: #selector(applicationDidBecomeActive),
    name: .UIApplicationDidBecomeActive, // UIApplication.didBecomeActiveNotification for swift 4.2+
    object: nil)

관찰자 제거

NotificationCenter.default.removeObserver(self,
    name: .UIApplicationDidBecomeActive, // UIApplication.didBecomeActiveNotification for swift 4.2+
    object: nil)

콜백

@objc func applicationDidBecomeActive() {
    // handle event
}

2
이걸 어디로 불러?

1
@ user8169082에서는 알림 수신을 시작해야하는 모든 곳에 관찰자를 추가합니다. 당신은 그것을 추가 할 수 있습니다 viewDidLoad또는 viewWillAppear:animated예를 들어. 또한 더 이상 알림이 필요하지 않거나 deinit 메소드에서 관찰자 인스턴스가 할당 해제 될 때 관찰자를 제거 할 수 있습니다
igrek

2
swift 4.2 다음을 사용하고 있습니다 : NotificationCenter.default.addObserver (자체, 선택자 : #selector (applicationDidBecomeActive (notification :)), 이름 : UIApplication.didBecomeActiveNotification, object : nil)
Brian

16

신속한 등가 2 :

let notificationCenter = NSNotificationCenter.defaultCenter()

// Add observer:
notificationCenter.addObserver(self,
  selector:Selector("applicationWillResignActiveNotification"),
  name:UIApplicationWillResignActiveNotification,
  object:nil)

// Remove observer:
notificationCenter.removeObserver(self,
  name:UIApplicationWillResignActiveNotification,
  object:nil)

// Remove all observer for all notifications:
notificationCenter.removeObserver(self)

// Callback:
func applicationWillResignActiveNotification() {
  // Handle application will resign notification event.
}

removeObserver스위프트 에 넣을 수 있는 최고의 장소 : deinitmethod.
Enrico Susatyo

일반적으로 deinit에서 self에 액세스하는 것은 권장되지 않습니다. 이 시점에서, 자아는 완전 할당과 할당 해제 사이에 있습니다
Zorayr

1
그러면 Observer를 어디에서 제거 하시겠습니까?
Enrico Susatyo

2
@EnricoSusatyo 당신은 그것을 정확하지 않기 때문에 무시할 수 있습니다. deinit를 재정의하는 것이 좋습니다. "deinitializer가 호출 될 때까지 인스턴스가 할당 해제되지 않기 때문에 deinitializer는 호출 된 인스턴스의 모든 속성에 액세스 할 수 있으며 해당 속성에 따라 동작을 수정할 수 있습니다 (예 : 파일을 닫아야합니다. " deinit 호출은 괜찮습니다
Dan Rosenstark

7

스위프트 4.2

관찰자 추가

NotificationCenter.default.addObserver(self, selector: #selector(handleEvent), name: UIApplication.didBecomeActiveNotification, object: nil)

관찰자 제거

NotificationCenter.default.removeObserver(self, name: UIApplication.didBecomeActiveNotification, object: nil)

이벤트 처리

@objc func handleEvent() {
}

5

Swift 4에서는 Apple이 새로운 컴파일러 경고를 #selector통해이 시나리오에서 사용하지 않는 것이 좋습니다 . 다음은이 작업을 수행하는 훨씬 안전한 방법입니다.

먼저 알림에 사용할 수있는 게으른 var를 만듭니다.

lazy var didBecomeActive: (Notification) -> Void = { [weak self] _ in
    // Do stuff
} 

당신이 포함 실제 통지가 필요한 경우, 바로 교체 _와 함께 notification.

다음으로 앱이 활성화되는 것을 관찰하기 위해 알림을 설정했습니다.

func setupObserver() {
    _ = NotificationCenter.default.addObserver(forName: .UIApplicationDidBecomeActive,
                                               object: nil,
                                               queue:.main,
                                               using: didBecomeActive)
}

여기서 큰 변화는를 호출하는 대신 #selector위에서 만든 var 를 호출한다는 것입니다 . 이렇게하면 잘못된 선택기 충돌이 발생하는 상황을 제거 할 수 있습니다.

마지막으로 관찰자를 제거합니다.

func removeObserver() {
    NotificationCenter.default.removeObserver(self, name: .UIApplicationDidBecomeActive, object: nil)
}

1
#selector@objcSwift 4에서 속성으로 선언 된 메소드를 호출 할 수 있습니다 .
AnBisw

1
관찰자를 추가 할 때 self 가 할당되지 removeObserver(self않았기 때문에 사용이 올바르지 않습니다 . 당신이해야 다음let observer = NotificationCenter.default.addObserverremoveObserver(observer
얀 Kalbaska

고맙습니다 @ CodeBender 나는 그 기능을 아직 몰랐고 (마침내)를 제거합니다 @objc. 그러나 그것을 시도 할 때 콘솔에 경고가 나타납니다 (Xcode 11.3.1 (11C504), Swift 13.3) : BackgroundTask를 종료 할 수 없습니다 : 식별자가있는 백그라운드 작업이 없습니다. NSObjectProtocol과 같은 변수에 관찰자를 저장하더라도.
palme

@objc변형을 사용하면 경고 메시지가 표시됩니다 .
Palme

3

스위프트 5

fileprivate  func addObservers() {
      NotificationCenter.default.addObserver(self,
                                             selector: #selector(applicationDidBecomeActive),
                                             name: UIApplication.didBecomeActiveNotification,
                                             object: nil)
    }

fileprivate  func removeObservers() {
        NotificationCenter.default.removeObserver(self, name: UIApplication.didBecomeActiveNotification, object: nil)
    }

@objc fileprivate func applicationDidBecomeActive() {
// here do your work
    }

0

결합 방법 :

import Combine

var cancellables = Set<AnyCancellable>()
NotificationCenter.default.publisher(for: UIApplication.didBecomeActiveNotification)
    .sink { notification in
            // do stuff
    }.store(in: &cancellables)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.