So modified it a bit to allow other notifications
import objc_util
import time
class NotificationObserver:
def __init__(self, name):
self.name = objc_util.ns(name)
self.center = objc_util.ObjCClass("NSNotificationCenter").defaultCenter()
self._observer = None
self._blk = None
self.queue = objc_util.ObjCClass('NSOperationQueue').new()
self.queue.setName_(objc_util.ns('test'))
self.state = False
'''define your own callback here'''
@objc_util.ui.in_background
def callback(self, name, obj, userInfo):
print(time.asctime() + name)
self.state = True
'''the objc block signature. do not modify'''
def _block(self, _cmd, notification):
try:
self.ni = objc_util.ObjCInstance(notification)
self.ni_name = self.ni.name()
self.ni_obj = self.ni.object()
self.ni_ui = self.ni.userInfo()
self.callback(self.ni_name.__str__(), self.ni_obj, self.ni_ui)
except Exception as ex:
print(ex)
'''start observing'''
def start(self):
#print(time.asctime() + ' starting')
if self._observer:
raise Exception('observer already started')
self._blk = objc_util.ObjCBlock(self._block, restype=None, argtypes=[objc_util.c_void_p, objc_util.c_void_p])
self._observer = self.center.addObserverForName_object_queue_usingBlock_(self.name, None, self.queue, self._blk)
objc_util.retain_global(self)
def stop(self):
#print(time.asctime() + ' stopping')
if self._observer:
self.center.removeObserver_(self._observer)
self._observer = None
objc_util.release_global(self)
To test it, I did
from NotificationObserver import NotificationObserver
observer_names = {
"UIApplicationDidBecomeActiveNotification": "didBecomeActive",
"UIApplicationDidEnterBackgroundNotification": "didEnterBackground",
"UIApplicationWillEnterForegroundNotification": "willEnterForeground",
"UIApplicationWillResignActiveNotification": "willResignActive"
}
for on in observer_names:
name = observer_names[on]
setattr(NotificationObserver, name, NotificationObserver(on))
getattr(NotificationObserver, name).start()
I also added applicationState() into the mix and got this in the console
sa.applicationState() = 0
...
sa.applicationState() = 1
sa.applicationState() = 1
willResignActive
sa.applicationState() = 1
...
sa.applicationState() = 2
sa.applicationState() = 2
didEnterBackground
sa.applicationState() = 2
...
willEnterForeground
sa.applicationState() = 1
...
sa.applicationState() = 0
sa.applicationState() = 0
didBecomeActive
sa.applicationState() = 0
...
So really it’s not much different than
if not sa.applicationState():
Correction: The notification is still good to run code when the app goes into the inactive state, but in my case I actually need something else. Also forgot to mention this (when you are done)
for on in observer_names:
getattr(NotificationObserver, observer_names[on]).stop()