iOS 13 适配那些事

作者: 前行哲 | 来源:发表于2019-06-10 09:34 被阅读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];
    }
    

    未完,持续更新

    相关文章

      网友评论

        本文标题:iOS 13 适配那些事

        本文链接:https://www.haomeiwen.com/subject/varaxctx.html