-
-
Save dabing1022/67faff67fbd5438c6001d19cb70d03a2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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