本地推送&遠(yuǎn)程推送
1.遠(yuǎn)程推送
- 推送通知的分類
遠(yuǎn)程推送通知
本地推送通知 - 推送通知作用
可以讓不在前臺(tái)運(yùn)行的App告知用戶App內(nèi)部發(fā)生了什么事情
新的聊天消息
物流信息更新
商品推薦廣告 - 推送通知效果
屏幕頂部顯示一個(gè)橫幅
應(yīng)用圖標(biāo)角標(biāo)
播放音效
鎖屏?xí)r顯示
屏幕中間彈出一個(gè)提醒框(iOS10取消了此效果)
用戶可以設(shè)置推送的效果
用戶未處理的推送通知都會(huì)展示在通知中心 - 推送通知的細(xì)節(jié)
點(diǎn)擊推送通知默認(rèn)會(huì)打開(kāi)發(fā)送推送通知的應(yīng)用
不管應(yīng)用是打開(kāi)還是關(guān)閉,推送通知都可以如期發(fā)送
2. 遠(yuǎn)程推送原理
遠(yuǎn)程推送實(shí)現(xiàn)原理
1. 推送消息的送達(dá), 必須經(jīng)過(guò)蘋果的推送服務(wù)器
蘋果推送服務(wù)器類似于快遞公司
2. 為了將消息精準(zhǔn)發(fā)送到設(shè)備, 需要該設(shè)備先去蘋果服務(wù)器注冊(cè), 獲取DeviceToken
DeviceToken類似于地址和電話
3. 獲取DeviceToken及推送消息給設(shè)備的流程
3.遠(yuǎn)程推送的證書準(zhǔn)備
一.調(diào)試遠(yuǎn)程推送app, 必備條件:
1.真機(jī): 模擬器無(wú)法獲取DeviceToken
2. 推送開(kāi)發(fā)證書 : 讓電腦能調(diào)試某個(gè)app的推送服務(wù)
3. 開(kāi)發(fā)證書 : 讓電腦具備真機(jī)調(diào)試的能力
4. 開(kāi)發(fā)Profile : 記錄某臺(tái)電腦能用某臺(tái)設(shè)備調(diào)試某個(gè)程序
二.發(fā)布具有推送的app, 必備條件
1. 推送發(fā)布證書 : 如果發(fā)布的程序中包含了推送服務(wù),就必須安裝這個(gè)證書
2. 發(fā)布證書 : 讓電腦具備發(fā)布程序的能力
3. 發(fā)布Profile : 記錄某臺(tái)電腦能發(fā)布某個(gè)程序
三.開(kāi)發(fā)推送功能, 需要先配置開(kāi)發(fā)者賬號(hào)
1. 打開(kāi)Xcode的推送服務(wù)
2. 配置推送開(kāi)發(fā)證書和推送發(fā)布證書
Xcode無(wú)法自動(dòng)配置推送證書, 必須手動(dòng)配置
第三方SDK
自己去看文檔.....額.....
2.本地推送
本地推送介紹
什么是本地推送通知
顧名思義珊楼,就是不需要聯(lián)網(wǎng)就能發(fā)出的推送通知(不需要服務(wù)器的支持)
本地推送通知的使用場(chǎng)景
常用來(lái)定時(shí)提醒用戶完成一些任務(wù)疯坤,比如
清理垃圾抹腿、記賬、買衣服秕硝、看電影、玩游戲
如何發(fā)出本地推送通知
1. 通知的授權(quán), 只需一次
2. 創(chuàng)建本地推送通知對(duì)象
3. 設(shè)置相關(guān)屬性: 發(fā)送時(shí)間洲尊、提醒內(nèi)容远豺、聲音等
4. 添加到本地通知調(diào)度池中
iOS10本地推送實(shí)現(xiàn)
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
/*
1. 通知的授權(quán), 只需一次
2. 創(chuàng)建本地推送通知對(duì)象
3. 設(shè)置相關(guān)屬性: 發(fā)送時(shí)間、提醒內(nèi)容坞嘀、聲音等
4. 添加到本地通知調(diào)度池中
*/
// 一. 通知的授權(quán), 只需一次 (不需要配置plist)
//1. 創(chuàng)建用戶通知中心
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
//2. 進(jìn)行授權(quán)(遠(yuǎn)程/本地通用)
[center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert) completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (granted) {
NSLog(@"授權(quán)成功");
} else {
NSLog(@"error: %@", error);
}
}];
//3. 設(shè)置代理
center.delegate = self;
return YES;
}
- (IBAction)sendLocalNotificationClick:(id)sender {
//本地推送和遠(yuǎn)程推送邏輯是類似的. 只不過(guò)將設(shè)置數(shù)據(jù)的部分放到了本地
//1. 設(shè)置通知的內(nèi)容, 必須使用 UNNotificationContent 的可變子類
UNMutableNotificationContent *content = [UNMutableNotificationContent new];
//設(shè)置附件
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"icon" ofType:@"png"]];
UNNotificationAttachment *attachment = [UNNotificationAttachment attachmentWithIdentifier:@"attachment" URL:url options:nil error:nil];
content.attachments = @[attachment];
//設(shè)置提醒文字
content.title = @"你好";
content.subtitle = @"呵呵";
content.body = @"女神: 去洗澡";
//設(shè)置角標(biāo)
content.badge = @([UIApplication sharedApplication].applicationIconBadgeNumber + 1);
//設(shè)置聲音
content.sound = [UNNotificationSound soundNamed:@"8360.mp3"];
//設(shè)置用于傳值的字典
content.userInfo = @{@"url" : @"https://www.baidu.com"};
//2. 設(shè)置觸發(fā)的時(shí)間 --> 使用子類設(shè)置
//如果設(shè)置重復(fù), 間隔至少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. 創(chuàng)建通知請(qǐng)求
UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:@"notifi1" content:content trigger:trigger];
//4. 添加到本地通知調(diào)度池中 --> iOS10添加本地通知到通知中心
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
[center addNotificationRequest:request withCompletionHandler:nil];
}
3.接收iOS10本地推送的值
//只能在前臺(tái)運(yùn)行時(shí)被調(diào)用 --> 可以獲取通知的值, 還可以設(shè)置前臺(tái)運(yùn)行時(shí)是否要顯示通知
- (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信息, 具體的邏輯處理將來(lái)看公司的需求
NSLog(@"notification: %@", notification.request.content.userInfo);
//這個(gè)設(shè)置通知呈現(xiàn)的樣式, 是iOS10增加的
completionHandler(UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionSound);
}
//前臺(tái)/后臺(tái)/退出, 都可以調(diào)用此方法
//點(diǎn)擊了通知之后會(huì)調(diào)用
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)())completionHandler __IOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0) __TVOS_PROHIBITED {
//可以獲取用戶的userInfo信息, 具體的邏輯處理將來(lái)看公司的需求
NSLog(@"notification: %@", response.notification.request.content.userInfo);
UISwitch *s = [UISwitch new];
s.frame = CGRectMake(30, 300, 0, 0);
[self.window addSubview:s];
//蘋果要求調(diào)用
completionHandler();
}
iOS8的實(shí)現(xiàn)...
過(guò)期了就算了....
傳感器
指紋識(shí)別
5S開(kāi)始才有的指紋識(shí)別, 目前絕大部分的設(shè)備都可以支持
iOS8的時(shí)候蘋果開(kāi)放了指紋識(shí)別的API
需要LocalAuthentication框架
//前提: 判斷設(shè)備/判斷版本
//1. 創(chuàng)建本地驗(yàn)證上下文對(duì)象
LAContext *context = [LAContext new];
//2. 判斷指紋識(shí)別是否可用d
//Evaluate: 執(zhí)行 Policy: 策略 Biometrics: 生物識(shí)別
if (![context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:nil]) {
NSLog(@"指紋識(shí)別不可用");
return;
}
//3. 如果可用就調(diào)用
[context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics localizedReason:@"請(qǐng)?jiān)试S訪問(wèn)" reply:^(BOOL success, NSError * _Nullable error) {
if (success) {
NSLog(@"指紋識(shí)別成功");
//打開(kāi)對(duì)應(yīng)的功能操作
} else {
NSLog(@"error: %@", error);
}
}];
注意1:更新UI放主線程
注意2:需要判斷error.code 用戶取消和驗(yàn)證失敗的邏輯可能不一樣
距離傳感器
- (void)viewDidLoad {
[super viewDidLoad];
//1. 打開(kāi)距離傳感器
//proximity: 接近 Monitoring: 檢測(cè)
[UIDevice currentDevice].proximityMonitoringEnabled = YES;
//2. 添加通知來(lái)獲取值
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceProximityStateDidChangeNotification) name:UIDeviceProximityStateDidChangeNotification object:nil];
}
//3. 添加通知來(lái)獲取值
- (void)deviceProximityStateDidChangeNotification {
if ([UIDevice currentDevice].proximityState) {
NSLog(@"逗比靠近了");
} else {
NSLog(@"逗比被嚇跑了");
}
}
運(yùn)動(dòng)管理器
1.加速計(jì)
//0. 創(chuàng)建運(yùn)動(dòng)管理器
_motionMgr = [CMMotionManager new];
//一. 加速計(jì) accelerometer --Push
//1. 判斷加速計(jì)是否可用
if (![_motionMgr isAccelerometerAvailable]) {
return NSLog(@"加速計(jì)不可用");
}
//2. 設(shè)置更新間隔
_motionMgr.accelerometerUpdateInterval = 1;
//3. 開(kāi)始統(tǒng)計(jì)數(shù)據(jù)
[_motionMgr startAccelerometerUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMAccelerometerData * _Nullable accelerometerData, NSError * _Nullable error) {
//加速計(jì)數(shù)據(jù)
//哪個(gè)軸的方向, 指向了地面, 那么這個(gè)軸方向的數(shù)據(jù), 就會(huì)被加速計(jì)統(tǒng)計(jì)
//數(shù)據(jù)在1和-1之間
//加速計(jì)是檢測(cè)力在某個(gè)方向上有作用. 如果速度越快, 值越大
CMAcceleration acceleration = accelerometerData.acceleration;
NSLog(@"x: %f, y: %f, z:%f", acceleration.x, acceleration.y, acceleration.z);
}];
//一. 加速計(jì) accelerometer --Pull --> 主動(dòng)獲取數(shù)據(jù), 當(dāng)需要的時(shí)候再去獲取
//1. 判斷加速計(jì)是否可用
if (![_motionMgr isAccelerometerAvailable]) {
return NSLog(@"加速計(jì)不可用");
}
//2. 開(kāi)始統(tǒng)計(jì)數(shù)據(jù)
[_motionMgr startAccelerometerUpdates];
2.陀螺儀 --> 將加速計(jì)的Accelerometer替換成Gyro即可
3.磁力計(jì) --> 磁力計(jì) Magnetometer : 檢測(cè)磁場(chǎng)變化
搖一搖
//開(kāi)始搖動(dòng)
- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event {
NSLog(@"開(kāi)始搖動(dòng)");
}
//搖動(dòng)結(jié)束
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event {
NSLog(@"搖動(dòng)結(jié)束");
}
//搖動(dòng)取消
- (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event {
NSLog(@"搖動(dòng)取消");
}
計(jì)步器
//1. 判斷計(jì)步器是否可用
if (![CMPedometer isStepCountingAvailable]) {
NSLog(@"計(jì)步功能不可用");
return ;
};
//2. 創(chuàng)建計(jì)步器 --> iOS8出現(xiàn)的,
_pedomter = [CMPedometer new];
//3. 開(kāi)始計(jì)步 --> 從當(dāng)前時(shí)間開(kāi)始統(tǒng)計(jì)
[_pedomter startPedometerUpdatesFromDate:[NSDate date] withHandler:^(CMPedometerData * _Nullable pedometerData, NSError * _Nullable error) {
[self performSelectorOnMainThread:@selector(updateUI:) withObject:pedometerData.numberOfSteps waitUntilDone:YES];
}];