XCode10 swift4.2 適配遇到的坑

Crazy凡發表於2018-09-18

以下是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 4 Swift 4.2
UITableViewCellStyle UITableViewCell.CellStyle

UIEvent

Swift 4 Swift 4.2
UIEventSubtype UIEvent.EventSubtype

UITableView

Swift 4 Swift 4.2
UITableViewScrollPosition UITableView.ScrollPosition
UITableViewAutomaticDimension UITableView.automaticDimension
UITableViewCellEditingStyle UITableViewCell.EditingStyle
UITableViewRowAnimation UITableView.RowAnimation
UITableViewStyle UITableView.Style
UITableViewCellAccessoryType UITableViewCell.AccessoryType

UIControl

Swift 4 Swift 4.2
UIControlEvents UIControl.Event

UIWindow

Swift 4 Swift 4.2
UIWindowLevelAlert UIWindow.Level.alert
UIKeyboardFrameEndUserInfoKey UIResponder.keyboardFrameEndUserInfoKey
UIKeyboardFrameBeginUserInfoKey UIResponder.keyboardFrameBeginUserInfoKey
UIKeyboardAnimationDurationUserInfoKey UIResponder.keyboardAnimationDurationUserInfoKey
UIKeyboardAnimationCurveUserInfoKey UIResponder.keyboardAnimationCurveUserInfoKey
UIKeyboardIsLocalUserInfoKey UIResponder.keyboardIsLocalUserInfoKey
UIWindowDidBecomeVisible UIWindow.didBecomeVisibleNotification
UIWindowDidBecomeHidden UIWindow.didBecomeHiddenNotification
UIWindowDidBecomeKey UIWindow.didBecomeKeyNotification
UIWindowDidResignKey UIWindow.didResignKeyNotification
UIKeyboardWillShow UIResponder.keyboardWillShowNotification
UIKeyboardDidShow UIResponder.keyboardDidShowNotification
UIKeyboardWillHide UIResponder.keyboardWillHideNotification
UIKeyboardDidHide UIResponder.keyboardDidHideNotification

UIViewController

Swift 4 Swift 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 4 Swift 4.2
UIActivityType UIActivity.ActivityType

UIActivityIndicatorView

Swift 4 Swift 4.2
activityIndicator.activityIndicatorViewStyle activityIndicator.style

UIAlertController

Swift 4 Swift 4.2
UIAlertActionStyle UIAlertAction.Style
UIAlertControllerStyle UIAlertController.Style

UIPageViewController

Swift 4 Swift 4.2
UIPageViewControllerNavigationDirection UIPageViewController.NavigationDirection
UIPageViewControllerSpineLocation UIPageViewController.SpineLocation
UIPageViewControllerNavigationOrientation UIPageViewController.NavigationOrientation
UIPageViewControllerTransitionStyle UIPageViewController.TransitionStyle
UIPageViewControllerOptionsKey UIPageViewController.OptionsKey

UINavigationController

Swift 4 Swift 4.2
UINavigationControllerOperation UINavigationController.Operation

UIGestureRecognizer

Swift 4 Swift 4.2
UIGestureRecognizerStatePossible UIGestureRecognizer.State.possible
UIGestureRecognizerStateBegan UIGestureRecognizer.State.began
UIGestureRecognizerStateChanged UIGestureRecognizer.State.changed
UIGestureRecognizerStateEnded UIGestureRecognizer.State.ended
UIGestureRecognizerStateCancelled UIGestureRecognizer.State.cancelled
UIGestureRecognizerStateFailed UIGestureRecognizer.State.failed
UIGestureRecognizerStateRecognized UIGestureRecognizer.State.recognized

NSLayoutFormat

Swift 4 Swift 4.2
NSLayoutFormatOptions NSLayoutConstraint.FormatOptions

UIEdgeInsets

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

UIFontDescriptor

Swift 4 Swift 4.2
UIFontDescriptorSymbolicTraits UIFontDescriptor.SymbolicTraits

UIImage

Swift 4 Swift 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 4 Swift 4.2
UIApplicationDidEnterBackground UIApplication.didEnterBackgroundNotification
UIApplicationWillEnterForeground UIApplication.willEnterForegroundNotification
UIApplicationDidFinishLaunching UIApplication.didFinishLaunchingNotification
UIApplicationDidBecomeActive UIApplication.didBecomeActiveNotification
UIApplicationWillResignActive UIApplication.willResignActiveNotification
UIApplicationDidReceiveMemoryWarning UIApplication.didReceiveMemoryWarningNotification
UIApplicationWillTerminate UIApplication.willTerminateNotification
UIApplicationSignificantTimeChange UIApplication.significantTimeChangeNotification
UIApplicationWillChangeStatusBarOrientation UIApplication.willChangeStatusBarOrientationNotification
UIApplicationDidChangeStatusBarOrientation UIApplication.didChangeStatusBarOrientationNotification
UIApplicationDidChangeStatusBarFrame UIApplication.didChangeStatusBarFrameNotification
UIApplicationBackgroundRefreshStatusDidChange UIApplication.backgroundRefreshStatusDidChangeNotification
UIApplicationProtectedDataWillBecomeUnavailable UIApplication.protectedDataWillBecomeUnavailableNotification
UIApplicationProtectedDataDidBecomeAvailable UIApplication.protectedDataDidBecomeAvailableNotification
UIApplicationUserDidTakeScreenshot UIApplication.userDidTakeScreenshotNotification
UIApplicationOpenSettingsURLString UIApplication.openSettingsURLString
UIApplicationLaunchOptionsKey UIApplication.LaunchOptionsKey
UIInterfaceOrientationIsLandscape() UIApplication.shared.statusBarOrientation.isLandscape

UIView

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

Foundation

NSAttributedString

Swift 4 Swift 4.2
NSAttributedStringKey NSAttributedString.Key

QuartzCore

CAShapeLayer

Swift 4 Swift 4.2
kCALineCapRound CAShapeLayerLineCap.round
kCALineCapButt CAShapeLayerLineCap.butt
kCALineCapSquare CAShapeLayerLineCap.square
kCALineJoinMiter CAShapeLayerLineJoin.miter
kCALineJoinRound CAShapeLayerLineJoin.round
kCALineJoinBevel CAShapeLayerLineJoin.bevel
kCAFillRuleNonZero CAShapeLayerFillRule.nonZero
kCAFillRuleEvenOdd CAShapeLayerFillRule.evenOdd

參考資料

Swift-Migration-4.2

相關文章