Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save dabing1022/67faff67fbd5438c6001d19cb70d03a2 to your computer and use it in GitHub Desktop.
Save dabing1022/67faff67fbd5438c6001d19cb70d03a2 to your computer and use it in GitHub Desktop.
import Foundation
import CoreFoundation
public final class CoreNotificationCenter {
public static let darwin = CoreNotificationCenter(CFNotificationCenterGetDarwinNotifyCenter())
public static let local = CoreNotificationCenter(CFNotificationCenterGetLocalCenter())
#if os(macOS)
public static let distributed = CoreNotificationCenter(CFNotificationCenterGetDistributedCenter())
#endif
private let center: CFNotificationCenter
private var observations: [Notification.Name: (Notification) -> Void] = [:]
private init(_ center: CFNotificationCenter) {
self.center = center
}
private func handleNotification(_ notification: Notification) {
observations[notification.name]?(notification)
}
public func addObserver(forName name: Notification.Name, suspensionBehavior: CFNotificationSuspensionBehavior = .deliverImmediately, using block: @escaping (Notification) -> Void) {
observations[name] = block
let callback: CFNotificationCallback = { (_, observer, optCFName, pObject, optCFDict) in
// needs to be an unsafeBitCast here - it's LITERALY the pointer in memory
let center = unsafeBitCast(observer, to: CoreNotificationCenter.self)
guard let cfName: CFNotificationName = optCFName else {
assertionFailure("Nameless notification")
return
}
let name = Notification.Name(cfName.rawValue as String)
let object: Any?
if let pObject = pObject {
object = unsafeBitCast(pObject, to: Any.self)
} else {
object = nil
}
let userInfo: [AnyHashable: Any]?
if let dictionary = optCFDict as? [String: AnyObject] {
userInfo = dictionary
} else {
userInfo = nil
}
let notification = Notification(name: name,
object: object,
userInfo: userInfo)
center.handleNotification(notification)
}
CFNotificationCenterAddObserver(
center,
Unmanaged.passUnretained(self).toOpaque(),
callback,
name.rawValue as CFString,
nil,
suspensionBehavior
)
}
public func removeObserver(withName name: Notification.Name) {
observations.removeValue(forKey: name)
CFNotificationCenterRemoveObserver(
center,
Unmanaged.passUnretained(self).toOpaque(),
CFNotificationName(name.rawValue as CFString),
nil
)
}
public func removeAllObservers() {
CFNotificationCenterRemoveEveryObserver(
center,
Unmanaged.passUnretained(self).toOpaque()
)
}
public func post(name: Notification.Name) {
CFNotificationCenterPostNotification(
center,
CFNotificationName(name.rawValue as CFString),
nil,
nil,
true
)
}
}
// https://www.iphonedevwiki.net/index.php/SpringBoard.app/Notifications
// https://employment12werft.blogspot.com/2011/02/ios-detect-monitor-when-system-messages.html
// https://developpaper.com/examples-of-the-underlying-notification-framework-library-of-ios-system/
// https://github.com/SCTCoding/LaunchEvents/blob/main/LaunchEvents.csv
extension Notification.Name {
public static let springboardActiveCallStateChanged = Notification.Name("com.apple.springboard.activeCallStateChanged")
public static let springboardAttemptActivation = Notification.Name("com.apple.springboard.attemptactivation")
public static let springboardBootedCleanly = Notification.Name("com.apple.springboard.bootedcleanly")
public static let springboardCallInterruptedApp = Notification.Name("com.apple.springboard.callinterruptedapp")
public static let springboardCurvedBatteryCapacity = Notification.Name("com.apple.springboard.curvedBatteryCapacity")
public static let springboardDeviceLockStatusChanged = Notification.Name("com.apple.springboard.DeviceLockStatusChanged")
public static let springboardDeviceWillShotDown = Notification.Name("com.apple.springboard.deviceWillShutDown")
public static let springboardDoubleHeightMode = Notification.Name("com.apple.springboard.doubleheightmode")
public static let springboardFullyCharged = Notification.Name("com.apple.springboard.fullycharged")
public static let springboardHasBlankedScreen = Notification.Name("com.apple.springboard.hasBlankedScreen")
public static let springboardLockComplete = Notification.Name("com.apple.springboard.lockcomplete")
public static let springboardLockInterrupted = Notification.Name("com.apple.springboard.lockinterrupted")
public static let springboardLockState = Notification.Name("com.apple.springboard.lockstate")
public static let springboardLowPowerAlertPresented = Notification.Name("com.apple.springboard.lowPowerAlertPresented")
public static let springboardOrientation = Notification.Name("com.apple.springboard.orientation")
public static let springboardPluggedIn = Notification.Name("com.apple.springboard.pluggedin")
public static let springboardProximityChanged = Notification.Name("com.apple.springboard.proximity.changed")
public static let springboardRawOrientation = Notification.Name("com.apple.springboard.rawOrientation")
public static let springboardRentalsExpiredNotification = Notification.Name("com.apple.springboard.RentalsExpiredNotification")
public static let springboardResetEnded = Notification.Name("com.apple.springboard.reset-ended")
public static let springboardResetReady = Notification.Name("com.apple.springboard.reset-ready")
public static let springboardResetWillEnd = Notification.Name("com.apple.springboard.reset-willend")
public static let springboardRingerState = Notification.Name("com.apple.springboard.ringerstate")
public static let springboardShowingAlertItem = Notification.Name("com.apple.springboard.showingAlertItem")
public static let springboardSyncingUnblocked = Notification.Name("com.apple.springboard.syncingUnblocked")
public static let springboardUnambiguousOrientation = Notification.Name("com.apple.springboard.unambiguousOrientation")
public static let airportUserNotification = Notification.Name("com.apple.airport.userNotification")
public static let airportSettingsVisible = Notification.Name("com.apple.airportsettingsvisible")
public static let alarmAlarmChanged = Notification.Name("com.apple.alarm.alarmchanged")
public static let alarmAlarmFired = Notification.Name("com.apple.alarm.alarmfired")
public static let mobileSubstantialTransition = Notification.Name("com.apple.mobile.SubstantialTransition")
public static let powerlogExit = Notification.Name("com.apple.powerlog.exit")
public static let remoteNotificationDelivered = Notification.Name("com.apple.remotenotification.notificationdelivered")
// AppleDatePreferencesChangedNotification
// AppleLanguagePreferencesChangedNotification
// AppleNumberPreferencesChangedNotification
// ApplePreferredContentSizeCategoryChangedNotification
// AppleTextBehaviorPreferencesChangedNotification
// AppleTimePreferencesChangedNotification
// com.apple.frontboard.systemappservices.serverNotifyToken
// com.apple.frontboard.workspace.serverNotifyToken
// com.apple.hangtracer.prefchangednotification
// kCTDaemonReadyNotification
// kKeepAppsUpToDateEnabledChangedNotification
// PINPolicyChangedNotification
// UIBacklightLevelChangedNotification
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment