以下是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或者open的class,协议方法记得也要加上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
可选方案:
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)
下面是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
网友评论