本地推送&远程推送
1.远程推送
- 推送通知的分类
远程推送通知
本地推送通知 - 推送通知作用
可以让不在前台运行的App告知用户App内部发生了什么事情
新的聊天消息
物流信息更新
商品推荐广告 - 推送通知效果
屏幕顶部显示一个横幅
应用图标角标
播放音效
锁屏时显示
屏幕中间弹出一个提醒框(iOS10取消了此效果)
用户可以设置推送的效果
用户未处理的推送通知都会展示在通知中心 - 推送通知的细节
点击推送通知默认会打开发送推送通知的应用
不管应用是打开还是关闭,推送通知都可以如期发送
2. 远程推送原理
远程推送实现原理
1. 推送消息的送达, 必须经过苹果的推送服务器
苹果推送服务器类似于快递公司
2. 为了将消息精准发送到设备, 需要该设备先去苹果服务器注册, 获取DeviceToken
DeviceToken类似于地址和电话
3. 获取DeviceToken及推送消息给设备的流程
3.远程推送的证书准备
一.调试远程推送app, 必备条件:
1.真机: 模拟器无法获取DeviceToken
2. 推送开发证书 : 让电脑能调试某个app的推送服务
3. 开发证书 : 让电脑具备真机调试的能力
4. 开发Profile : 记录某台电脑能用某台设备调试某个程序
二.发布具有推送的app, 必备条件
1. 推送发布证书 : 如果发布的程序中包含了推送服务,就必须安装这个证书
2. 发布证书 : 让电脑具备发布程序的能力
3. 发布Profile : 记录某台电脑能发布某个程序
三.开发推送功能, 需要先配置开发者账号
1. 打开Xcode的推送服务
2. 配置推送开发证书和推送发布证书
Xcode无法自动配置推送证书, 必须手动配置
第三方SDK
自己去看文档.....额.....
2.本地推送
本地推送介绍
什么是本地推送通知
顾名思义,就是不需要联网就能发出的推送通知(不需要服务器的支持)
本地推送通知的使用场景
常用来定时提醒用户完成一些任务,比如
清理垃圾、记账、买衣服、看电影、玩游戏
如何发出本地推送通知
1. 通知的授权, 只需一次
2. 创建本地推送通知对象
3. 设置相关属性: 发送时间、提醒内容、声音等
4. 添加到本地通知调度池中
iOS10本地推送实现
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
/*
1. 通知的授权, 只需一次
2. 创建本地推送通知对象
3. 设置相关属性: 发送时间、提醒内容、声音等
4. 添加到本地通知调度池中
*/
// 一. 通知的授权, 只需一次 (不需要配置plist)
//1. 创建用户通知中心
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
//2. 进行授权(远程/本地通用)
[center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert) completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (granted) {
NSLog(@"授权成功");
} else {
NSLog(@"error: %@", error);
}
}];
//3. 设置代理
center.delegate = self;
return YES;
}
- (IBAction)sendLocalNotificationClick:(id)sender {
//本地推送和远程推送逻辑是类似的. 只不过将设置数据的部分放到了本地
//1. 设置通知的内容, 必须使用 UNNotificationContent 的可变子类
UNMutableNotificationContent *content = [UNMutableNotificationContent new];
//设置附件
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"icon" ofType:@"png"]];
UNNotificationAttachment *attachment = [UNNotificationAttachment attachmentWithIdentifier:@"attachment" URL:url options:nil error:nil];
content.attachments = @[attachment];
//设置提醒文字
content.title = @"你好";
content.subtitle = @"呵呵";
content.body = @"女神: 去洗澡";
//设置角标
content.badge = @([UIApplication sharedApplication].applicationIconBadgeNumber + 1);
//设置声音
content.sound = [UNNotificationSound soundNamed:@"8360.mp3"];
//设置用于传值的字典
content.userInfo = @{@"url" : @"https://www.baidu.com"};
//2. 设置触发的时间 --> 使用子类设置
//如果设置重复, 间隔至少1分钟
// UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:3 repeats:NO];
NSDateComponents *dateComponents = [NSDateComponents new];
dateComponents.hour = 16;
dateComponents.minute = 22;
UNCalendarNotificationTrigger *trigger = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:dateComponents repeats:YES];
//3. 创建通知请求
UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:@"notifi1" content:content trigger:trigger];
//4. 添加到本地通知调度池中 --> iOS10添加本地通知到通知中心
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
[center addNotificationRequest:request withCompletionHandler:nil];
}
3.接收iOS10本地推送的值
//只能在前台运行时被调用 --> 可以获取通知的值, 还可以设置前台运行时是否要显示通知
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0) {
//可以获取用户的userInfo信息, 具体的逻辑处理将来看公司的需求
NSLog(@"notification: %@", notification.request.content.userInfo);
//这个设置通知呈现的样式, 是iOS10增加的
completionHandler(UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionSound);
}
//前台/后台/退出, 都可以调用此方法
//点击了通知之后会调用
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)())completionHandler __IOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0) __TVOS_PROHIBITED {
//可以获取用户的userInfo信息, 具体的逻辑处理将来看公司的需求
NSLog(@"notification: %@", response.notification.request.content.userInfo);
UISwitch *s = [UISwitch new];
s.frame = CGRectMake(30, 300, 0, 0);
[self.window addSubview:s];
//苹果要求调用
completionHandler();
}
iOS8的实现...
过期了就算了....
传感器
指纹识别
5S开始才有的指纹识别, 目前绝大部分的设备都可以支持
iOS8的时候苹果开放了指纹识别的API
需要LocalAuthentication框架
//前提: 判断设备/判断版本
//1. 创建本地验证上下文对象
LAContext *context = [LAContext new];
//2. 判断指纹识别是否可用d
//Evaluate: 执行 Policy: 策略 Biometrics: 生物识别
if (![context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:nil]) {
NSLog(@"指纹识别不可用");
return;
}
//3. 如果可用就调用
[context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics localizedReason:@"请允许访问" reply:^(BOOL success, NSError * _Nullable error) {
if (success) {
NSLog(@"指纹识别成功");
//打开对应的功能操作
} else {
NSLog(@"error: %@", error);
}
}];
注意1:更新UI放主线程
注意2:需要判断error.code 用户取消和验证失败的逻辑可能不一样
距离传感器
- (void)viewDidLoad {
[super viewDidLoad];
//1. 打开距离传感器
//proximity: 接近 Monitoring: 检测
[UIDevice currentDevice].proximityMonitoringEnabled = YES;
//2. 添加通知来获取值
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceProximityStateDidChangeNotification) name:UIDeviceProximityStateDidChangeNotification object:nil];
}
//3. 添加通知来获取值
- (void)deviceProximityStateDidChangeNotification {
if ([UIDevice currentDevice].proximityState) {
NSLog(@"逗比靠近了");
} else {
NSLog(@"逗比被吓跑了");
}
}
运动管理器
1.加速计
//0. 创建运动管理器
_motionMgr = [CMMotionManager new];
//一. 加速计 accelerometer --Push
//1. 判断加速计是否可用
if (![_motionMgr isAccelerometerAvailable]) {
return NSLog(@"加速计不可用");
}
//2. 设置更新间隔
_motionMgr.accelerometerUpdateInterval = 1;
//3. 开始统计数据
[_motionMgr startAccelerometerUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMAccelerometerData * _Nullable accelerometerData, NSError * _Nullable error) {
//加速计数据
//哪个轴的方向, 指向了地面, 那么这个轴方向的数据, 就会被加速计统计
//数据在1和-1之间
//加速计是检测力在某个方向上有作用. 如果速度越快, 值越大
CMAcceleration acceleration = accelerometerData.acceleration;
NSLog(@"x: %f, y: %f, z:%f", acceleration.x, acceleration.y, acceleration.z);
}];
//一. 加速计 accelerometer --Pull --> 主动获取数据, 当需要的时候再去获取
//1. 判断加速计是否可用
if (![_motionMgr isAccelerometerAvailable]) {
return NSLog(@"加速计不可用");
}
//2. 开始统计数据
[_motionMgr startAccelerometerUpdates];
2.陀螺仪 --> 将加速计的Accelerometer替换成Gyro即可
3.磁力计 --> 磁力计 Magnetometer : 检测磁场变化
摇一摇
//开始摇动
- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event {
NSLog(@"开始摇动");
}
//摇动结束
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event {
NSLog(@"摇动结束");
}
//摇动取消
- (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event {
NSLog(@"摇动取消");
}
计步器
//1. 判断计步器是否可用
if (![CMPedometer isStepCountingAvailable]) {
NSLog(@"计步功能不可用");
return ;
};
//2. 创建计步器 --> iOS8出现的,
_pedomter = [CMPedometer new];
//3. 开始计步 --> 从当前时间开始统计
[_pedomter startPedometerUpdatesFromDate:[NSDate date] withHandler:^(CMPedometerData * _Nullable pedometerData, NSError * _Nullable error) {
[self performSelectorOnMainThread:@selector(updateUI:) withObject:pedometerData.numberOfSteps waitUntilDone:YES];
}];