平时生活和工作中的iOSiOS开发部落iOS Crazies

iOS 10 适配知识点总结

2016-09-20  本文已影响25697人  Dely

背景

刚刚过完中秋节,第二天app上线被拒,原因是因为启动app就会crash,领导大早上给我打电话让我去公司解决,好吧谁让人家是领导呢!正好iOS10系统刚刚出来,需要适配iOS10,不然上线还是会拒,所以我果断升级了xcode8.0。我总结了一些资料,接下来介绍一下iOS适配的一些知识点:

iOS 10.png

1.证书问题

39B1F3AE-530A-46B7-BE6E-379A0AA6B4DE.png
这个问题刚开始估计大家都会碰到也是第一个要解决的问题
这个问题就是一个证书的设置问题,下面看两张图
正常我们会在BuildeSettings中设置证书:
A6682834-E135-4D55-9636-DC5E0962AF05.png
但是在xcode8.0中我们看到下面的新特性:
06300540-83C7-44F4-9069-F198599F0086.png
相信大家都能看到在Genreal下面会有Siging,没错这就是新特性,为了方便用户来管理,大家可以选择Automatically manage signing。需要输入开发者账号!如果没有账号也没关系,在下面也可以选择Debug、Realease、inHouse模式下对应的证书也可以!

2.隐私数据访问问题

问题出现

This app has crashed because it attempted to access privacy-sensitive data without a usage description.The app's Info.plist must contain an NSPhotoLibraryUsageDescription key with a string value explaining to the user how the app uses this data.

崩溃原因

解决办法

    <key>NSPhotoLibraryUsageDescription</key>
    <string>App需要您的同意,才能访问相册</string>
    
    <key>NSCameraUsageDescription</key>
    <string>App需要您的同意,才能访问相机</string>
    
    <key>NSMicrophoneUsageDescription</key>
    <string>App需要您的同意,才能访问麦克风</string>
    
    <key>NSLocationUsageDescription</key>
    <string>App需要您的同意,才能访问位置</string>
    
    <key>NSLocationWhenInUseUsageDescription</key>
    <string>App需要您的同意,才能在使用期间访问位置</string>
    
    <key>NSLocationAlwaysUsageDescription</key>
    <string>App需要您的同意,才能始终访问位置</string>
    
    <key>NSCalendarsUsageDescription</key>
    <string>App需要您的同意,才能访问日历</string>
    
    <key>NSRemindersUsageDescription</key>
    <string>App需要您的同意,才能访问提醒事项</string>
    
    <key>NSMotionUsageDescription</key>
    <string>App需要您的同意,才能访问运动与健身</string>
    
    <key>NSHealthUpdateUsageDescription</key>
    <string>App需要您的同意,才能访问健康更新 </string>
    
    <key>NSHealthShareUsageDescription</key>
    <string>App需要您的同意,才能访问健康分享</string>
    
    <key>NSBluetoothPeripheralUsageDescription</key>
    <string>App需要您的同意,才能访问蓝牙</string> 
    
    <key>NSAppleMusicUsageDescription</key> 
    <string>App需要您的同意,才能访问媒体资料库</string>

跳转到app内的隐私数据设置页面

UIKIT_EXTERN NSString *const UIApplicationOpenSettingsURLString NS_AVAILABLE_IOS(8_0);
这个是iOS8.0以后的方法

//-----------------------系统权限设置路径(iOS8以后适用)---------------------
//url
#define SettingURL [NSURL URLWithString:UIApplicationOpenSettingsURLString]
//调到设置
#define GoToSetting if([[UIApplication sharedApplication] canOpenURL:SettingURL]) { \
                        [[UIApplication sharedApplication] openURL:SettingURL];}}

我们直接调用下面代码就可以了

//去设置
        if (IOS8_OR_LATER) {
            GoToSetting;
        }

看到评论说跳到蓝牙有什么办法,我补充一下:

1.首先你在info.plist的文件中添加相应权限
2.在要跳转蓝牙设置界面添加类#import <CoreBluetooth/CoreBluetooth.h> 并声明代理<CBCentralManagerDelegate>
3.设置全局的控件@property (nonatomic, strong)CBCentralManager *testCB;
4.在要跳转的地方写(最好不要写局部变量,因为你得拿到这个CB来做连接设备等一些处理。当然你要局部变量也没关系,你在代理方法也可以拿到CB做处理。看个人喜好了^_^)

    if (_testCB) {
        _testCB = nil;
        _testCB.delegate = nil;
        _testCB = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
    }else{
        _testCB = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
    }
5.若要获得蓝牙状态,实现代理方法
-(void)centralManagerDidUpdateState:(CBCentralManager *)central{
}
这样如果蓝牙关闭会提示"打开蓝牙来允许“xxx”连接到配件" ,这样点击设置就可以跳到蓝牙设置界面了
A55064BB-2BD5-4DEA-A733-862761D76F5B.png 88F76B47-A82A-4426-A5AE-8EB42CAB0DEA.png

iOS 10 干掉了所有系统设置的 URL Scheme,这意味着你再也不可能直接跳转到系统设置页面(比如 WiFi、蜂窝数据、定位等)。

iOS 10中如下跳到系统的设置方法已经不生效了(如果看到解决办法再补充,如果你有解决办法请赐教留下你宝贵的评论.....感谢):

//代码失效,谨慎使用
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"prefs:root=WIFI"]];

3.系统版本判断方法失效

#define IOS9_OR_LATER ([[[UIDevice currentDevice] systemVersion] compare:@"9.0"] != NSOrderedAscending)

#define IOS8_OR_LATER ([[[UIDevice currentDevice] systemVersion] compare:@"8.0"] != NSOrderedAscending)

#define IOS7_OR_LATER ([[[UIDevice currentDevice] systemVersion] compare:@"7.0"] != NSOrderedAscending)

#define IOS6_OR_LATER ([[[UIDevice currentDevice] systemVersion] compare:@"6.0"] != NSOrderedAscending)
#define isiOS10 ([[[[UIDevice currentDevice] systemVersion] substringToIndex:1] intValue]>=10)
#define IOS10_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 10.0)

#define IOS9_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 9.0)

#define IOS8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)

#define IOS7_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0)

#define IOS6_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 6.0)

4.UIColor问题

+ (UIColor *)colorWithDisplayP3Red:(CGFloat)displayP3Red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha NS_AVAILABLE_IOS(10_0);
- (UIColor *)initWithDisplayP3Red:(CGFloat)displayP3Red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha NS_AVAILABLE_IOS(10_0);

我用新老方法测试两个方法在RGB相同的数值在表现上的区别看下图:

06E01411-216F-4BE6-B36D-27FE3FEA790D.png F354DBB8-6192-403B-9817-024257DE1310.png

5.真彩色的显示

<key>UIWhitePointAdaptivityStyle</key>

它有五种取值,分别是:

<string>UIWhitePointAdaptivityStyleStandard</string> // 标准模式
<string>UIWhitePointAdaptivityStyleReading</string> // 阅读模式
<string>UIWhitePointAdaptivityStylePhoto</string> // 图片模式
<string>UIWhitePointAdaptivityStyleVideo</string> // 视频模式
<string>UIWhitePointAdaptivityStyleStandard</string> // 游戏模式

6.字体变化

7.插件取消

8.UIStatusBar的问题

21A56CDA-7A82-433C-B446-24C428087D1F.png

警告中提到从iOS9.0开始就弃用这两个方法了,需要用

-[UIViewController preferredStatusBarstyle]

-[UIViewController preferredStatusBarHidden]来替换使用,那我们来看看新的替换方法。

#if UIKIT_DEFINE_AS_PROPERTIES
@property(nonatomic, readonly) UIStatusBarStyle preferredStatusBarStyle NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED; // Defaults to UIStatusBarStyleDefault
@property(nonatomic, readonly) BOOL prefersStatusBarHidden NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED; // Defaults to NO
// Override to return the type of animation that should be used for status bar changes for this view controller. This currently only affects changes to prefersStatusBarHidden.
@property(nonatomic, readonly) UIStatusBarAnimation preferredStatusBarUpdateAnimation NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED; // Defaults to UIStatusBarAnimationFade
#else
- (UIStatusBarStyle)preferredStatusBarStyle NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED; // Defaults to UIStatusBarStyleDefault
- (BOOL)prefersStatusBarHidden NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED; // Defaults to NO
// Override to return the type of animation that should be used for status bar changes for this view controller. This currently only affects changes to prefersStatusBarHidden.
- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED; // Defaults to UIStatusBarAnimationFade
#endif

//这是错误的写法
self.preferredStatusBarStyle = UIStatusBarStyleDefault;和
self.prefersStatusBarHidden = YES;
//这是正确的
- (BOOL)prefersStatusBarHidden{
    return YES;
}

- (UIStatusBarStyle)preferredStatusBarStyle{
    return UIStatusBarStyleDefault;
}

9.UITextField(好像作用并不大)


UIKIT_EXTERN UITextContentType const UITextContentTypeName                      NS_AVAILABLE_IOS(10_0);
UIKIT_EXTERN UITextContentType const UITextContentTypeNamePrefix                NS_AVAILABLE_IOS(10_0);
UIKIT_EXTERN UITextContentType const UITextContentTypeGivenName                 NS_AVAILABLE_IOS(10_0);
UIKIT_EXTERN UITextContentType const UITextContentTypeMiddleName                NS_AVAILABLE_IOS(10_0);
UIKIT_EXTERN UITextContentType const UITextContentTypeFamilyName                NS_AVAILABLE_IOS(10_0);
UIKIT_EXTERN UITextContentType const UITextContentTypeNameSuffix                NS_AVAILABLE_IOS(10_0);
UIKIT_EXTERN UITextContentType const UITextContentTypeNickname                  NS_AVAILABLE_IOS(10_0);
UIKIT_EXTERN UITextContentType const UITextContentTypeJobTitle                  NS_AVAILABLE_IOS(10_0);
UIKIT_EXTERN UITextContentType const UITextContentTypeOrganizationName          NS_AVAILABLE_IOS(10_0);
UIKIT_EXTERN UITextContentType const UITextContentTypeLocation                  NS_AVAILABLE_IOS(10_0);
UIKIT_EXTERN UITextContentType const UITextContentTypeFullStreetAddress         NS_AVAILABLE_IOS(10_0);
UIKIT_EXTERN UITextContentType const UITextContentTypeStreetAddressLine1        NS_AVAILABLE_IOS(10_0);
UIKIT_EXTERN UITextContentType const UITextContentTypeStreetAddressLine2        NS_AVAILABLE_IOS(10_0);
UIKIT_EXTERN UITextContentType const UITextContentTypeAddressCity               NS_AVAILABLE_IOS(10_0);
UIKIT_EXTERN UITextContentType const UITextContentTypeAddressState              NS_AVAILABLE_IOS(10_0);
UIKIT_EXTERN UITextContentType const UITextContentTypeAddressCityAndState       NS_AVAILABLE_IOS(10_0);
UIKIT_EXTERN UITextContentType const UITextContentTypeSublocality               NS_AVAILABLE_IOS(10_0);
UIKIT_EXTERN UITextContentType const UITextContentTypeCountryName               NS_AVAILABLE_IOS(10_0);
UIKIT_EXTERN UITextContentType const UITextContentTypePostalCode                NS_AVAILABLE_IOS(10_0);
UIKIT_EXTERN UITextContentType const UITextContentTypeTelephoneNumber           NS_AVAILABLE_IOS(10_0);
UIKIT_EXTERN UITextContentType const UITextContentTypeEmailAddress              NS_AVAILABLE_IOS(10_0);
UIKIT_EXTERN UITextContentType const UITextContentTypeURL                       NS_AVAILABLE_IOS(10_0);
UIKIT_EXTERN UITextContentType const UITextContentTypeCreditCardNumber          NS_AVAILABLE_IOS(10_0);


10.UICollectionViewCell的的优化

- (void)collectionView:(UICollectionView *)collectionView prefetchItemsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths NS_AVAILABLE_IOS(10_0);

- (void)collectionView:(UICollectionView *)collectionView cancelPrefetchingForItemsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths  NS_AVAILABLE_IOS(10_0);

11.UIRefreshControl

//创建
 UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
 refreshControl.tintColor = [UIColor redColor];
 refreshControl.attributedTitle = [[NSAttributedString alloc] initWithString:@"正在刷新"];
 [refreshControl addTarget:self action:@selector(loadData) forControlEvents:UIControlEventValueChanged];
 
 //开始和停止刷新
 [refreshControl beginRefreshing];
 [refreshControl endRefreshing];

#import<UIRefershControll.h>

- (instancetype)init;

@property (nonatomic, readonly, getter=isRefreshing) BOOL refreshing;

@property (null_resettable, nonatomic, strong) UIColor *tintColor;
@property (nullable, nonatomic, strong) NSAttributedString *attributedTitle UI_APPEARANCE_SELECTOR;

// May be used to indicate to the refreshControl that an external event has initiated the refresh action
- (void)beginRefreshing NS_AVAILABLE_IOS(6_0);
// Must be explicitly called when the refreshing has completed
- (void)endRefreshing NS_AVAILABLE_IOS(6_0);

C5934374-2403-4C9E-9BBC-BB89B9A77420.png

12.Xcode8 debug输出不相关信息

升级到Xcode8时,我们在debug的时候控制台输出了很长很长的信息,看着比较烦,怎么屏蔽呢?

需要edit Scheme添加一个键值对就ok了。

打开Scheme方式1.png 打开Scheme方式1.png 添加键值对.png

添加 key:OS_ACTIVITY_MODE value:disable

13.UserNotifications(用户通知)

iOS 9 以前的通知

在调用方法时,有些方法让人很难区分,容易写错方法,这让开发者有时候很苦恼。
应用在运行时和非运行时捕获通知的路径还不一致。
应用在前台时,是无法直接显示远程通知,还需要进一步处理。
已经发出的通知是不能更新的,内容发出时是不能改变的,并且只有简单文本展示方式,扩展性根本不是很好。

iOS 10 开始的通知

所有相关通知被统一到了UserNotifications.framework框架中。
增加了撤销、更新、中途还可以修改通知的内容。
通知不在是简单的文本了,可以加入视频、图片,自定义通知的展示等等。
iOS 10相对之前的通知来说更加好用易于管理,并且进行了大规模优化,对于开发者来说是一件好事。
iOS 10开始对于权限问题进行了优化,申请权限就比较简单了(本地与远程通知集成在一个方法中)。

iOS 10 通知学习相关资料:

  1. UserNotifications: 苹果官方文档
  1. 活久见的重构 - iOS 10 UserNotifications 框架解析
  2. WWDC2016 Session笔记 - iOS 10 推送Notification新特性

后面对UserNotifications单独发表文章学习相关的知识

参考资料:

  1. http://blog.csdn.net/jiang314/article/details/52502450
  2. http://www.jianshu.com/p/90d5323cf510
  3. 个人博客 http://dely.vip
上一篇下一篇

猜你喜欢

热点阅读