Detect if the application in background or foreground in swift
[UIApplication sharedApplication].applicationState
will return current state of applications such as:
- UIApplicationStateActive
- UIApplicationStateInactive
- UIApplicationStateBackground
or if you want to access via notification see UIApplicationDidBecomeActiveNotification
Swift 3+
let state = UIApplication.shared.applicationState
if state == .background || state == .inactive {
// background
} else if state == .active {
// foreground
}
switch UIApplication.shared.applicationState {
case .background, .inactive:
// background
case .active:
// foreground
default:
break
}
Objective C
UIApplicationState state = [[UIApplication sharedApplication] applicationState];
if (state == UIApplicationStateBackground || state == UIApplicationStateInactive) {
// background
} else if (state == UIApplicationStateActive) {
// foreground
}
How can I detect when the swift application is foreground from the background?
You probably need willEnterForegroundNotification.
Posted shortly before an app leaves the background state on its way to
becoming the active app.
Keep in mind thow that this notification posted olso after application(_:didFinishLaunchingWithOptions:)
when opening the application for the first time.
When application opens for the first time the applicationState
is inactive and when the application comes from the background the applicationState
is background.
So, your code will be something like this:
token = NotificationCenter.default.addObserver(
forName: UIApplication.willEnterForegroundNotification,
object: nil,
queue: .main
) { (notification: Notification) in
if UIApplication.shared.applicationState == .background {
// Came from the background
}
}
How to detect when iOS app appears in foreground, with Swift?
You can use the applicationDidBecomeActive(_:)
method of your UIApplicationDelegate
. You should read up on the app lifecycle. Your app delegate would then need to inform your view controller in some fashion.
Or you can register your view controller as an observer of the UIApplicationDidBecomeActive
notification. Documentation for that can be found here
How to detect if the main app is in the foreground in the NotificationServiceExtension?
From what I can tell, this isn't possible as of right now.
My guess is that Apple doesn't want these extensions to depend on the state of the main app.
What are proper places to detect foreground/background delegates in iOS?
Notification is one to many communication. If you really don't this functionality. you can use the protocol delegate method. you can assign a delegate, only when you need it.
and to solve your problem, you can move your observer to didSet of delegate variable. So, only when you assign a delegate, that time only observers will be added. if you don't set it, it will not be added for that viewController.
@objc protocol AppActivityTracker{
func appMovedToBackground()
func appMovedToForeground()
}
class BaseViewController: UIViewController {
var activityDelegate : AppActivityTracker? {
didSet{
//MARK:-Observer will be added only when you assign delegate.
let notificationCenter = NotificationCenter.default
notificationCenter.addObserver(self, selector: #selector(activityDelegate?.appMovedToForeground), name: UIApplication.didBecomeActiveNotification, object: nil)
notificationCenter.addObserver(self, selector: #selector(activityDelegate?.appMovedToBackground), name: UIApplication.didEnterBackgroundNotification, object: nil)
}
}
override func viewDidLoad() {
super.viewDidLoad()
}
}
class MyViewController: BaseViewController {
override func viewDidLoad() {
super.viewDidLoad()
//MARK:- Assign delegate only when you need observers
activityDelegate = self
}
}
//MARK:- Assign delegate only when you need observers
extension MyViewController : AppActivityTracker{
func appMovedToBackground() {
print("Do whatever need to do for current view controllers on appMovedToBackground")
}
func appMovedToForeground() {
print("Do whatever need to do for current view controllers on appMovedToForeground")
}
}
Discussion from comment:-
Adding observer on viewWillAppear
and removing observer on viewDidDisappear
.
@objc protocol AppActivityTracker{
func appMovedToBackground()
func appMovedToForeground()
}
class BaseViewController: UIViewController {
var activityDelegate : AppActivityTracker? {
didSet{
if activityDelegate != nil{
addOberservers()
}
else{
removeOberservers()
}
}
}
func addOberservers(){
let notificationCenter = NotificationCenter.default
notificationCenter.addObserver(self, selector: #selector(activityDelegate?.appMovedToForeground), name: UIApplication.didBecomeActiveNotification, object: nil)
notificationCenter.addObserver(self, selector: #selector(activityDelegate?.appMovedToBackground), name: UIApplication.didEnterBackgroundNotification, object: nil)
}
func removeOberservers(){
let notificationCenter = NotificationCenter.default
notificationCenter.removeObserver(self, name: UIApplication.didBecomeActiveNotification, object: nil)
notificationCenter.removeObserver(self, name: UIApplication.didEnterBackgroundNotification, object: nil)
}
}
class MyViewController: BaseViewController {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
//MARK:- Assign delegate only when you need observers
self.activityDelegate = self
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
//MARK:- Removing observer on view will disappear.
self.activityDelegate = nil
}
}
//MARK:- Assign delegate only when you need observers
extension MyViewController : AppActivityTracker{
func appMovedToBackground() {
print("Do whatever need to do for current view controllers on appMovedToBackground")
}
func appMovedToForeground() {
print("Do whatever need to do for current view controllers on appMovedToForeground")
}
}
Detecting application becoming going to the background and coming back to the foreground
The original code I wrote worked:
.onReceive(NotificationCenter.default.publisher(for: NSApplication.didBecomeActiveNotification))
Added this as to the view:
struct ContentView: View {
var body: some View {
Text("Hello, world!")
.padding()
.onReceive(NotificationCenter.default.publisher(for: NSApplication.didBecomeActiveNotification)) {
print("coming back!")
}
}
But I had the project being Multiplatform and it was creating some issues. I turned the project into a macOS only project and it worked.
Detect when a view controller goes to background and gets resumed
use UIApplicationDidBecomeActive
for resume and UIApplicationWillResignActive
for handle goes background
SwiftUI
Text("check application state!")
.onReceive(NotificationCenter.default.publisher(for: UIApplication.willResignActiveNotification)) { _ in
print("User received on willResignActiveNotification!")
}
.onReceive(NotificationCenter.default.publisher(for: UIApplication.didBecomeActiveNotification)) { _ in
print("User received on didBecomeActiveNotification!")
}
Swift 5.x > above
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
NotificationCenter.default.removeObserver(self, name: UIApplication.willResignActiveNotification, object: nil)
NotificationCenter.default.removeObserver(self, name: UIApplication.didBecomeActiveNotification, object: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(self.openAndCloseActivity), name: UIApplication.willResignActiveNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(self.openAndCloseActivity), name: UIApplication.didBecomeActiveNotification, object: nil)
}
@objc func openAndCloseActivity(_ notification: Notification) {
if notification.name == UIApplication.didBecomeActiveNotification{
// become active notifictaion
}else{
// willResignActiveNotification
}
}
Swift 5.x < below
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIApplicationWillResignActive, object: nil)
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIApplicationDidBecomeActive, object: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(self.closeActivityController), name: NSNotification.Name.UIApplicationWillResignActive, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(self.openactivity), name: NSNotification.Name.UIApplicationDidBecomeActive, object: nil)
}
and handle the method as
func closeActivityController() {
}
func openactivity() {
//view should reload the data.
}
other notification types are
extension NSNotification.Name {
@available(iOS 4.0, *)
public static let UIApplicationDidEnterBackground: NSNotification.Name
@available(iOS 4.0, *)
public static let UIApplicationWillEnterForeground: NSNotification.Name
public static let UIApplicationDidFinishLaunching: NSNotification.Name
public static let UIApplicationDidBecomeActive: NSNotification.Name
public static let UIApplicationWillResignActive: NSNotification.Name
public static let UIApplicationDidReceiveMemoryWarning: NSNotification.Name
public static let UIApplicationWillTerminate: NSNotification.Name
}
Related Topics
Multiple Locations on Map (Using Mkmapitem and Clgeocoder)
Is Possible to Simulate Touch Event Using an External Keyboard on iOS Jailbroken
This Class Is Not Key Value Coding-Compliant for the Key Xxxxxx
Error: Uicollectionview Must Be Initialized with a Non-Nil Layout Parameter
Swiftui Modal Presentation Works Only Once from Navigationbaritems
Swiftui: Set Status Bar Color for a Specific View
Sbstatusbarcontroller Instance
How to Force an App to Change Language in iOS/Objective-C
How to Get the Incoming Call Number by Using Callkit
How to Implement Login/Logout Navigation Using Userdefaults in Swift
How to Draw a Single Point Line in iOS
Wrap Items in a Horizontal Uistackview on Multiple Lines
How to Copy SQLite Database When Application Is Launched in iOS
@Published Property Wrapper Not Working on Subclass of Observableobject