Alarm_Clock_UserNotifications

仿ios系统闹钟

添加闹钟效果图

收到通知效果图

更新日志

2018.09.12 由于iOS系统限制了注册本地推送的数量,最大的注册量为64条,且一旦超出64条,所有的推送都将失效,故而在添加推送的时候做了一个判断,超过64条后,将不添加,以免影响已经添加的推送。

前言

最近项目中涉及到了本地通知的功能,索性就模仿系统闹钟写了个demo,对于iOS系统闹钟,应该都比较熟悉,该demo,基本实现了系统闹钟的全部功能。该demo本地通知使用的是iOS10 推出的UserNotifications, 关于UserNotifications的介绍和使用,网上已有诸多文章,在此就不多做赘述。

UNNotificationsManager

关于闹钟所使用到的UserNotifications库 做了一个简单的封装, 包含了注册通知,添加通知,以及 一些通知组件的 实现方法,同时提供了可供 外部使用的收到推送的通知

extern NSString * const UNDidReciveRemoteNotifationKey;//收到远程通知时调用

extern NSString * const UNDidReciveLocalNotifationKey; //收到本地通知时

extern NSString * const UNNotifationInfoIdentiferKey; //本地通知userinfo 里 Identifer的key值

一些其他方法,以demo为准

//注册本地通知

+ (void)registerLocalNotification;

#pragma mark -- AddNotification

/* 添加通知

* identifer 标识符

* body 主体

* title 标题

* subTitle 子标题

* weekDay 周几

* date 日期

* repeat 是否重复

* music 音乐

*/

+ (void)addNotificationWithBody:(NSString *)body

title:(NSString *)title

subTitle:(NSString *)subTitle

weekDay:(NSInteger)weekDay

date:(NSDate *)date

music:(NSString *)music

identifer:(NSString *)identifer

isRepeat:(BOOL)repeat

completionHanler:(void (^)(NSError *))handler;

#pragma mark -- NotificationManage

/*

* identifer 标识符

* 根据标识符 移除 本地通知

*/

+ (void)removeNotificationWithIdentifer:(NSString *)identifer;

#pragma mark -- NSDateComponents

/*

* return 日期组件 时分秒

* ex 每天重复

*/

+ (NSDateComponents *)componentsEveryDayWithDate:(NSDate *)date;

#pragma mark -- UNNotificationContent

/* UNMutableNotificationContent 通知内容

* title 标题

* subTitle 子标题

* body 主体

*/

+ (UNMutableNotificationContent *)contentWithTitle:(NSString *)title

subTitle:(NSString *)subTitle

body:(NSString *)body;

#pragma mark -- UNNotificationTrigger

/* UNNotificationTrigger 通知触发器

* interval 通知间隔

* repeats 是否重复

*/

+ (UNNotificationTrigger *)triggerWithTimeInterval:(NSTimeInterval)interval repeats:(BOOL)repeats;

添加闹钟

普通闹钟

[UNNotificationsManager addNotificationWithContent:[UNNotificationsManager contentWithTitle:@"时钟" subTitle:nil body:nil sound:[UNNotificationSound soundNamed:self.music]] dateComponents:[UNNotificationsManager componentsWithDate:self.date] identifer:self.identifer isRepeat:self.repeats completionHanler:^(NSError *error) {

NSLog(@"add error %@", error);

}];

每天重复

[UNNotificationsManager addNotificationWithContent:[UNNotificationsManager contentWithTitle:@"时钟" subTitle:nil body:nil sound:[UNNotificationSound soundNamed:self.music]] dateComponents:[UNNotificationsManager componentsEveryDayWithDate:self.date] identifer:self.identifer isRepeat:self.repeats completionHanler:^(NSError *error) {

NSLog(@"add error %@", error);

}];

每周重复(周一,周二等)

[self.repeatStrs enumerateObjectsUsingBlock:^(NSString * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {

NSInteger week = 0;

if ([obj containsString:@"周日"]) {

week = 1;

}else if([obj containsString:@"周一"]){

week = 2;

}else if([obj containsString:@"周二"]){

week = 3;

}else if([obj containsString:@"周三"]){

week = 4;

}else if([obj containsString:@"周四"]){

week = 5;

}else if([obj containsString:@"周五"]){

week = 6;

}else if([obj containsString:@"周六"]){

week = 7;

}

[UNNotificationsManager addNotificationWithContent:[UNNotificationsManager contentWithTitle:@"闹钟" subTitle:nil body:nil sound:[UNNotificationSound soundNamed:self.music]] weekDay:week date:self.date identifer:self.identifer isRepeat:YES completionHanler:^(NSError *error) {

NSLog(@"add error %@", error);

}];

}];

}

铃声

这里无法获取系统铃声和震动类型,自己在网上找了点铃声素材。 系统铃声需要caf格式,MP3和caf 格式相互转化方法如下

//控制台输入

afconvert xxx.mp3 xxx.caf -d ima4 -f caff -v

通知栏选项

首先注册通知的时候需要UNNotificationCategory 以及UNNotificationAction

UNNotificationAction *action1 = [UNNotificationAction actionWithIdentifier:actionFiveMin title:@"5分钟后" options:UNNotificationActionOptionNone];

UNNotificationAction *action2 = [UNNotificationAction actionWithIdentifier:actionHalfAnHour title:@"半小时后" options:UNNotificationActionOptionNone];

UNNotificationAction *action3 = [UNNotificationAction actionWithIdentifier:actionOneHour title:@"1小时后" options:UNNotificationActionOptionNone];

UNNotificationAction *action4 = [UNNotificationAction actionWithIdentifier:actionStop title:@"停止" options:UNNotificationActionOptionNone];

UNNotificationCategory *category = [UNNotificationCategory categoryWithIdentifier:identiferStr actions:@[action1, action2,action3, action4] intentIdentifiers:@[] options:UNNotificationCategoryOptionNone];

UNNotificationCategory *stopCategory = [UNNotificationCategory categoryWithIdentifier:categryStopIdf actions:@[action4] intentIdentifiers:@[] options:UNNotificationCategoryOptionNone];

[center setNotificationCategories:[NSSet setWithArray:@[category,stopCategory]]];

然后在设置UNMutableNotificationContent的时候需要设置对应的categoryIdentifier 这里区分了是否设置了稍候提醒

+ (void)addNotificationWithContent:(UNNotificationContent *)content identifer:(NSString *)identifer trigger:(UNNotificationTrigger *)trigger completionHanler:(void (^)(NSError *))handler {

//设置 category

UNMutableNotificationContent *aContent = [content mutableCopy];

if ([identifer hasPrefix:@"isLater"]) {

aContent.categoryIdentifier = categryLaterIdf;

}else {

aContent.categoryIdentifier = categryStopIdf;

}

[self addNotificationWithRequest:[UNNotificationRequest requestWithIdentifier:identifer content:aContent trigger:trigger] completionHanler:handler];

}

最后在用户点击导航栏控件的时候,根据identifier处理相应事件

//与导航控件交互的时候会调用

- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler {

NSLog(@"%s", __func__);

[self handCommnet:response];

completionHandler();

}

-(void)handCommnet:(UNNotificationResponse *)response

{

NSString *actionIdef = response.actionIdentifier;

NSDate *date;

if ([actionIdef isEqualToString:actionStop]) {

return;

}else if ([actionIdef isEqualToString:actionFiveMin]) {

date = [NSDate dateWithTimeIntervalSinceNow:5 * 60];

}else if ([actionIdef isEqualToString:actionHalfAnHour]) {

date = [NSDate dateWithTimeIntervalSinceNow:30 * 60];

}else if ([actionIdef isEqualToString:actionOneHour]) {

date = [NSDate dateWithTimeIntervalSinceNow:60 * 60];

}

if (date) {

[UNNotificationsManager addNotificationWithContent:response.notification.request.content identifer:response.notification.request.identifier trigger:[UNNotificationsManager triggerWithDateComponents:[UNNotificationsManager componentsWithDate:date] repeats:NO] completionHanler:^(NSError *error) {

NSLog(@"delay11111 %@", error);

}];

}

}

持续推送

本地铃声 时长小于30s。当手机处于后台,息屏的时候,铃声音乐是可以放完的的,手机处于活跃状态,只会持续到推送消失,经评论区 @bigcancancancan 指出,想要在活跃状态持续推送本地闹钟,需要用户在 设置-通知-横幅风格 选择持续。

仿苹果手机闹钟_高仿iOS系统闹钟 UserNotifications相关推荐

  1. 辰光php客服系统源码_仿伊对梵高相亲交友系统产品特性以及构成基础,你了解吗?...

    梵高婚恋相亲交友系统,顾名思义是一个集相亲.交友于一身的婚恋社交App.可搭建平台,出售源码. 仿伊对梵高相亲交友系统开发特色及应用场景 1.仿伊对梵高相亲交友系统开发特色:直播间在线相亲,红娘在线视 ...

  2. ios 仿苹果闹钟_苹果片状iOS闹钟的三种选择

    ios 仿苹果闹钟 If two iPhone alarm failures in less than three months (the Daylight Savings bug and the N ...

  3. android+高仿视频录制,android高仿微信视频编辑页

    android高仿微信视频编辑页-视频多张图片提取 上一篇中介绍了有关视频提取图片的知识点,如果对这个不太了解 建议看下android提取视频多张图片和视频信息之前这篇. 这里实现的是仿微信的视频编辑 ...

  4. android 仿网易标签切换,高仿网易云音乐客户端的Home页面切换Tabhost-IT蓝豹

    1.高仿网易云音乐客户端的Home页面切换Tabhost 高仿网易云音乐客户端的Home页面切换Tabhost,并且三角形是透明的, 实现方式,自定义AnimTabsView继承 RelativeLa ...

  5. 高仿简书Android,高仿简书个人中心页面

    高仿简书个人中心页面 Demo下载地址: 先贴上效果图 1. 步骤 1.1 把APP的主题改为NoAction 1.2 引入Material Design 包 implementation 'com. ...

  6. android仿iphonex home,安卓高仿iPhoneX桌面

    安卓高仿iPhoneX桌面是一款非常装逼的手机主题软件,这款软件可以快速的让安卓手机变成iPhoneX桌面,演变效果非常的逼真,还有超强的壁纸外表,下面西西就为大家带来安卓高仿iPhoneX桌面软件最 ...

  7. 今日上新推荐源码,高仿微信社交,高仿拼多多商城

    Flutter社交App源码 介绍:利用 Flutter 来高仿微信(WeChat) 7.0.0+ App,代码规范惊为天人.注释详解令人发指.细节处理精益求精.核心功能配备文档.接近98%还原度的原 ...

  8. android+高仿视频录制,Android高仿微信拍照控件,实战推荐!

    原标题:Android高仿微信拍照控件,实战推荐! 作者:陈嘉桐 转自:ttps://github.com/CJT2325 控件介绍 不知道是不是在微信更新到6.0版本之后,微信将它的拍照和录制视频的 ...

  9. 苹果youtube无法连接网络_杂项其一 “IOS系统某些app无法连接到网络,其他正常”解决办法...

    "IOS系统某些app无法连接到网络,其他正常"的解决办法 我的iphoneX 在更新到13.31以后,有几个新下的app,死活连接不到网络,其他app正常登录. 发现是他们自动会 ...

最新文章

  1. Matlab与机器学习-- 数据的归一化
  2. JS组件系列——开源免费图表组件:Chart.js
  3. 【论文解读】FcaNet:频率通道注意力网络论文解读
  4. java new 多线程_Java多线程:Java多线程执行框架
  5. boost::hana::none_of用法的测试程序
  6. uva437The Tower of Babylon
  7. 分词消除歧义_角色标题消除歧义
  8. 数据库中的索引原理阅读
  9. activemq消息丢失_面试必问之消息中间件
  10. 安卓是java ios c_如何为Android和iOS使用相同的C ++代码?
  11. excel几个数相加等于某个数_[求助]如何能计算出几个数字相加等于一个给定的数...
  12. jenkins教程_1 简介
  13. 阶段3 3.SpringMVC·_01.SpringMVC概述及入门案例_02.SpringMVC框架的介绍
  14. android记账本流程图,记账的基本流程
  15. 南邮的计算机通信工程课程是什么,通信工程考研详解之南京邮电大学
  16. 微型计算机自动化控制专业,自动化专业简介
  17. python中度数怎么表示_python中如何将华氏温度转换为摄氏温度?
  18. Python 函数的使用和内嵌函数
  19. 每个计算机的ip地址要一样吗,同一ip网站-局域网中的所有电脑都是同一个IP地址吗? – 手机爱问...
  20. CAM/TCAM/RAM

热门文章

  1. 看了多篇2019年的面经后的个人总结
  2. SumatraPDF反向搜索命令行设置
  3. [2023最新]美少妇Metasploit(MSF)下载安装及使用详解,永久免费使用,环境配置和使用技巧指南
  4. 手机无线网络需要服务器,一台手机能连两个WiFi吗?
  5. php 如果记录集不存在,ThinkPHP教程_PHP框架之ThinkPHP(八)【CRUD与连贯操作】
  6. 励志:98岁老爷爷用Windows系统自带画图软件制作的神作
  7. 个性化学习之自适应测试[Adaptive Test]
  8. Show Stopper!
  9. Assignment 2: UDP Pinger[课后作业]
  10. Angelababy顺产生子,做女人当如Angelababy!