XCode10 swift4.2 適配遇到的坑

2019年5月11日優化顯示錯誤

2019年4月26日更新部分說明

以下是2018年10月23日更新

經過大約一個月的時間的適配,項目正式使用XCode10大部分庫都升級為Swift4.2,下面是適配過程中遇到的一些坑。

1. Swift4、Swift4.2混編

如果你對項目是小的獨立項目,完全可以全部升級為Swift4.2,你可以略過第一條;如果你依賴了一些第三方的庫,且沒有升級Swift4.2,你可以繼續看這一條。目前測試的結果來看,Swift4 和 Swift4.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

升級XCode10和Swift4.2之前,項目里面有些對 NSDataAsset 的錯誤使用: 用NSDataAssetImageAsset中的圖片,這個是不正確的,但是卻可以工作,這次升級修復了這個BUG。

正確的做法使用DataAsset,然后才可以用NSDataAsset讀取數據,我由于不夠認真且經驗不足還以為是個BUG,給Apple提了個BUG。。。[捂臉]

3. 第三方庫的重命名 typealias

為了方便的適配Switf4.2對UIKit中的重命名,有些第三方使用typealias對一些類型進行了重命名,以 RxSwift 為例子,RxSwift中就有如下代碼:

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

這會導致一些重命名的類型即使不改也不會報錯,但是一旦去掉了對某個庫的依賴就會引入新的問題。

4.Delegate 的 Access Modifier

在升級Swift4.2過程中,XCode10偶爾會提示需要給某些Delegate方法添加 private修飾符,不要為了消除這個??添加private,可能會導致Delegate永遠不被調到;另外,如果是一個public或者openclass,協議方法記得也要加上public,否則會出一樣的問題,具體原因我還在測試,但是現象是這樣的,有新的見解歡迎評論區討論。

5. 機型適配問題,iPhone XS Max字體變大

有些同事遇到XCode9構建的安裝包在iPhone XS Max上會有字體變大的情況,這個貌似是普遍現象,微信也有,使用XCode10構建安裝包可以解決這個問題,但是會遇到問題6

6. iOS9.3以下系統Crash率飆升

使用XCode10構建安裝包可以解決問題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

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 如果喜歡這篇文章,歡迎點贊或者點個關注:[我的微博](http://weibo.com/devlcd) ,以后發布...
    devlcd閱讀 6,448評論 4 9
  • 片段 一: 選自《堅持,一種可以養成的習慣》 I:對自己一天既定生活、工作規律進行分析,結合自己偶發因素的影響,磨...
    自畫像55閱讀 128評論 0 0
  • 再次醒來之后,他看見他在空中飄著,前面有個小孩用繩子拉著他走,嘴里還在嘟囔著:“好累啊,人間的路怎么這么長,怎么還...
    廣電1701b劉玉靜閱讀 258評論 1 1
  • 焦慮,自責,內疚,沒安全感,這些負面情緒集聚在這一段時間,原因一是對于新工作的不適應,及對未來的更加迷茫。二是人際...
    英仔_6b07閱讀 3,428評論 0 0
  • 今天是2016年4月19日,陰天。我在大連,一個海濱城市。昨天在一個app上偶然翻到簡書,基于好奇,翻了翻內...
    欣欣592閱讀 258評論 0 0