各位大神好,请教一个iOS LocalNotification的技术问题,翻遍苹果的官方技术文档,问遍各大人工智能,找遍各大论坛,写程序做各种验证,没有答案,想请大神帮忙从逆向工程的角度给予帮助。万分感谢!
有个iOS 应用Alarmy,能够使用LocalNotification 实现持续不断闹钟响铃,我想实现这个功能。
对Alarmy 做了仔细研究,发现在不联网(飞行模式),关闭应用后台刷新,使用应用程序管理器关闭该应用的情况下,依然能够实现在闹钟时间持续不断发消息通知响铃。
通过Xcode Device Console 分析iPhone系统消息,发现在设定某个闹钟,比如上午8:32,会在上午8:32 Post 40个LocalNotification(第1个 08:32:00 SpringBoard Posting notification id: 163B-B3EC),在同一时间点发2个通知,过3秒再发2个通知,等到40个LocalNotification 发完后,正好1分钟。接着又Post 第1个Local Notification(08:33:00 SpringBoard Posting notification id: 163B-B3EC),然后Modify第1个Local Notification(08:33:00 SpringBoard Modify notification id: 163B-B3EC),这样又Post 完40 个LocalNotification后,正好1分钟。只要用户不响应通知,通知会一直持续发出。
iOS 的User Notifications有两个触发LocalNotification通知的类:
UNTimeIntervalNotificationTrigger基于时间间隔触发通知,而UNCalendarNotificationTrigger基于日历事件(具体日期和时间)触发通知。
经反复写程序验证,推测该程序应该使用了UNTimeIntervalNotificationTrigger,该类可以设置一个定时器通知,init(timeInterval: TimeInterval, repeats: Bool) 方法,如果repeats 设为true,timeInterval 最小为60,单位为秒。符合Alarmy 1分钟后重复发送第一条消息通知,经写程序验证,只要不响应该通知,会持续不断发送。在Xcode Device Console 中跟踪Activity 和Message,发现Alarmy 的Posting notification 特征,先40条Posting notification,然后是同一notification id 的Posting notification和Modify notification成对出现,共79条。写程序验证发现UNTimeIntervalNotificationTrigger会先Posting notification,然后是同一notification id 的Posting notification和Modify notification成对出现。和Alarmy 的特征相符。但这个类只能指定从运行时刻起的时间间隔,使用场景为定时器,无法指定具体通知时间。
UNCalendarNotificationTrigger 类可以指定具体的通知时间,init(dateMatching: DateComponents, repeats: Bool)方法,如果repeats 设为true,则在指定的时间会再次出发通知。而且一个iOS应用最多可以发64个UNCalendarNotificationTrigger,经写程序验证,如果通知多于64个,会保留最后64个通知,前面的通知会被忽略。UNCalendarNotificationTrigger 只有Posting notification Activity特征,没有Modify notification Activity 特征。
至此,分析结果已走向死胡同。使用UNTimeIntervalNotificationTrigger 无法指定通知触发时间,而UNCalendarNotificationTrigger 无法做到1分钟后永远重复。
我对逆向工程不怎么在行,想请各位大神帮忙分析Alarmy 是如何做到在指定通知触发事件,且永远重复通知。是否使用了iOS 未公开的类和方法?以上分析也许有错误,仅供参考,希望不会误导。感谢!
以下两条Device Console Activity 的Message:
08:33:00.270797+0800 SpringBoard Posting notification id: 163B-B3EC; section: droom.sleepIfUCanFree; thread: C428-6833; category: ; timestamp: 2024-05-02 上午12:33:00 +0000; interruption-level: active; relevance-score: 0.00; filter-criteria: (null); actions: [ minimal: 0 (0 text), default: 0 (0 text) ]; destinations: [ {(
BulletinDestinationCoverSheet,
BulletinDestinationBanner,
BulletinDestinationNotificationCenter,
BulletinDestinationLockScreen
)} ]
08:33:00.297116+0800 SpringBoard Modify notification id: 163B-B3EC; section: droom.sleepIfUCanFree; thread: C428-6833; category: ; timestamp: 2024-05-02 上午12:33:00 +0000; interruption-level: active; relevance-score: 0.00; filter-criteria: (null); actions: [ minimal: 0 (0 text), default: 0 (0 text) ]; destinations: [ {(
)} ]