XCode10 swift4.2 适配遇到的坑

以下是2018年10月23日更新

经过大约一个月的时间的适配,项目正式使用XCode10(以下简称为10 or XC10)大部分库都升级为Swift4.2(以下简称为 4.2 or S4.2),下面是适配过程中遇到的一些坑。

1. Swift4、Swift4.2混编

如果你对项目是小的独立项目,完全可以全部升级为4.2,你可以略过第一条;如果你依赖了一些第三方的库,且没有升级4.2,你可以继续看这一条。目前测试的结果来看,Swift4 和 S4.2的混编没有什么大的问题,如果你是通过cocoapod引入的可以在Podfile中加入如下代码:

swift_41_pod_targets = ['your_target_name']
post_install do |installer|
  installer.pods_project.targets.each do |target|
    if swift_41_pod_targets.include?(target.name)
      target.build_configurations.each do |config|
        config.build_settings['SWIFT_VERSION'] = '4.1'
      end
    end
  end
end
复制代码

2. NSDataAsset

升级XC10和S.2之前,项目里面有些对 'NSDataAsset' 的错误使用: 用‘NSDataAsset’读ImageAsset中的图片,这个是不正确的,但是却可以工作,这次升级修复了这个BUG。

正确的做法使用'DataAsset',然后才可以用‘NSDataAsset’读取数据,我由于不够认真且经验不足还以为是个BUG,给Apple提了个BUG。。。[捂脸]

3. 第三方库的重命名 typealias

为了方便的适配S4.2对UIKit中的重命名,有些第三方使用typealias对一些类型进行了重命名,以 RxSwift 为例子,RxSwift中就有如下代码:

#if swift(>=4.2)
    public typealias UIControlEvents = UIControl.Event  private
#endif
复制代码

这会导致一些重命名的类型即使不改也不会报错,但是一旦去掉了对某个库的依赖就会引入新的问题。

4.Delegate 的 Access Modifier

在升级S4.2过程中,XC偶尔会提示需要给某些Delegate方法添加 private修饰符,不要为了消除这个⚠️添加private,可能会导致Delegate永远不被调到;另外,如果是一个public或者openclass,协议方法记得也要加上public,否则会出一样的问题,具体原因我还在测试,但是现象是这样的,有新的见解欢迎评论区讨论。

5. 机型适配问题,iPhone XS Max字体变大

有些同事遇到XC9构建的安装包在iPhone XS Max上会有字体变大的情况,这个貌似是普遍现象,微信也有,使用XC10构建安装包可以解决这个问题,但是会遇到问题6

###6. iOS9.3以下系统Crash率飙升 使用XC10构建安装包可以解决问题5,但是iOS9.3以下的系统Crash到让你怀疑人生

以下是2018年9月18日内容

AVAudioSession.sharedInstance().setCategory()

disappeared

Swift 4.2 中 iOS10以下不能用 AVAudioSession.sharedInstance() setCategory

可选方案:
  • 使用OC实现该部分,然后使用Swift调用
  • 放弃 iOS9用户体验

参考地址

do {
    if #available(iOS 11.0, *) {
        try audioSession.setCategory(.playback, mode: .default, policy: .longForm, options: [])
    } else if #available(iOS 10.0, *) {
        try audioSession.setCategory(.playback, mode: .default, options: [])
    } else {
        // Compiler error: 'setCategory' is unavailable in Swift
        try audioSession.setCategory(AVAudioSession.Category.playback)
    }
} catch let error {
    print("Unable to configure audio sesson category: \(error)")
}
复制代码

NSUnderlineStyle(.patternSolid、.none)

disappeared

可选方案:
  • .none

    mutableAttributedString.addAttribute(NSAttributedString.Key.underlineStyle, value: NSUnderlineStyle.none.rawValue, range: range) ^~~~~ 'none' is unavailable: use [] to construct an empty option set

Wrong: mutableAttributedString.addAttribute(NSAttributedString.Key.underlineStyle, value: [], range: range) Right: mutableAttributedString.addAttribute(NSAttributedString.Key.underlineStyle, value: 0, range: range)

  • 使用 CTUnderlineStyleModifiers

    // 没有测试 NSUnderlineStyle.init(rawValue: Int(CTUnderlineStyleModifiers.patternSolid.rawValue))

  • 使用其他默认值

下面是Rename操作

UIKit

#Swift4/UIKit

UITableViewCell

Swift 4Swift 4.2
UITableViewCellStyleUITableViewCell.CellStyle

UIEvent

Swift 4Swift 4.2
UIEventSubtypeUIEvent.EventSubtype

UITableView

Swift 4Swift 4.2
UITableViewScrollPositionUITableView.ScrollPosition
UITableViewAutomaticDimensionUITableView.automaticDimension
UITableViewCellEditingStyleUITableViewCell.EditingStyle
UITableViewRowAnimationUITableView.RowAnimation
UITableViewStyleUITableView.Style
UITableViewCellAccessoryTypeUITableViewCell.AccessoryType

UIControl

Swift 4Swift 4.2
UIControlEventsUIControl.Event

UIWindow

Swift 4Swift 4.2
UIWindowLevelAlertUIWindow.Level.alert
UIKeyboardFrameEndUserInfoKeyUIResponder.keyboardFrameEndUserInfoKey
UIKeyboardFrameBeginUserInfoKeyUIResponder.keyboardFrameBeginUserInfoKey
UIKeyboardAnimationDurationUserInfoKeyUIResponder.keyboardAnimationDurationUserInfoKey
UIKeyboardAnimationCurveUserInfoKeyUIResponder.keyboardAnimationCurveUserInfoKey
UIKeyboardIsLocalUserInfoKeyUIResponder.keyboardIsLocalUserInfoKey
UIWindowDidBecomeVisibleUIWindow.didBecomeVisibleNotification
UIWindowDidBecomeHiddenUIWindow.didBecomeHiddenNotification
UIWindowDidBecomeKeyUIWindow.didBecomeKeyNotification
UIWindowDidResignKeyUIWindow.didResignKeyNotification
UIKeyboardWillShowUIResponder.keyboardWillShowNotification
UIKeyboardDidShowUIResponder.keyboardDidShowNotification
UIKeyboardWillHideUIResponder.keyboardWillHideNotification
UIKeyboardDidHideUIResponder.keyboardDidHideNotification

UIViewController

Swift 4Swift 4.2
open func addChildViewController(_ childController: UIViewController)open func addChild(_ childController: UIViewController)
open func willMove(toParentViewController parent: UIViewController?)open func willMove(toParent parent: UIViewController?)
open func didMove(toParentViewController parent: UIViewController?)open func didMove(toParent parent: UIViewController?)
open func removeFromParentViewController()open func removeFromParent()

UIActivity

Swift 4Swift 4.2
UIActivityTypeUIActivity.ActivityType

UIActivityIndicatorView

Swift 4Swift 4.2
activityIndicator.activityIndicatorViewStyleactivityIndicator.style

UIAlertController

Swift 4Swift 4.2
UIAlertActionStyleUIAlertAction.Style
UIAlertControllerStyleUIAlertController.Style

UIPageViewController

Swift 4Swift 4.2
UIPageViewControllerNavigationDirectionUIPageViewController.NavigationDirection
UIPageViewControllerSpineLocationUIPageViewController.SpineLocation
UIPageViewControllerNavigationOrientationUIPageViewController.NavigationOrientation
UIPageViewControllerTransitionStyleUIPageViewController.TransitionStyle
UIPageViewControllerOptionsKeyUIPageViewController.OptionsKey

UINavigationController

Swift 4Swift 4.2
UINavigationControllerOperationUINavigationController.Operation

UIGestureRecognizer

Swift 4Swift 4.2
UIGestureRecognizerStatePossibleUIGestureRecognizer.State.possible
UIGestureRecognizerStateBeganUIGestureRecognizer.State.began
UIGestureRecognizerStateChangedUIGestureRecognizer.State.changed
UIGestureRecognizerStateEndedUIGestureRecognizer.State.ended
UIGestureRecognizerStateCancelledUIGestureRecognizer.State.cancelled
UIGestureRecognizerStateFailedUIGestureRecognizer.State.failed
UIGestureRecognizerStateRecognizedUIGestureRecognizer.State.recognized

NSLayoutFormat

Swift 4Swift 4.2
NSLayoutFormatOptionsNSLayoutConstraint.FormatOptions

UIEdgeInsets

Swift 4Swift 4.2
public func UIEdgeInsetsMake(_ top: CGFloat, _ left: CGFloat, _ bottom: CGFloat, _ right: CGFloat) -> UIEdgeInsetsUIEdgeInsets(top: CGFloat, left: CGFloat, bottom: CGFloat, right: CGFloat)
public func UIEdgeInsetsInsetRect(_ rect: CGRect, _ insets: UIEdgeInsets) -> CGRectpublic func inset(by insets: UIEdgeInsets) -> CGRect

UIFontDescriptor

Swift 4Swift 4.2
UIFontDescriptorSymbolicTraitsUIFontDescriptor.SymbolicTraits

UIImage

Swift 4Swift 4.2
UIKIT_EXTERN NSData * __nullable UIImagePNGRepresentation(UIImage * __nonnull image);public func pngData() -> Data?
NSData * __nullable UIImageJPEGRepresentation(UIImage * __nonnull image, CGFloat compressionQuality);public func jpegData(compressionQuality: CGFloat) -> Data?

UIApplication

Swift 4Swift 4.2
UIApplicationDidEnterBackgroundUIApplication.didEnterBackgroundNotification
UIApplicationWillEnterForegroundUIApplication.willEnterForegroundNotification
UIApplicationDidFinishLaunchingUIApplication.didFinishLaunchingNotification
UIApplicationDidBecomeActiveUIApplication.didBecomeActiveNotification
UIApplicationWillResignActiveUIApplication.willResignActiveNotification
UIApplicationDidReceiveMemoryWarningUIApplication.didReceiveMemoryWarningNotification
UIApplicationWillTerminateUIApplication.willTerminateNotification
UIApplicationSignificantTimeChangeUIApplication.significantTimeChangeNotification
UIApplicationWillChangeStatusBarOrientationUIApplication.willChangeStatusBarOrientationNotification
UIApplicationDidChangeStatusBarOrientationUIApplication.didChangeStatusBarOrientationNotification
UIApplicationDidChangeStatusBarFrameUIApplication.didChangeStatusBarFrameNotification
UIApplicationBackgroundRefreshStatusDidChangeUIApplication.backgroundRefreshStatusDidChangeNotification
UIApplicationProtectedDataWillBecomeUnavailableUIApplication.protectedDataWillBecomeUnavailableNotification
UIApplicationProtectedDataDidBecomeAvailableUIApplication.protectedDataDidBecomeAvailableNotification
UIApplicationUserDidTakeScreenshotUIApplication.userDidTakeScreenshotNotification
UIApplicationOpenSettingsURLStringUIApplication.openSettingsURLString
UIApplicationLaunchOptionsKeyUIApplication.LaunchOptionsKey
UIInterfaceOrientationIsLandscape()UIApplication.shared.statusBarOrientation.isLandscape

UIView

Swift 4Swift 4.2
func bringSubview(toFront view: UIView)func bringSubviewToFront(_ view: UIView)
UIViewAnimationOptionsUIView.AnimationOptions()

Foundation

NSAttributedString

Swift 4Swift 4.2
NSAttributedStringKeyNSAttributedString.Key

QuartzCore

CAShapeLayer

Swift 4Swift 4.2
kCALineCapRoundCAShapeLayerLineCap.round
kCALineCapButtCAShapeLayerLineCap.butt
kCALineCapSquareCAShapeLayerLineCap.square
kCALineJoinMiterCAShapeLayerLineJoin.miter
kCALineJoinRoundCAShapeLayerLineJoin.round
kCALineJoinBevelCAShapeLayerLineJoin.bevel
kCAFillRuleNonZeroCAShapeLayerFillRule.nonZero
kCAFillRuleEvenOddCAShapeLayerFillRule.evenOdd

参考资料

Swift-Migration-4.2

转载于:https://juejin.im/post/5ba0dfb9e51d450e4a1babcb

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值