2017-09-14 16:39:40 CodingFire 阅读数 481
  • iOS开发-全面解析iOS蓝牙BLE4.0开发

    只要你会OC基础,会写HelloWorld,你就可以实现iOS的蓝牙通信功能,实现蓝牙小项目也不在话下,作者会带领大家详细分析BLE4.0原理,通过分析xcode使用的蓝牙API,让学者能够得心应手的实现蓝牙BLE4.0的开发

    3673 人正在学习 去看看 许英俊

iOS10以来,开发时都需要加入各种权限,通讯录,相册,蓝牙,麦克风,位置信息等等,一开始都是根据自己的需要来加入不同的权限,但是近期突然发现有几个权限属于必加的,否则即使传上去也不能够提交,状态一直是wait submit,料想这种情况出现也有一段时间了。还好去看了绑定的邮箱,苹果有提醒邮件,可以帮助开发者检查权限问题:

Dear developer,
We have discovered one or more issues with your recent delivery for "XXXX". To process your delivery, the following issues must be corrected:
Missing Info.plist key - This app attempts to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSMicrophoneUsageDescription key with a string value explaining to the user how the app uses this data.
Once these issues have been corrected, you can then redeliver the corrected binary.
Regards,
The App Store team

这里博主是因为没有加麦克风权限(因为项目中并没有用到这个功能),被拒绝使用这个包的,至于哪些是必加的还不好说,既然麦克风都加了,那常用的几个肯定要加的如下:

Privacy - Camera Usage Description
Privacy - Contacts Usage Description
Privacy - Microphone Usage Description
Privacy - Photo Library Usage Description
Privacy - Location Always Usage Description(位置信息的还没试过不传会不会发生这种情况,但目前看来,其余四个应该是必加了。)

如果碰到App的invalid binary问题,不知道什么问题的话就看看邮箱吧,也许就是权限的问题了。后面碰到其他问题会继续更新。

2016-04-27 14:46:18 jsjxiaobing 阅读数 1774
  • iOS开发-全面解析iOS蓝牙BLE4.0开发

    只要你会OC基础,会写HelloWorld,你就可以实现iOS的蓝牙通信功能,实现蓝牙小项目也不在话下,作者会带领大家详细分析BLE4.0原理,通过分析xcode使用的蓝牙API,让学者能够得心应手的实现蓝牙BLE4.0的开发

    3673 人正在学习 去看看 许英俊

在iOS开发中,有时会有跳转系统设置界面的需求,例如提示用户打开蓝牙或者WIFI,提醒用户打开推送或者位置权限等。在iOS6之后,第三方应用需要跳转系统设置界面,需要在URL type中添加一个prefs值,如下图:



打开WiFi的设置页面 

- (IBAction)setWifi:(id)sender {
    NSString * UIApplicationOpenSettingsURLString = @"prefs:root=WIFI";
    NSURL * url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
    
    if([[UIApplication sharedApplication] canOpenURL:url]) {
        [[UIApplication sharedApplication] openURL:url];
    }
}

有很多系统的其他设置代码如下:

About — prefs:root=General&path=About
 
 Accessibility — prefs:root=General&path=ACCESSIBILITY
 
 AirplaneModeOn— prefs:root=AIRPLANE_MODE
 
 Auto-Lock — prefs:root=General&path=AUTOLOCK
 
 Brightness — prefs:root=Brightness
 
 Bluetooth — prefs:root=General&path=Bluetooth
 
 Date& Time — prefs:root=General&path=DATE_AND_TIME
 
 FaceTime — prefs:root=FACETIME
 
 General— prefs:root=General
 
 Keyboard — prefs:root=General&path=Keyboard
 
 iCloud — prefs:root=CASTLE  iCloud
 
 Storage & Backup — prefs:root=CASTLE&path=STORAGE_AND_BACKUP
 
 International — prefs:root=General&path=INTERNATIONAL
 
 Location Services — prefs:root=LOCATION_SERVICES
 
 Music — prefs:root=MUSIC
 
 Music Equalizer — prefs:root=MUSIC&path=EQ
 
 Music VolumeLimit— prefs:root=MUSIC&path=VolumeLimit
 
 Network — prefs:root=General&path=Network
 
 Nike + iPod — prefs:root=NIKE_PLUS_IPOD
 
 Notes — prefs:root=NOTES
 
 Notification — prefs:root=NOTIFICATIONS_ID
 
 Phone — prefs:root=Phone
 
 Photos — prefs:root=Photos
 
 Profile — prefs:root=General&path=ManagedConfigurationList
 
 Reset — prefs:root=General&path=Reset
 
 Safari — prefs:root=Safari  Siri — prefs:root=General&path=Assistant
 
 Sounds — prefs:root=Sounds
 
 SoftwareUpdate— prefs:root=General&path=SOFTWARE_UPDATE_LINK
 
 Store — prefs:root=STORE
 
 Twitter — prefs:root=TWITTER
 
 Usage — prefs:root=General&path=USAGE
 
 VPN — prefs:root=General&path=Network/VPN
 
 Wallpaper — prefs:root=Wallpaper
 
 Wi-Fi — prefs:root=WIFI
 
 Setting—prefs:root=INTERNET_TETHERING
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"></span><pre name="code" class="objc">@{@"系统设置":@"prefs:root=INTERNET_TETHERING"},
@{@"WIFI设置":@"prefs:root=WIFI"},
@{@"蓝牙设置":@"prefs:root=Bluetooth"},
@{@"系统通知":@"prefs:root=NOTIFICATIONS_ID"},
@{@"通用设置":@"prefs:root=General"},
@{@"显示设置":@"prefs:root=DISPLAY&BRIGHTNESS"},
@{@"壁纸设置":@"prefs:root=Wallpaper"},
@{@"声音设置":@"prefs:root=Sounds"},
@{@"隐私设置":@"prefs:root=privacy"},
@{@"APP Store":@"prefs:root=STORE"},
@{@"Notes":@"prefs:root=NOTES"},
@{@"Safari":@"prefs:root=Safari"},
@{@"Music":@"prefs:root=MUSIC"},
@{@"photo":@"prefs:root=Photos"},
@{@"关于本机":@"prefs:root=General&path=About"},
@{@"软件升级":@"prefs:root=General&path=SOFTWARE_UPDATE_LINK"},
@{@"日期时间":@"prefs:root=General&path=DATE_AND_TIME"},
@{@"Accessibility":@"prefs:root=General&path=ACCESSIBILITY"},
@{@"键盘设置":@"prefs:root=General&path=Keyboard"},
@{@"VPN":@"prefs:root=General&path=VPN"},
@{@"壁纸设置":@"prefs:root=Wallpaper"},
@{@"声音设置":@"prefs:root=Sounds"},
@{@"隐私设置":@"prefs:root=privacy"},
@{@"APP Store":@"prefs:root=STORE"},
@{@"还原设置":@"prefs:root=General&path=Reset"},
@{@"应用通知":@"prefs:root=NOTIFICATIONS_ID&path=应用的boundleId"}



<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">打开自己的设置界面:</span>
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">
</span>
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
    if (buttonIndex != 0) {
        NSString * UIApplicationOpenSettingsURLString = @"prefs:root=com.xiaoxiaobing.APPA";
        NSURL * url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
        
        if([[UIApplication sharedApplication] canOpenURL:url]) {
            [[UIApplication sharedApplication] openURL:url];
        }
    }
}

其中  com.xiaoxiaobing.APPA  是你自己的程序的BundleID

测试Demo地址 https://github.com/sixTiger/APPJump


2017-08-03 12:24:27 SunFlowerInRain 阅读数 421
  • iOS开发-全面解析iOS蓝牙BLE4.0开发

    只要你会OC基础,会写HelloWorld,你就可以实现iOS的蓝牙通信功能,实现蓝牙小项目也不在话下,作者会带领大家详细分析BLE4.0原理,通过分析xcode使用的蓝牙API,让学者能够得心应手的实现蓝牙BLE4.0的开发

    3673 人正在学习 去看看 许英俊

在iOS开发中,有时会有跳转系统设置界面的需求,例如提示用户打开蓝牙或者WIFI,提醒用户打开推送或者位置权限等。

设置跳转有三种方式,每一种的使用场景都不同。 并且你在跳转到系统中自己应用下面设置的时候,你的应用要提前至少申请了某一个权限,如通知,定位等。否则,会引起崩溃。

方式一:prefs:root=某项服务

方式二:prefs:root=bundleID

方式三: UIApplicationOpenSettingsURLString

跳转
当 iOS系统版本 <= iOS7时 , 只能跳转到 系统设置页面

NSURL *url= [NSURL URLWithString:@"prefs:root=LOCATION_SERVICES"];

跳转到: 隐私-定位服务。


prefs:root=某项服务


系统设置:prefs:root=INTERNET_TETHERING


WIFI设置:prefs:root=WIFI


蓝牙设置:prefs:root=Bluetooth


系统通知:prefs:root=NOTIFICATIONS_ID


通用设置:prefs:root=General


显示设置:prefs:root=DISPLAY&BRIGHTNESS


壁纸设置:prefs:root=Wallpaper


声音设置:prefs:root=Sounds


隐私设置:prefs:root=privacy


蜂窝网路:prefs:root=MOBILE_DATA_SETTINGS_ID


音乐:prefs:root=MUSIC


APP Store:prefs:root=STORE


Notes:prefs:root=NOTES


Safari:prefs:root=Safari


Music:prefs:root=MUSIC


photo":prefs:root=Photos



这种跳转方式,都是跳转到系统的设置界面。 

当 iOS系统版本 >= iOS8 ,支持跳转到第三方应用的设置界面中使用prefs:root= bundleID ,

bundleID是你第三方应用工程的唯一ID  局限性:只支持iOS8,iOS9系统,在iOS10系统上,不会跳转。
当系统版本号大于iOS
UIApplicationOpenSettingsURLString字段,是在iOS8上才提供的,支持iOS8,iOS9,iOS10系统,推荐使用。

参考资料

2016-05-31 22:23:35 zm19920924 阅读数 205
  • iOS开发-全面解析iOS蓝牙BLE4.0开发

    只要你会OC基础,会写HelloWorld,你就可以实现iOS的蓝牙通信功能,实现蓝牙小项目也不在话下,作者会带领大家详细分析BLE4.0原理,通过分析xcode使用的蓝牙API,让学者能够得心应手的实现蓝牙BLE4.0的开发

    3673 人正在学习 去看看 许英俊

在iOS开发中,有时会有跳转系统设置界面的需求,例如提示用户打开蓝牙或者WIFI,提醒用户打开推送或者位置权限等。在iOS6之后,第三方应用需要跳转系统设置界面,需要在URL type中添加一个prefs值
如图:
这里写图片描述

跳转系统设置根目录中的项目使用如下的方法:
_array = @[
@{@”系统设置”:@”prefs:root=INTERNET_TETHERING”},
@{@”WIFI设置”:@”prefs:root=WIFI”},
@{@”蓝牙设置”:@”prefs:root=Bluetooth”},
@{@”系统通知”:@”prefs:root=NOTIFICATIONS_ID”},
@{@”通用设置”:@”prefs:root=General”},
@{@”显示设置”:@”prefs:root=DISPLAY&BRIGHTNESS”},
@{@”壁纸设置”:@”prefs:root=Wallpaper”},
@{@”声音设置”:@”prefs:root=Sounds”},
@{@”隐私设置”:@”prefs:root=privacy”},
@{@”APP Store”:@”prefs:root=STORE”},
@{@”Notes”:@”prefs:root=NOTES”},
@{@”Safari”:@”prefs:root=Safari”},
@{@”Music”:@”prefs:root=MUSIC”},
@{@”photo”:@”prefs:root=Photos”}
];
NSURL * url = [NSURL URLWithString:[_array[index] allValues].firstObject];
[[UIApplication sharedApplication]openURL:url];
例如要跳转到系统设置页面:
NSURL * url = [NSURL URLWithString:[_array[0] allValues].firstObject];
[[UIApplication sharedApplication]openURL:url];
如果要跳转第三方应用的设置界面中,使用prefs:root=boundleId的方式,boundleId是第三方应用的boundleId。

    如果需要继续向项目内层进行跳转,可以通过添加path路径的方式,如下:
    _array = @[
           @{@"关于本机":@"prefs:root=General&path=About"},
           @{@"软件升级":@"prefs:root=General&path=SOFTWARE_UPDATE_LINK"},
           @{@"日期时间":@"prefs:root=General&path=DATE_AND_TIME"},
           @{@"Accessibility":@"prefs:root=General&path=ACCESSIBILITY"},
           @{@"键盘设置":@"prefs:root=General&path=Keyboard"},
           @{@"VPN":@"prefs:root=General&path=VPN"},
           @{@"壁纸设置":@"prefs:root=Wallpaper"},
           @{@"声音设置":@"prefs:root=Sounds"},
           @{@"隐私设置":@"prefs:root=privacy"},
           @{@"APP Store":@"prefs:root=STORE"},
           @{@"还原设置":@"prefs:root=General&path=Reset"},
           @{@"应用通知":@"prefs:root=NOTIFICATIONS_ID&path=应用的boundleId"}
           ];
2016-06-30 15:00:45 ZWQ0325 阅读数 1265
  • iOS开发-全面解析iOS蓝牙BLE4.0开发

    只要你会OC基础,会写HelloWorld,你就可以实现iOS的蓝牙通信功能,实现蓝牙小项目也不在话下,作者会带领大家详细分析BLE4.0原理,通过分析xcode使用的蓝牙API,让学者能够得心应手的实现蓝牙BLE4.0的开发

    3673 人正在学习 去看看 许英俊

iOS应用开发免不了使用设备硬件资源,这是都是要用授权的,授权路径在设置->隐私;

一、定位服务

1、获取授权状态

- (void)checkLocationServicesAuthorizationStatus {
    /*
     We can ask the location services manager ahead of time what the authorization status is for our bundle and take the appropriate action.
     */
    [self reportLocationServicesAuthorizationStatus:[CLLocationManager authorizationStatus]];
}

- (void)reportLocationServicesAuthorizationStatus:(CLAuthorizationStatus)status {
    NSString *statusText = nil;
    if(status == kCLAuthorizationStatusNotDetermined) {
        statusText = NSLocalizedString(@"UNDETERMINED", @"");
    }
    else if(status == kCLAuthorizationStatusRestricted) {
        statusText = NSLocalizedString(@"RESTRICTED", @"");
    }
    else if(status == kCLAuthorizationStatusDenied) {
        statusText = NSLocalizedString(@"DENIED", @"");
    }
    else if(status == kCLAuthorizationStatusAuthorizedWhenInUse) {
        statusText = NSLocalizedString(@"LOCATION_WHEN_IN_USE", @"");
    }
    else if(status == kCLAuthorizationStatusAuthorizedAlways) {
        statusText = NSLocalizedString(@"LOCATION_ALWAYS", @"");
    }
    
    [self alertViewWithDataClass:Location status:statusText];
}
2、获取授权

- (void)requestLocationServicesAuthorization {
    if (!self.locationManager) {
        self.locationManager = [[CLLocationManager alloc] init];
        self.locationManager.delegate = self;
    }
    
    /*
     Gets user permission to get their location while the app is in the foreground.
     
     To monitor the user's location even when the app is in the background:
     1. Replace [self.locationManager requestWhenInUseAuthorization] with [self.locationManager requestAlwaysAuthorization]
     2. Change NSLocationWhenInUseUsageDescription to NSLocationAlwaysUsageDescription in InfoPlist.strings
     */
    [self.locationManager requestWhenInUseAuthorization];
    
    /*
     Requests a single location after the user is presented with a consent dialog.
     */
    [self.locationManager startUpdatingLocation];
}

#pragma mark - CLLocationMangerDelegate methods

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
    /*
     Handle the failure...
     */
    [self.locationManager stopUpdatingLocation];
}

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
    /*
     Do something with the new location the application just received...
     */
    [self.locationManager stopUpdatingLocation];
}

- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
    /*
     The delegate function will be called when the permission status changes the application should then attempt to handle the change appropriately by changing UI or setting up or tearing down data structures.
     */
    [self reportLocationServicesAuthorizationStatus:status];
}


3、plist中添加key

 NSLocationWhenInUseUsageDescription 或者 NSLocationAlwaysUsageDescription


二、通讯录

1、获取授权状态

iOS8

    ABAuthorizationStatus status = ABAddressBookGetAuthorizationStatus();
    if(status == kABAuthorizationStatusNotDetermined) {
        [self alertViewWithMessage:NSLocalizedString(@"UNDETERMINED", @"")];
    }
    else if(status == kABAuthorizationStatusRestricted) {
        
        [self alertViewWithMessage:NSLocalizedString(@"RESTRICTED", @"")];
    }
    else if(status == kABAuthorizationStatusDenied) {
        
        [self alertViewWithMessage:NSLocalizedString(@"DENIED", @"")];
    }
    else if(status == kABAuthorizationStatusAuthorized) {
        [self alertViewWithMessage:NSLocalizedString(@"GRANTED", @"")];
    }


iOS9

- (void)checkContactStoreAccess {
    /*
     We can ask the contact store ahead of time what the authorization status is for our bundle and take the appropriate action.
     */
    CNAuthorizationStatus status = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
    if(status == CNAuthorizationStatusNotDetermined) {
        [self alertViewWithDataClass:Contacts status:NSLocalizedString(@"UNDETERMINED", @"")];
    }
    else if(status == CNAuthorizationStatusRestricted) {
        [self alertViewWithDataClass:Contacts status:NSLocalizedString(@"RESTRICTED", @"")];
    }
    else if(status == CNAuthorizationStatusDenied) {
        [self alertViewWithDataClass:Contacts status:NSLocalizedString(@"DENIED", @"")];
    }
    else if(status == CNAuthorizationStatusAuthorized) {
        [self alertViewWithDataClass:Contacts status:NSLocalizedString(@"GRANTED", @"")];
    }
}

2、获取授权

iOS8

- (void)requestAddressBookAccess {
    CFErrorRef myError = NULL;
    ABAddressBookRef myAddressBook = ABAddressBookCreateWithOptions(NULL, &myError);
    APLPrivacyClassesTableViewController * __weak weakSelf = self;  // avoid capturing self in the block
    ABAddressBookRequestAccessWithCompletion(myAddressBook,^(bool granted, CFErrorRef error){

        [weakSelf checkAddressBookAccess];
                                                 
         CFRelease(myAddressBook);
    });

}

iOS9

- (void)requestContactStoreAccess {
    if(!self.contactStore) {
        self.contactStore = [[CNContactStore alloc] init];
    }
    
    [self.contactStore requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [self alertViewWithDataClass:Contacts status:(granted) ? NSLocalizedString(@"GRANTED", @"") : NSLocalizedString(@"DENIED", @"")];
            
            /*
             Do something with the access to the contact store...
             */
        });
    }];    
}


3、plist中添加key

NSContactsUsageDescription


三、日历

1、授权状态

 [self checkEventStoreAccessForType:EKEntityTypeEvent];
- (void)checkEventStoreAccessForType:(EKEntityType)type {
    /*
     We can ask the event store ahead of time what the authorization status is for our bundle and take the appropriate action.
     */
    EKAuthorizationStatus status = [EKEventStore authorizationStatusForEntityType:type];
    if(status == EKAuthorizationStatusNotDetermined) {
        [self alertViewWithDataClass:((type == EKEntityTypeEvent) ? Calendars : Reminders) status:NSLocalizedString(@"UNDETERMINED", @"")];
    }
    else if(status == EKAuthorizationStatusRestricted) {
        [self alertViewWithDataClass:((type == EKEntityTypeEvent) ? Calendars : Reminders) status:NSLocalizedString(@"RESTRICTED", @"")];
    }
    else if(status == EKAuthorizationStatusDenied) {
        [self alertViewWithDataClass:((type == EKEntityTypeEvent) ? Calendars : Reminders) status:NSLocalizedString(@"DENIED", @"")];
    }
    else if(status == EKAuthorizationStatusAuthorized) {
        [self alertViewWithDataClass:((type == EKEntityTypeEvent) ? Calendars : Reminders) status:NSLocalizedString(@"GRANTED", @"")];
    }
}

2、获取授权

            [self requestEventStoreAccessWithType:EKEntityTypeEvent];

- (void)requestEventStoreAccessWithType:(EKEntityType)type {
    if(!self.eventStore) {
        self.eventStore = [[EKEventStore alloc] init];
    }
    
    /*
     When the application requests to receive event store data that is when the user is presented with a consent dialog.
     */
    [self.eventStore requestAccessToEntityType:type completion:^(BOOL granted, NSError *error) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [self alertViewWithDataClass:((type == EKEntityTypeEvent) ? Calendars : Reminders) status:(granted) ? NSLocalizedString(@"GRANTED", @"") : NSLocalizedString(@"DENIED", @"")];
            
            /*
             Do something with the access to eventstore...
             */
        });
    }];
}

3、plist中添加key

NSCalendarsUsageDescription


四、提醒事项

1、权限状态

            [self checkEventStoreAccessForType:EKEntityTypeReminder];

- (void)checkEventStoreAccessForType:(EKEntityType)type {
    /*
     We can ask the event store ahead of time what the authorization status is for our bundle and take the appropriate action.
     */
    EKAuthorizationStatus status = [EKEventStore authorizationStatusForEntityType:type];
    if(status == EKAuthorizationStatusNotDetermined) {
        [self alertViewWithDataClass:((type == EKEntityTypeEvent) ? Calendars : Reminders) status:NSLocalizedString(@"UNDETERMINED", @"")];
    }
    else if(status == EKAuthorizationStatusRestricted) {
        [self alertViewWithDataClass:((type == EKEntityTypeEvent) ? Calendars : Reminders) status:NSLocalizedString(@"RESTRICTED", @"")];
    }
    else if(status == EKAuthorizationStatusDenied) {
        [self alertViewWithDataClass:((type == EKEntityTypeEvent) ? Calendars : Reminders) status:NSLocalizedString(@"DENIED", @"")];
    }
    else if(status == EKAuthorizationStatusAuthorized) {
        [self alertViewWithDataClass:((type == EKEntityTypeEvent) ? Calendars : Reminders) status:NSLocalizedString(@"GRANTED", @"")];
    }
}

2、获取权限

            [self requestEventStoreAccessWithType:EKEntityTypeReminder];

- (void)requestEventStoreAccessWithType:(EKEntityType)type {
    if(!self.eventStore) {
        self.eventStore = [[EKEventStore alloc] init];
    }
    
    /*
     When the application requests to receive event store data that is when the user is presented with a consent dialog.
     */
    [self.eventStore requestAccessToEntityType:type completion:^(BOOL granted, NSError *error) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [self alertViewWithDataClass:((type == EKEntityTypeEvent) ? Calendars : Reminders) status:(granted) ? NSLocalizedString(@"GRANTED", @"") : NSLocalizedString(@"DENIED", @"")];
            
            /*
             Do something with the access to eventstore...
             */
        });
    }];
}

3、plist中添加key

NSRemindersUsageDescription


五、照片

1、权限状态

- (void)reportPhotosAuthorizationStatus {
    /*
     We can ask the photo library ahead of time what the authorization status is for our bundle and take the appropriate action.
     */
    NSString *statusText = nil;
    if([PHPhotoLibrary authorizationStatus] == PHAuthorizationStatusNotDetermined) {
       statusText = NSLocalizedString(@"UNDETERMINED", @"");
    }
    else if([PHPhotoLibrary authorizationStatus] == PHAuthorizationStatusRestricted) {
        statusText = NSLocalizedString(@"RESTRICTED", @"");
    }
    else if([PHPhotoLibrary authorizationStatus] == PHAuthorizationStatusDenied) {
        statusText = NSLocalizedString(@"DENIED", @"");
    }
    else if([PHPhotoLibrary authorizationStatus] == PHAuthorizationStatusAuthorized) {
        statusText = NSLocalizedString(@"GRANTED", @"");
    }
    
    NSString *message = [NSString stringWithFormat:NSLocalizedString(@"PHOTOS_ACCESS_LEVEL", @""), statusText];
    [self alertViewWithMessage:message];
}

2、获取权限

- (void)requestPhotosAccessUsingImagePicker {
    /*
    There are two ways to prompt the user for permission to access photos. This one will display the photo picker UI.  See the PHPhotoLibrary example in this file for the other way to request photo access.
     */
    
    UIImagePickerController *picker = [[UIImagePickerController alloc] init];
    picker.delegate = self;
    
    /*
     Upon presenting the picker, consent will be required from the user if the user previously denied access to the photo library, an "access denied" lock screen will be presented to the user to remind them of this choice.
     */
    [self.navigationController presentViewController:picker animated:YES completion:nil];
}

- (void)requestPhotosAccessUsingPhotoLibrary {
    /*
     There are two ways to prompt the user for permission to access photos. This one will not display the photo picker UI.  See the UIImagePickerController example in this file for the other way to request photo access.
     */
    [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [self reportPhotosAuthorizationStatus];
        });
    }];
}


3、plist中添加key


NSPhotoLibraryUsageDescription 

六、蓝牙共享

1、权限状态

- (void)checkBluetoothAccess {
    if(!self.cbManager) {
        self.cbManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
    }
    
    /*
     We can ask the bluetooth manager ahead of time what the authorization status is for our bundle and take the appropriate action.
     */
    CBCentralManagerState state = [self.cbManager state];
    if(state == CBCentralManagerStateUnknown) {
        [self alertViewWithDataClass:Bluetooth status:NSLocalizedString(@"UNKNOWN", @"")];
    }
    else if(state == CBCentralManagerStateUnauthorized) {
        [self alertViewWithDataClass:Bluetooth status:NSLocalizedString(@"DENIED", @"")];
    }
    else {
        [self alertViewWithDataClass:Bluetooth status:NSLocalizedString(@"GRANTED", @"")];
    }
}

- (void)centralManagerDidUpdateState:(CBCentralManager *)central {
    /*
     The delegate method will be called when the permission status changes the application should then attempt to handle the change appropriately by changing UI or setting up or tearing down data structures.
     */
}

2、请求权限

- (void)requestBluetoothAccess {
    if(!self.cbManager) {
        self.cbManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
    }
    
    /*
     When the application requests to start scanning for bluetooth devices that is when the user is presented with a consent dialog.
     */
    [self.cbManager scanForPeripheralsWithServices:nil options:nil];
}

- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI {
    /*
     Handle the discovered bluetooth devices...
     */
}


3、plist中添加key

NSBluetoothPeripheralUsageDescription


七、麦克风

1、权限状态

官方暂无提供接口。

2、请求权限

- (void)requestMicrophoneAccess {
    AVAudioSession *session = [[AVAudioSession alloc] init];
    [session requestRecordPermission:^(BOOL granted) {
        if(granted) {
            NSError *error;
            /*
             Setting the category will also request access from the user
             */
            [session setCategory:AVAudioSessionCategoryPlayAndRecord error:&error];
            
            /*
             Do something with the audio session
             */
        }
        else {
            /*
             Handle failure
             */
        }
        
        dispatch_async(dispatch_get_main_queue(), ^{
            [self alertViewWithDataClass:Microphone status:(granted) ? NSLocalizedString(@"GRANTED", @"") : NSLocalizedString(@"DENIED", @"")];
        });
    }];
}

3、plist中添加key

NSMicrophoneUsageDescription

八、相机

1、权限状态

- (void)checkCameraAccess {
    
    AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
    if(status ==AVAuthorizationStatusNotDetermined) {
        [self alertViewWithMessage:NSLocalizedString(@"UNDETERMINED", @"")];
    }
    else if(status == AVAuthorizationStatusRestricted) {
        
        [self alertViewWithMessage:NSLocalizedString(@"RESTRICTED", @"")];
    }
    else if(status == AVAuthorizationStatusDenied) {
        
        [self alertViewWithMessage:NSLocalizedString(@"DENIED", @"")];
    }
    else if(status == AVAuthorizationStatusAuthorized) {
        [self alertViewWithMessage:NSLocalizedString(@"GRANTED", @"")];
    }
}


2、请求权限

- (void)requestCameraAccess {
    [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
        [self checkCameraAccess];
    }];
}


3、plist中添加key
NSCameraUsageDescription

九、健康

1、权限状态

- (void)checkHealthAccess {
    if ([HKHealthStore isHealthDataAvailable]) {
        if (!self.healthStore) {
            self.healthStore = [[HKHealthStore alloc] init];
        }
        
        HKQuantityType *heartRateType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierHeartRate];
        HKAuthorizationStatus status = [self.healthStore authorizationStatusForType:heartRateType];
        
        if (status == HKAuthorizationStatusNotDetermined) {
            [self alertViewWithDataClass:Health status:NSLocalizedString(@"UNKNOWN", @"")];
        }
        else if (status == HKAuthorizationStatusSharingAuthorized) {
            [self alertViewWithDataClass:Health status:NSLocalizedString(@"GRANTED", @"")];
        }
        else if (status == HKAuthorizationStatusSharingDenied) {
            [self alertViewWithDataClass:Health status:NSLocalizedString(@"DENIED", @"")];
        }
    }
    else {
        // Health data is not available on all devices
        [self alertViewWithDataClass:Health status:NSLocalizedString(@"UNAVAILABLE", @"")];
    }
}


2、请求权限

- (void)requestHealthAccess {
    if ([HKHealthStore isHealthDataAvailable]) {
        if (!self.healthStore) {
            self.healthStore = [[HKHealthStore alloc] init];
        }
        
        HKQuantityType *heartRateType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierHeartRate];
        NSSet *typeSet = [NSSet setWithObject:heartRateType];
        
        /*
         Requests consent from the user to read and write heart rate data from the health store
         */
        [self.healthStore requestAuthorizationToShareTypes:typeSet
                                                 readTypes:typeSet
                                                completion:^(BOOL success, NSError *error) {
                                                    dispatch_async(dispatch_get_main_queue(), ^{
                                                        [self checkHealthAccess];
                                                    });
                                                }];
    }
    else {
        // Health data is not available on all devices
        [self alertViewWithDataClass:Health status:NSLocalizedString(@"UNAVAILABLE", @"")];
    }
}


十、HomeKit

1、权限状态

官方暂无提供接口。

2、请求权限

- (void)requestHomeAccess {
    self.homeManager = [[HMHomeManager alloc] init];
    
    // HMHomeManager will notify the delegate when it's ready to vend home data. It will ask for user permission first, if needed.
    self.homeManager.delegate = self;
}

- (void)homeManagerDidUpdateHomes:(HMHomeManager *)manager {
    if (manager.homes.count > 0) {
        // A home exists, so we have access
        [self alertViewWithDataClass:Home status:NSLocalizedString(@"GRANTED", @"")];
    }
    else {
        // No homes are available.  Is that because no home is set in HMHomeManager, or because the user denied access?
        __weak HMHomeManager *weakHomeManager = manager; // Prevent memory leak
        [manager addHomeWithName:@"Test Home" completionHandler:^(HMHome *home, NSError *error) {
            
            if (!error) {
                [self alertViewWithDataClass:Home status:NSLocalizedString(@"GRANTED", @"")];
            }
            else {
                if (error.code == HMErrorCodeHomeAccessNotAuthorized) {
                    // User denied permission
                    [self alertViewWithDataClass:Home status:NSLocalizedString(@"DENIED", @"")];
                }
                else {
                    // Handle other errors cleanly
                    NSString *message = [NSString stringWithFormat:NSLocalizedString(@"HOME_ERROR", @""), error.code, error.localizedDescription];
                    [self alertViewWithMessage:message];
                }
            }
            
            if (home) {
                // Clean up after ourselves, don't leave the Test Home in the HMHomeManager array
                [weakHomeManager removeHome:home completionHandler:^(NSError * _Nullable error) {
                    // ... do something with the result of removing the home ...
                }];
            }
        }];
    }
}


十一、运动与健身

1、权限状态

官方暂无提供接口。

2、请求权限

- (void)requestMotionAccessData {
    self.cmManager = [[CMMotionActivityManager alloc] init];
    self.motionActivityQueue = [[NSOperationQueue alloc] init];
    [self.cmManager startActivityUpdatesToQueue:self.motionActivityQueue withHandler:^(CMMotionActivity *activity) {
        /* 
         * Do something with the activity reported
         */
        [self alertViewWithDataClass:Motion status:NSLocalizedString(@"ALLOWED", @"")];
        [self.cmManager stopActivityUpdates];
    }];
}

3、plist中添加key

NSMotionUsageDescription


官方Demo下载链接    官方Demo补充

没有更多推荐了,返回首页