Chỉnh sửa app để thích hợp với Xcode 7.3 và Swift 2.2 nào ^^
Như chúng ta đã biết, bản Xcode 7.3 vừa mới được update, và Swift đã được nâng lên version 2.2. Do đó khi Build lại các Project đã phát triển thì sẽ xuất hiện một số Error hay Warning trong Project. Bài viết này tác giả xin tổng hợp lại cách xử lý những vấn đề đó. Warning ở đây hầu hết là việc ...
Như chúng ta đã biết, bản Xcode 7.3 vừa mới được update, và Swift đã được nâng lên version 2.2. Do đó khi Build lại các Project đã phát triển thì sẽ xuất hiện một số Error hay Warning trong Project. Bài viết này tác giả xin tổng hợp lại cách xử lý những vấn đề đó.
Warning ở đây hầu hết là việc Apple hướng đến Swift 3 và không còn đồng ý với cú pháp đó nữa. Nếu các warning khác ở project của các bạn không xuất hiện trong bài viết này thì các bạn hãy check ở Github với địa chỉ apple/swift-evolution để tìm nguyên nhân nhé.
1.Warning
var param ở function đã bị warning và sẽ được remove trong Swift 3
swift-evolution: SE-003
Code khi chưa thay đổi :
func sayHelloTo(var name: String) { name = "Hello, (name)." print(name) }
Code khi đã thay đổi :
func sayHelloTo(name: String) { var name = name name = "Hello, (name)." print(name) }
++ cũng bị khuyến cáo và cũng sẽ bị remove trong Swift3
swift-evolution: SE-007
Code khi chưa thay đổi:
var index: Int = 0 index++
Khi đã thay đổi
var index: Int = 0 index += 1
-- cũng tương tự như vậy nhá =))
C-style cho các câu lệnh điều kiện cũng được khuyến cáo không sử dụng và sẽ bị loại bỏ sau này
swift-evolution: SE-0007
Code khi trước
// Loop tăng dần let array1: [Int] = [10, 20, 30, 40, 50] for var i = 0; i < array1.count; i++ { print("(i): (array1[i])") } // Loop giảm dần var array2: [Int] = [1, 2, 3, 4, 5, 6, 7, 8, 9] for var i = array2.count - 1; i >= 0; i -= 1 { array2.removeAtIndex(i) } print(array2) // []
Code thay đổi: (Có rất nhiều cách để thay đổi ^^ )
// Loop tăng let array1: [Int] = [10, 20, 30, 40, 50] // 0 ..< array1.count for index in 0 ..< array1.count { print("(index): (element)") } // array1.enumerate() for (index, element) in array1.enumerate() { print("(index): (element)") } // array1.enumerate() forEach array1.enumerate().forEach { (index, element) in print("(index): (element)") } // Loop giảm var array2: [Int] = [1, 2, 3, 4, 5, 6, 7, 8, 9] for i in (0 ..< array2.count).reverse() { array2.removeAtIndex(i) } print(array2) // [] // forEach var array3: [Int] = [1, 2, 3, 4, 5, 6, 7, 8, 9] array3.indices.reverse().forEach { array3.removeAtIndex($0) } print(array3) // []
Use #selector instead of explicitly constructing a Selector
Use of string literal for Objective-C selectors is deprecated; use #selector instead
swift-evolution: SE-0022
Việc gọi tên Method ở NSNotificationCenter và UIControl cũng đã thay đổi
Phần gọi tên hàm (action) hiện tại chúng ta chỉ cần ghi tên hàm để reference đến. Tuy nhiên ở phiên bản này việc chỉ định hảm cần theo cú pháp mới #selector(<Class>.<MethodName>).
Code trước:
class SomeTableViewController: UITableViewController { override func viewDidLoad() { super.viewDidLoad() refreshControl = UIRefreshControl() refreshControl.addTarget( self, action: "refresh", forControlEvents: .ValueChanged) tableView.addSubview(refreshControl) } func refresh() { }
Code sau khi sửa:
class SomeTableViewController: UITableViewController { override func viewDidLoad() { super.viewDidLoad() refreshControl = UIRefreshControl() refreshControl.addTarget( self, action: #selector(SomeTableViewController.refresh), forControlEvents: .ValueChanged) tableView.addSubview(refreshControl) } func refresh() { }
__FILE__ is deprecated and will be removed in Swift 3. please use #file
__LINE__ is deprecated and will be removed in Swift 3. please use #line
__FUNCTION__ is deprecated and will be removed in Swift 3. please use #function
swift-evolution: SE-0028 Tên định danh sử dụng trong debug được thay đổi cách gọi như sau:
__FILE__ -> #file __LINE__ -> #line __COLUMN__ -> #column __FUNCTION__ -> #function (Added during review) __DSO_HANDLE__ -> #dsohandle
Code trước:
print("(__FILE__), (__FUNCTION__), (__LINE__)")
Code sau khi sửa:
print("(__FILE__), (__FUNCTION__), (__LINE__)")
2.Error
Use of unresolved identifier 'SomeEnumType'
Swift file không reference được đến enum được định nghĩa ở file Objective-C .h những phần được định nghĩa ở bên trong @interface khi di chuyển ra bên ngoài sẽ bị lỗi
Code trước:
@interface Feedback : NSObject typedef NS_ENUM(NSInteger, SomeEnumType) { SomeEnumTypeNone = 0, SomeEnumTypeA = 1, SomeEnumTypeB = 2, SomeEnumTypeC = 3, }
Code sau khi sửa:
typedef NS_ENUM(NSInteger, SomeEnumType) { SomeEnumTypeNone = 0, SomeEnumTypeA = 1, SomeEnumTypeB = 2, SomeEnumTypeC = 3, } @interface Feedback : NSObject
'(name: String, size: CGSize) -> UIFont' is not convertible to '(name: String, size: CGFloat) -> UIFont?'
Property font của UILabel khi ta khai báo trực tiếp object UIFont vào sẽ bị lỗi. Nguyên nhân thì tác giả cũng chưa rõ lắm:
Code trước:
let label = UILabel() if let font = UIFont(name: "AvenirNext-Medium", size: 12.0) { label.font = font }
Code sau khi sửa:
let label = UILabel() let descriptor = UIFontDescriptor(name: "AvenirNext-Medium", size: 12.0) label.font = UIFont(descriptor: descriptor, size: 12.0)