ios 13iOS开发知识小集ios

iOS 13 适配那些事

2019-06-10  本文已影响134人  前行哲

iOS 13 如期而至,虽然正式版还没出来,但是适配工作可以开展起来啦。在适配 iOS 13 过程中,遇到了如下一些问题。

1. UITextField 的私有属性 _placeholderLabel 被禁止访问了

遇到的第一个崩溃是修改UITextFieldplaceholder的颜色,历史遗留代码如下:

[_textField setValue:self.placeholderColor forKeyPath:@"_placeholderLabel.textColor"];

收到的错误信息⚠️

'Access to UITextField's _placeholderLabel ivar is prohibited. This is an application bug' 

那么这个问题如何处理呢?

其实,UITextField有个attributedPlaceholder的属性,我们可以自定义这个富文本来达到我们需要的结果。

修改如下:

NSMutableAttributedString *placeholderString = [[NSMutableAttributedString alloc] initWithString:placeholder attributes:@{NSForegroundColorAttributeName : self.placeholderColor}];
_textField.attributedPlaceholder = placeholderString;

2. 控制器的 modalPresentationStyle 默认值变了

对于这个变化,有点措手不及,直接修改了模态窗口的交互。
查阅了下 UIModalPresentationStyle枚举定义,赫然发现iOS 13新加了一个枚举值:

typedef NS_ENUM(NSInteger, UIModalPresentationStyle) {
    UIModalPresentationFullScreen = 0,
    UIModalPresentationPageSheet API_AVAILABLE(ios(3.2)) API_UNAVAILABLE(tvos),
    UIModalPresentationFormSheet API_AVAILABLE(ios(3.2)) API_UNAVAILABLE(tvos),
    UIModalPresentationCurrentContext API_AVAILABLE(ios(3.2)),
    UIModalPresentationCustom API_AVAILABLE(ios(7.0)),
    UIModalPresentationOverFullScreen API_AVAILABLE(ios(8.0)),
    UIModalPresentationOverCurrentContext API_AVAILABLE(ios(8.0)),
    UIModalPresentationPopover API_AVAILABLE(ios(8.0)) API_UNAVAILABLE(tvos),
    UIModalPresentationBlurOverFullScreen API_AVAILABLE(tvos(11.0)) API_UNAVAILABLE(ios) API_UNAVAILABLE(watchos),
    UIModalPresentationNone API_AVAILABLE(ios(7.0)) = -1,
    UIModalPresentationAutomatic API_AVAILABLE(ios(13.0)) = -2,
};

是的,就是UIModalPresentationAutomatic,苹果居然直接将modalPresentationStyle默认值改成这个,有点不解,难道是怕我们不知道新加了这个交互?这个也完全违反了开闭原则吧😒。

如何修改:
如果你完全接受苹果的这个默认效果,那就不需要去修改任何代码。
如果,你原来就比较细心,已经设置了modalPresentationStyle的值,那你也不会有这个影响。
对于想要找回原来默认交互的同学,直接设置如下即可:

self.modalPresentationStyle = UIModalPresentationOverFullScreen;

注意:UIModalPresentationOverFullScreen最低支持iOS 8,如果你还要支持iOS 8以下版本,那么你可以用UIModalPresentationFullScreen,这个两个值的交互略有些细微差别,具体的可以自己看下效果。

3. MPMoviePlayerController 在iOS 13已经不能用了

在使用到MPMoviePlayerController的地方,直接抛了异常:

'MPMoviePlayerController is no longer available. Use AVPlayerViewController in AVKit.' 

如何修改:
这个没啥好说的,既然不能再用了,那只能换掉了。替代方案就是AVKit里面的那套播放器。

4. iOS 13 DeviceToken有变化

可能大多数使用第三方推送的童鞋都不会注意到这个问题,一般现在的第三方推送都是将DeviceToken原始数据丢进去,具体的解析都是第三方内部处理,所以,这些第三方解析DeviceToken的方式正确的话,那就毫无问题。如果你们是通过这种方式来获取DeviceToken,那你需要注意了。(这个坑也是多年前埋下的,很多文章介绍的也是下面这个方法,不规范的做法迟早要还的🤣),如下:

NSString *dt = [deviceToken description];
dt = [dt stringByReplacingOccurrencesOfString: @"<" withString: @""];
dt = [dt stringByReplacingOccurrencesOfString: @">" withString: @""];
dt = [dt stringByReplacingOccurrencesOfString: @" " withString: @""];

这段代码运行在 iOS 13 上已经无法获取到准确的DeviceToken字符串了,iOS 13 通过[deviceToken description]获取到的内容已经变了。

{length = 32, bytes = 0x778a7995 29f32fb6 74ba8167 b6bddb4e ... b4d6b95f 65ac4587 }

可以看到,跟原来我们认识的那个已经完全不一样了。其实,造成这样的问题,主要还是没有使用正确的方式来操作,下面是解决办法:

NSMutableString *deviceTokenString = [NSMutableString string];
const char *bytes = deviceToken.bytes;
NSInteger count = deviceToken.length;
for (int i = 0; i < count; i++) {
    [deviceTokenString appendFormat:@"%02x", bytes[i]&0x000000FF];
}

未完,持续更新

上一篇 下一篇

猜你喜欢

热点阅读