iOS 关于手机权限的检查与获取
手机通讯录权限:
/**
* 检测权限并作响应的操作
*/
- (void)checkAuthorizationStatus:(UISwitch *)sender {
switch (ABAddressBookGetAuthorizationStatus()) {
case kABAuthorizationStatusAuthorized: //存在权限
//获取通讯录
self.phonesAry = [self obtainContacts:self.addressBook];
if (_setAddBookBlock) {
_setAddBookBlock(sender.isOn ? 0 : 1, _phonesAry);
}
break;
case kABAuthorizationStatusNotDetermined: //权限未知
//请求权限
[self requestAuthorizationStatus:sender];
break;
case kABAuthorizationStatusDenied: //如果没有权限 需要提示
case kABAuthorizationStatusRestricted:
//弹窗提醒
{
NSString *appName = kApp_Display_Name;
UIAlertView *alertview = [[UIAlertView alloc]initWithTitle:[NSString stringWithFormat:@"%@没有获取手机通讯录的权限",appName] message:[NSString stringWithFormat:@"请在“[设置]-[隐私]-[通讯录]”里允许%@使用",appName] delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
[alertview show];
//重置开关
dispatch_async(dispatch_get_main_queue(), ^{
[sender setOn:NO];
});
}
break;
default:
break;
}
}
/**
* 请求通讯录的权限
*/
- (void)requestAuthorizationStatus:(UISwitch *)sender {
WeakSelf(self);
ABAddressBookRequestAccessWithCompletion(self.addressBook, ^(bool granted, CFErrorRef error) {
//权限得到允许
if (granted == true) {
dispatch_async(dispatch_get_main_queue(), ^{
[sender setOn:YES];
weakSelf.phonesAry = [weakSelf obtainContacts:weakSelf.addressBook];
if (weakSelf.setAddBookBlock) {
weakSelf.setAddBookBlock(sender.isOn ? 0 : 1, weakSelf.phonesAry);
}
});
} else {
//不允许
dispatch_async(dispatch_get_main_queue(), ^{
[sender setOn:NO];
});
}
});
}
/**
* 获取通讯录中的联系人
*/
- (NSMutableArray *)obtainContacts:(ABAddressBookRef)addressBook {
//按照添加时间请求所有的联系人
CFArrayRef contants = ABAddressBookCopyArrayOfAllPeople(addressBook);
//存放所有联系人电话号码的数组
NSMutableArray *allNumArray = [NSMutableArray arrayWithCapacity:0];
//遍历获取所有的数据
for (NSInteger i = 0; i < CFArrayGetCount(contants); i++) {
//获得People对象
ABRecordRef recordRef = CFArrayGetValueAtIndex(contants, i);
NSArray *contact = [self contactPhonePropertyWithRecordRef:recordRef];
//添加对象
[allNumArray addObjectsFromArray:contact];
}
//释放资源
CFRelease(contants);
return allNumArray;
}
//获取单个联系人的电话号码数组
- (NSArray *)contactPhonePropertyWithRecordRef:(ABRecordRef)recordRef {
//外传数组
NSMutableArray *phones = [NSMutableArray arrayWithCapacity:0];
//获得电话号码的多值对象
ABMultiValueRef values = ABRecordCopyValue(recordRef, kABPersonPhoneProperty);
for (NSInteger i = 0; i < ABMultiValueGetCount(values); i++) {
//电话号码
NSString *phoneNumber = (__bridge NSString *)ABMultiValueCopyValueAtIndex(values, i);
//添加数据
[phones addObject:phoneNumber];
}
//释放资源
CFRelease(values);
return [NSArray arrayWithArray:phones];
}
相机权限:
//检查相机权限
- (void)checkVideoStatus {
AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
switch (authStatus) {
case AVAuthorizationStatusNotDetermined:
//没有询问是否开启相机
break;
case AVAuthorizationStatusRestricted:
//未授权,家长限制
break;
case AVAuthorizationStatusDenied:
//未授权
break;
case AVAuthorizationStatusAuthorized:
//玩家授权
break;
default:
break;
}
}
//授权相机
- (void)videoAuthAction {
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
if (granted) {
//相机准许
} else {
//相机不准许
}
}];
}
麦克风权限:
//检查麦克风权限
- (void)checkAudioStatus {
AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio];
switch (authStatus) {
case AVAuthorizationStatusNotDetermined:
//没有询问是否开启麦克风
break;
case AVAuthorizationStatusRestricted:
//未授权,家长限制
break;
case AVAuthorizationStatusDenied:
//玩家未授权
break;
case AVAuthorizationStatusAuthorized:
//玩家授权
break;
default:
break;
}
}
//授权麦克风
- (void)audioAuthAction {
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeAudio completionHandler:^(BOOL granted) {
if (granted) {
//麦克风准许
} else {
//麦克风不准许
}
}];
}
照片权限:
//检查照片权限
- (void) checkPhotoStauts{
PHAuthorizationStatus photoAuthorStatus = [PHPhotoLibrary authorizationStatus];
switch (photoAuthorStatus) {
case PHAuthorizationStatusAuthorized:
break;
case PHAuthorizationStatusDenied:
break;
case PHAuthorizationStatusNotDetermined:
break;
case PHAuthorizationStatusRestricted:
break;
default:
break;
}
}
//授权照片
- (void)phontLibraryAction{
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
dispatch_async(dispatch_get_main_queue(), ^{
if (status == PHAuthorizationStatusAuthorized) {
//照片允许
} else {
[[[UIAlertView alloc] initWithTitle:[NSString stringWithFormat:@"%@没有使用照片的权限",kApp_Display_Name] message:[NSString stringWithFormat:@"请在“[设置]-[隐私]-[照片]”里允许%@使用",kApp_Display_Name] delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil] show];
}
});
}];
}
定位权限:
+ (instancetype)shareInstance {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [[LocationManager alloc] init];
});
return _instance;
}
- (instancetype)init {
if (self = [super init]) {
//定位管理器
_locationManager = [CLLocationManager new];
_geocoder = [CLGeocoder new];
}
return self;
}
//设置定位管理
- (void)setLocationManager {
if (![CLLocationManager locationServicesEnabled]) {
DLog(@"定位信息没有开启");
};
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined) {
if ([DeviceInfo getCurrentDeviceVersion] >= 8) {
[_locationManager requestWhenInUseAuthorization];//?只在前台开启定位
//[_locationManager requestAlwaysAuthorization];//?在后台也可定位
}
// 5.iOS9新特性:将允许出现这种场景:同一app中多个location manager:一些只能在前台定位,另一些可在后台定位(并可随时禁止其后台定位)。
// if ([DeviceInfo getCurrentDeviceVersion] >= 9) {
// _locationManager.allowsBackgroundLocationUpdates = YES;
// }
} else if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorizedWhenInUse) {
//设置代理
_locationManager.delegate = self;
//设置定位精度
_locationManager.desiredAccuracy = kCLLocationAccuracyBest;
//定位频率,每隔多少米定位一次
CLLocationDistance distance = 100;//百米定位一次
_locationManager.distanceFilter = distance;
//启动跟踪定位
[_locationManager startUpdatingLocation];
}
}
#pragma mark - CoreLocation 代理
#pragma mark 跟踪定位代理方法,每次位置发生变化即会执行(只要定位到相应位置)
//可以通过模拟器设置一个虚拟位置,否则在模拟器中无法调用此方法
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
CLLocation *location = [locations firstObject];//取出第一个位置
CLLocationCoordinate2D coordinate = location.coordinate;//位置坐标
_longitude = [NSString stringWithFormat:@"%f",coordinate.longitude];
_latitude = [NSString stringWithFormat:@"%f",coordinate.latitude];
[self getAddressByLatitude:coordinate.latitude longitude:coordinate.longitude];
if (_sendPointBlock) {
_sendPointBlock(_latitude,_longitude);
}
// [[iToast makeText:@"正在定位....."] show];
//31.20476569,+121.62868477
// [self getAddressByLatitude:coordinate.longitude longitude:coordinate.latitude];
//如果不需要实时定位,使用完即使关闭定位服务
[_locationManager stopUpdatingLocation];
}
#pragma mark 根据地名确定地理坐标
- (void)getCoordinateByAddress:(NSString *)address{
//地理编码
[_geocoder geocodeAddressString:address completionHandler:^(NSArray *placemarks, NSError *error) {
//取得第一个地标,地标中存储了详细的地址信息,注意:一个地名可能搜索出多个地址
// CLPlacemark *placemark=[placemarks firstObject];
//
// CLLocation *location=placemark.location;//位置
// CLRegion *region=placemark.region;//区域
// NSDictionary *addressDic= placemark.addressDictionary;//详细地址信息字典,包含以下部分信息
//NSString *name=placemark.name;//地名
//NSString *thoroughfare=placemark.thoroughfare;//街道
//NSString *subThoroughfare=placemark.subThoroughfare; //街道相关信息,例如门牌等
//NSString *locality=placemark.locality; // 城市
//NSString *subLocality=placemark.subLocality; // 城市相关信息,例如标志性建筑
//NSString *administrativeArea=placemark.administrativeArea; // 州
//NSString *subAdministrativeArea=placemark.subAdministrativeArea; //其他行政区域信息
//NSString *postalCode=placemark.postalCode; //邮编
//NSString *ISOcountryCode=placemark.ISOcountryCode; //国家编码
//NSString *country=placemark.country; //国家
//NSString *inlandWater=placemark.inlandWater; //水源、湖泊
//NSString *ocean=placemark.ocean; // 海洋
//NSArray *areasOfInterest=placemark.areasOfInterest; //关联的或利益相关的地标
//NSLog(@"位置:%@,区域:%@,详细信息:%@",location,region,addressDic);
}];
}
#pragma mark 根据坐标取得地名
-(void)getAddressByLatitude:(CLLocationDegrees)latitude longitude:(CLLocationDegrees)longitude {
//反地理编码
CLLocation *location = [[CLLocation alloc] initWithLatitude:latitude longitude:longitude];
[_geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {
CLPlacemark *placemark = [placemarks firstObject];
_name = placemark.name;//名称
_locality = placemark.locality;//城市名
_area = placemark.subLocality;//区
_thoroughfare = placemark.thoroughfare;//街道
dispatch_async(dispatch_get_main_queue(), ^{
if (_addressBlock) {
_addressBlock(_locality,_area);
}
});
// [[iToast makeText:_name] show];
// [[iToast makeText:_locality] show];
// [[iToast makeText:[NSString stringWithFormat:@"%@",error]] show] ;
}];
}
相关文章:

也谈谈区块链技术
链客,专为开发者而生,有问必答! 此文章来自区块链社区,未经允许拒绝转载。 现在区块链技术很火,而且几乎被上升到了一个“革命性”的高度,很多股票居然都因为沾了点区块链变得炙手可热。其实这玩意没有这么…

nyoj——297(期望)
GoroSort 时间限制:3000 ms | 内存限制:65535 KB难度:4描述Goro has 4 arms. Goro is very strong. You dont mess with Goro. Goro needs to sort an array of N different integers. Algorithms are not Goros strength; strength is Gor…

js ajax调用请求
<pre name"code" class"html"> function getAppList(env){var data {};data.env env;var successfn function(jdata){$(".deploy_list").html("");_HTML "<tr><th>发布清单</th></tr>";$…

iOS SDWebImage加载webp
项目更新使用的最新版本的SDWebImage, 需配置如下: Build Settings -> preprocessor macros -> 添加 SD_WEBP1

区块链之初识区块链
链客,专为开发者而生,有问必答! 此文章来自链客区块链技术问答社区,未经允许拒绝转载。 首先得明白几个概念:区块链,比特币,中心化,去中心化,挖矿 区块链和比特币 区…

Linux RSS/RPS/RFS/XPS对比
RSS适合于多队列网卡,把不同的流分散的不同的网卡多列中,至于网卡队列由哪个cpu处理还需要绑定网卡队列中断与cpuRPS:适合于单队列网卡或者虚拟网卡,把该网卡上的数据流让多个cpu处理RFS:当流量需要传输到用户态处理时…
iOS 关于UIView覆盖StatusBar的小知识点
项目中有关于浏览图片的需求, 自己写了一套, 但是一直有个关于StatusBar的问题: 因为在查看图片时隐藏掉了StatusBar, 当结束查看后再显示sta会发现整个界面下滑了20px, 在IM聊天界面这个滑动效果很不友好 最近在优化这一块东西时又想到了这个问题, 现在得到了比较好的解决方…

从数字货币说起
链客,专为开发者而生,有问必答! 此文章来自链客区块链技术问答社区,未经允许拒绝转载。 从数字货币说起 历史上,货币的形态经历了多个阶段的演化,包括实物货币、金属货币、代用货币、信用货币、电子货币、…

git常用命令及规范流程
参考地址:https://www.cnblogs.com/my--sunshine/p/7093412.html,感谢分享 官网地址:https://git-scm.com/book/zh/v2 git init 在本地新建一个repo,进入一个项目目录,执行git init,会初始化一个repo,并在当前文件夹下创建一个.git文件夹.git…

关于iOS 11的适配
距离iOS 11正式发布也有小半年了, 陆陆续续也看到许多关于iOS 11和iPhone X适配相关的文章, 现记录下自己做适配所做的工作 首先给出自己适配所用到的宏定义, 如下://状态栏 #define kStatusBarHeight [[UIApplication sharedApplication] statusBarFrame].size.height //导航条…

PHP实现队列的原理
关于的队列的介绍,我这里就不多讲了,随便百度一下都很多 用过laravel框架的童鞋都知道其自带队列功能,之前我很费解,PHP只是一个脚本,有超时机制 为什么能不停的去执行队列呢? 带着这个问题,在网…

实现代币的管理者
链客,专为开发者而生,有问必答! 此文章来自区块链技术社区,未经允许拒绝转载。 实现代币的管理者 虽然区块链是去中心化的,但是实现对代币(合约)的管理,也在许多应用中有需求&…

Oracle数据库基本操作(二) —— 视图、序列、索引、同义词
一、视图(Views)与 同义词 1、视图:实际上是对查询结果集的封装,视图本身不存储任何数据,所有的数据都存放在原来的表中; 在逻辑上可以把视图看作是一张表 2、作用: 封装查询语句,简化复杂的查询需求屏蔽表中的细节3、语法: create [or replace] view 视…
iOS crash日志分析
项目集成talkingdata收集到的crash日志, 看到那些日志时自己也是很崩溃, 全是内存地址, 根本搞不懂项目到底crash到了那里, 比如这样:自己在网上找了很多方法, 以下是自己最后所用到的方法(心累): 1, 首先拿到.dSYM 文件, 步骤:XCode中的Window -> Organizer -> 找到App …

Xamarin Android项目运行失败
Xamarin Android项目运行失败 错误信息:Build Failed: MonoDroid does not support running the previous version. Please ensure your solution builds before running or debugging it.这是由于由于项目生成失败,并找不到以前编译的结果。这时&#…

logging模块
import logging from conf import settingsdef logger(log_type):# 生成 logger 对象logger logging.getLogger(log_type)logger.setLevel(settings.LOG_LEVEL)# 生成handler对象,向文件输出日志信息log_file "%s/log/%s.log" % (settings.BASE_DIR, lo…

iOS 模糊效果相关
项目中一直有使用到模糊处理, 例如图片的高斯模糊, 一直使用的代码如下: // 内部方法,核心代码,封装了毛玻璃效果 参数:半径,颜色,色彩饱和度 - (UIImage *)imgBluredWithRadius:(CGFloat)blurRadius tintColor:(UIColor *)tintColor saturationDeltaFactor:(CGFloat)saturati…

CDN的原理及对SEO的影响
http://www.williamlong.info/archives/4059.html CDN的概念最早于1995年由美国麻省理工大学提出,是一套能够实现用户就近访问的网络解决方案。具体方法是:采用智能路由和流量管理技术,将用户的访问请求指向 CDN网络中健康且响应最快的CDN节点…

JavaScript学习笔记 - 入门篇(1)- 准备
为什么学习JavaScript 一、你知道,为什么JavaScript非常值得我们学习吗? 所有主流浏览器都支持JavaScript。目前,全世界大部分网页都使用JavaScript。它可以让网页呈现各种动态效果。做为一个Web开发师,如果你想提供漂亮的网页、令…

iOS关于像素的适配
项目中很多地方会用到分割线, 一般设置为1.0, 但是在不同的机型上这个1.0显示的效果是不同的,1x的机型上正常, 2x和3x的机型上显示的就会很粗, 影响适配, 困扰很久后得到了以下解决办法, 在此记录一下: 1.0/UIScreen.mainScreen.scale

非对称加密中公钥
链客,专为开发者而生,有问必答! 此文章来自区块链技术社区,未经允许拒绝转载。 数字签名是公钥密码体系中签名验证功能的一个应用。其目的是保证信息传输的完整性、发送者的身份认证、防止交易中的抵赖发生。其中数字签名是个加密…

bzoj 4813: [Cqoi2017]小Q的棋盘【树形dp】
这么简单的dp我怎么没想到x2 f为从这个点出发后回到这个点最多能走过的点,g为从这个点出发后不回到这个点最多能走过的点,注意g有两种转移:g[u][k]max(g[u][k],f[u][k-j-1]g[e[i].to][j])是在e[i].to这个子树前走了一棵子树再回来,…

spring WebServiceTemplate 调用 axis1.4 发布的webservice
前言: 最近在开发中需要调用对方的 webservice服务,按照现有的技术,本应该是一件很简单的事情,只需要拿到wsdl文件,生成客户端代码即可,但是,对方的webservice服务是06年用axis1.4生成发布的&am…

iOS 获取Assets中的启动页
app启动时先进入一个广告页, 若无广告图则用启动页占位, 一直为这个占位图的适配烦恼, 最近查资料终于找到了结果, 现记录一下: - (UIImage *)getLaunchImage { CGSize viewSize [UIScreen mainScreen].bounds.size; NSString *viewOrientation "Portrait";//方向…

SunlightChain 区块链宣言
链客,专为开发者而生,有问必答! 此文章来自区块链技术社区,未经允许拒绝转载。 SunlightChain 区块链宣言 区块链技术的应用必将颠覆现在过度依赖于中心的经济模式,它与生俱来的开放、共享、去中心化等特点极大地提高…

Ajax跨域:Jsonp原理解析
推荐先看下这篇文章:JS跨域(ajax跨域、iframe跨域)解决方法及原理详解(jsonp) JavaScript是一种在Web开发中经常使用的前端动态脚本技术。在JavaScript中,有一个很重要的安全性限制,被称为“Sam…

iOS 微信SDK1.8.6后需要UniversalLink解决方案及采坑记录
项目最初因审核原因,一直使用iOS原生分享, 最近因项目需求要求, 接入微信分享, 以为和原来的没有区别, 但是接入时才发现改动的地方还是挺多的, 主要是需要配置UniversalLink和提包时的一些问题, 在此做一下记录 UniversalLink配置步骤 1.制作apple-app-site-association文件…

GO语言编程基础-复合类型结构体
链客,专为开发者而生,有问必答! 此文章来自区块链技术社区,未经允许拒绝转载。 1 结构体类型 有时我们需要将不同类型的数据组合成一个有机的整体,如:一个学生有学号/姓名/性别/年龄/地址等属性。显然单独…

【BZOJ1015】【JSOI2008】星球大战 并查集
题目大意 给你一张\(n\)个点\(m\)条边的无向图,有\(q\)次操作,每次删掉一个点以及和这个点相邻的边,求最开始和每次删完点后的连通块个数。 \(q\leq n\leq 400000,m\leq 200000\) 题解 我们可以用并查集维护连通块个数,可惜并查集…

python基于Django框架编译报错“django.core.exceptions.ImproperlyConfigured”的解决办法?...
下面是我具体遇到的问题和解决方法: 错误详细信息: django.core.exceptions.ImproperlyConfigured: Requested setting DEFAULT_INDEX_TABLESPACE, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_…