Chỉnh sửa app để thích hợp với Xcode 7.3 và Swift 2.2 nào ^^
Bài đăng này đã không được cập nhật trong 8 năm
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)
All rights reserved