Starting: cclog
Hipo 2.0 has been rewritten from Swift 1 to Swift 2. The subsequent Hipo functions are stable and updates are much slower… Swift itself is in great progress. 5.0 has been released. This article summarizes the updates from Swift 3.0 to Swift 5.1.
Prepare a summary from new to old for easy reading.
All the things below are from HackingWithSwift.com.
Swift, 5.1
Swift 5.1 update is late, separate from Swift 5.1 changes.
Swift, 5.0
Swift 5.0 ABI Stability is the most important ABI Stability for Swift 5.0.
There are other updates as well.
Result
type
Implementation of the SE-0235 proposal. Used for error handling in complex objects.
The Result type has two generic enumerators, Success and Failure, and the generics for Failure must follow Swift’s Error type.
Routine use
enum NetworkError: Error {
case badURL
}
import Foundation
func fetchUnreadCount1(from urlString: String, completionHandler: @escaping (Result<Int, NetworkError>) -> Void) {
guard let url = URL(string: urlString) else {
completionHandler(.failure(.badURL))
return
}
// complicated networking code here
print("Fetching \(url.absoluteString)...")
completionHandler(.success(5))
}
fetchUnreadCount1(from: "https://www.hackingwithswift.com") { result in
switch result {
case .success(let count) :print("\ [count) unread messages.")
case .failure(let error):
print(error.localizedDescription)
}
}
Copy the code
First, Result has a get() method that either returns a success value or throws an error. So you can use it this way.
fetchUnreadCount1(from: "https://www.hackingwithswift.com") { result in
if let count = try? result.get() {
print("\ [count) unread messages.")}}Copy the code
Again, Result can accept a closure to initialize, and if the closure returns successfully, it is placed on the side of success, and if an error is thrown, it is placed on the side of failure.
let result = Result { try String(contentsOfFile: someFile) }
Copy the code
Finally, you can use your own Error enumeration, but Swift official recommends that you use swift. Error as an Error parameter.
“It’s expected that most uses of Result will use Swift.Error as the Error type argument.”
Raw string
Se-0200 introduces Raw strings wrapped in #. Characters inside are not processed, especially escape characters.
The difference needs to do that
let answer = 42
let dontpanic = #"The answer to life, the universe, and everything is \#(answer)."#
Copy the code
This is especially useful for regular
let regex1 = "\\\\[A-Z]+[A-Za-z]+\\.[a-z]+"
let regex2 = #"\\[A-Z]+[A-Za-z]+\.[a-z]+"#
Copy the code
Custom string interpolation
The SE-0228 proposal improves Swift’s string interpolation to make it more efficient and free.
struct User {
var name: String
var age: Int
}
extension String.StringInterpolation {
mutating func appendInterpolation(_ value: User) {
appendInterpolation("My name is \(value.name) and I'm \(value.age)")}}let user = User(name: "Guybrush Threepwood", age: 33)
print("User details: \(user)")
// User details: My name is Guybrush Threepwood and I'm 33,
Copy the code
// TODO: More use, more research
Dynamic callable type
Se-0216 added @dynamicCallable to support dynamic method calls, similar to @dynamicMemberLookup.
You can take
struct RandomNumberGenerator {
func generate(numberOfZeroes: Int) -> Double {
let maximum = pow(10.Double(numberOfZeroes))
return Double.random(in: 0. maximum) } }Copy the code
Into a
@dynamicCallable
struct RandomNumberGenerator {
func dynamicallyCall(withKeywordArguments args: KeyValuePairs<String, Int>) -> Double {
let numberOfZeroes = Double(args.first? .value ??0)
let maximum = pow(10, numberOfZeroes)
return Double.random(in: 0. maximum) } }let random = RandomNumberGenerator(a)let result = random(numberOfZeroes: 0)
Copy the code
@dynamicCallable
parameter- No parameter label
withArguments
You can use any followExpressibleByArrayLiteral
Type, such as array, array slice, set, etc - With a parameter label
withKeywordArguments
, use any followExpressibleByDictionaryLiteral
Types, such as dictionaries, and key value pairs, and moreKeyValuePairs
You can see here,What is KeyValuePairs?
- No parameter label
- You can use it for structs, enums, classes, and protocols
- If you use
withKeywordArguments
Rather thanwithArguments
You still use it as a no-argument label, except that key is an empty string. - if
withKeywordArguments
orwithArguments
The call type also throws an error. - Cannot be used in extensions
@dynamicCallable
- You can still add properties and methods.
Process future enumeration values
Implementation of SE_0192.
Sometimes enumerated switches use default to prevent errors, but it is not actually used, but if new cases are added in the future, those processing places will be missed. Now you can add @unknkow to trigger Xcode.
func showNew(error: PasswordError) {
switch error {
case .short:
print("Your password was too short.")
case .obvious:
print("Your password was too obvious.")
@unknown default:
print("Your password wasn't suitable.")}}Copy the code
This will raise an alarm if PasswordError (switch block is no longer Exhaustive) is not cleared.
fromtry?
Flush nesting is optional
struct User {
var id: Int
init? (id:Int) {
if id < 1 {
return nil
}
self.id = id
}
func getMessages(a) throws -> String {
// complicated code here
return "No messages"}}let user = User(id: 1)
let messages = try? user? .getMessages()Copy the code
In the above example, for Swift 4.2 and before, message would be String?? In Swift 5, you can return a flattened String, okay?
Check if the integers are even
Se-0225 added isMultiple(of:) to check if the integer is even, same as if rowNumber % 2 == 0.
let rowNumber = 4
if rowNumber.isMultiple(of: 2) {
print("Even")}else {
print("Odd")}Copy the code
The dictionarycompactMapValues()
methods
Se-0218 added the compactMapValues() method to the dictionary, which is like combining the array compactMap() method (iterating over the members, determining optional values, and discarding nil members) with the dictionary’s mapValues() method (converting only the dictionary’s values).
let times = [
"Hudson": "38"."Clarke": "42"."Robinson": "35"."Hartis": "DNF"
]
let finishers1 = times.compactMapValues { Int($0)}let finishers2 = times.compactMapValues(Int.init)
let people6 = [
"Paul": 38."Sophie": 8."Charlotte": 5."William": nil
]
let knownAges = people6.compactMapValues { $0 }
print("compactMapValues, \(finishers1).\(finishers2).\(knownAges)")
// compactMapValues, ["Clarke": 42, "Robinson": 35, "Hudson": 38], ["Robinson": 35, "Clarke": 42, "Hudson": 38],["Charlotte": 5, "Sophie": 8, "Paul": 38]
Copy the code
Recall function: conditional count
Se-0220 introduces the count(where:) function to count the number of members in a list that follows a Sequence.
let scores = [100.80.85]
let passCount = scores.count{$0> =85 }
let pythons = ["Eric Idle"."Graham Chapman"."John Cleese"."Michael Palin"."Terry Gilliam"."Terry Jones"]
let terryCount = pythons.count{$0.hasPrefix("Terry")}Copy the code
This feature was withdrawn due to performance issues.
Swift, 4.2
CaseIterable
agreement
The proposed implementation of SE-0194, Swift4.2 adds the CaseIterable protocol, which automatically generates an array of all enumerations for the allCases attribute of an enumeration.
enum Pasta: CaseIterable {
case cannelloni, fusilli, linguine, tagliatelle
}
for shape in Pasta.allCases {
print("I like eating \(shape).")}Copy the code
Of course, you can do it yourself
enum Car: CaseIterable {
static var allCases: [Car] {
return [.ford, .toyota, .jaguar, .bmw, .porsche(convertible: false), .porsche(convertible: true)]}case ford, toyota, jaguar, bmw
case porsche(convertible: Bool)}Copy the code
Warnings and error instructions
Implementation of the SE-0196 proposal. Swift 4.2 provides these two prompts to make Xcode prompt at compile time
#warning
Warning, mainly to indicate the need for future processing, Xcode can compile through#error
Used in the Library to force a message that it needs to be fixed or it will not compile.
func encrypt(_ string: String, with password: String) -> String {
#warning("This is terrible method of encryption")
return password + String(string.reversed()) + password
}
struct Configuration {
var apiKey: String {
#error("Please enter your API key below then delete this line.")
return "Enter your key here"}}Copy the code
It can also be used with #if.
#if os(macOS)
#error("MyLibrary is not supported on macOS.")
#endif
Copy the code
Dynamic lookup member
Implementation of the SE-0195 proposal. Swift 4.2 provides @dynamicmemberlookup property, which is used together with subscript(dynamicMember:) to achieve dynamic attribute values.
@dynamicMemberLookup
struct Person5 {
subscript(dynamicMember member: String) - >String {
let properties = ["name": "Tylor Swift"."city" : "Nashville"]
return properties[member, default: ""]}}let person5 = Person5(a)print("person5.name: \(person5.name)")
print("person5.city: \(person5.city)")
print("person5.favoriteIceCream: \(person5.favoriteIceCream)")
// person5.name: Tylor Swift
// person5.city: Nashville
// person5.favoriteIceCream:
Copy the code
Of course, there are similar uses for polymorphism.
@dynamicMemberLookup
struct Person5 {
subscript(dynamicMember member: String) - >String {
let properties = ["name": "Tylor Swift"."city" : "Nashville"]
return properties[member, default: ""]}subscript(dynamicMember member: String) - >Int {
let properties = ["age": 26."height": 178]
return properties[member, default: 0]}}let person5 = Person5(a)print("person5.age: \(person5.age)")
let age: Int = person5.age
print("person5.age2: \(age)")
// person5.age:
// person5.age2: 26
Copy the code
Note that you need to specify the explicitly specified type for Swift to work correctly.
And if you already have an existing attribute, the dynamic attribute will not take effect
struct Singer {
public var name = "Justin Bieber"
subscript(dynamicMember member: String) - >String {
return "Taylor Swift"}}let singer = Singer(a)print(singer.name)
// Justin Bieber
Copy the code
DynamicMemberLookup can be used with protocols, structures, enumerations, classes, and even classes labeled @objc and their successors.
For example, with protocol, you can use it like this
@dynamicMemberLookup
protocol Subscripting {}extension Subscripting {
subscript(dynamicMember member: String) - >String {
return "This is coming from the subscript"}}extension String: Subscripting {}let str = "Hello, Swift"
print(str.username)
Copy the code
The example of Chris Lattner’s proposal makes sense,
@dynamicMemberLookup
enum JSON {
case intValue(Int)
case stringValue(String)
case arrayValue(Array<JSON>)
case dictionaryValue(Dictionary<String.JSON>)
var stringValue: String? {
if case .stringValue(let str) = self {
return str
}
return nil
}
subscript(index: Int) - >JSON? {
if case .arrayValue(let arr) = self {
return index < arr.count ? arr[index] : nil
}
return nil
}
subscript(key: String) - >JSON? {
if case .dictionaryValue(let dict) = self {
return dict[key]
}
return nil
}
subscript(dynamicMember member: String) - >JSON? {
if case .dictionaryValue(let dict) = self {
return dict[member]
}
return nil}}Copy the code
Normal use
let json = JSON.stringValue("Example")
json[0]? ["name"]? ["first"]? .stringValueCopy the code
If I write it the way I wrote it
json[0]? .name?.first?.stringValueCopy the code
Conditional compliance with protocol enhancements
Swift 4.1 introduces conditional compliance protocols
extension Array: Purchaseable where Element: Purchaseable {
func buy(a) {
for item in self {
item.buy()
}
}
}
Copy the code
In Swift 4.1, however, an error is reported if you want to determine whether an object is following a protocol. Swift 4.2 fixes this problem
let items: Any = [Book(), Book(), Book()]
if let books = items as? Purchaseable {
books.buy()
}
Copy the code
Also, Swift’s built-in types, optional arrays, dictionaries, ranges, automatically follow Hashable if their members follow Hashable.
Random number generation andshuffling
Implementation of the SE-0202 proposal. Swift 4.2 provides a native random number method. This means you don’t need to use arc4random_Uniform () or GameplayKit to do it.
let randomInt = Int.random(in: 1..<5)
let randomFloat = Float.random(in: 1..<10)
let randomDouble = Double.random(in: 1.100)
let randomCGFloat = CGFloat.random(in: 1.1000)
let randomBool = Bool.random()
Copy the code
Se-0202 also suggests shuffle() and Shuffled ()
var albums = ["Red"."1989"."Reputation"]
// shuffle in place
albums.shuffle()
// get a shuffled array back
let shuffled = albums.shuffled()
Copy the code
There is also the randomElement() method.
if let random = albums.randomElement() {
print("The random album is \(random).")}Copy the code
Simpler, secure hashes
The se-0206 implementation makes it easier to use the Hashable protocol for your own types.
Swift 4.1 can automatically generate hash values for types that follow the Hashable protocol. But you still have to write a lot of code if you have to implement it yourself.
Swift 4.2 introduces the Hasher structure, which provides random seeds, and generic hash functions to simplify the process
struct iPad: Hashable {
var serialNumber: String
var capacity: Int
func hash(into hasher: inout Hasher) {
hasher.combine(serialNumber)
}
}
let first = iPad(serialNumber: "12345", capacity: 256)
let second = iPad(serialNumber: "54321", capacity: 512)
var hasher = Hasher()
hasher.combine(first)
hasher.combine(second)
let hash = hasher.finalize()
Copy the code
Check whether the list meets the conditions
The implementation of SE-0207 provides the allSatisfy() method to check whether all elements in an array satisfy conditions.
let scores = [85.88.95.92]
let passed = scores.allSatisfy { $0> =85 }
Copy the code
Removes elements from the original dictionary
Se-0197 provides a new removeAll(where:) method to provide a more efficient filter-like method that manipulates raw data.
var pythons = ["John"."Michael"."Graham"."Terry"."Eric"."Terry"]
pythons.removeAll { $0.hasPrefix("Terry")}print(pythons)
Copy the code
Boolean toggling
Se-0199 provides a toggle() method for Bool, similarly
extension Bool {
mutating func toggle(a) {
self=!self}}Copy the code
Swift 4.2 you can do this
var loggedIn = false
loggedIn.toggle()
Copy the code
Swift, 4.1
Equatable
andHashable
agreement
Classes and structs can be compared, which needs to be implemented manually.
struct Person: Equatable {
var firstName: String
var lastName: String
var age: Int
var city: String
static func= =(lhs: Person, rhs: Person) -> Bool {
return lhs.firstName == rhs.firstName && lhs.lastName == rhs.lastName && lhs.age == rhs.age && lhs.city == rhs.city
}
}
let person1 = Person(firstName: "hicc", lastName: "w", age: 20, city: "shenzhen")
let person2 = Person(firstName: "hicc", lastName: "w", age: 20, city: "shenzhen")
print("person1 1 == person2 : \(person1 == person2)")
// person1 1 == person2 : true
Copy the code
Swift 4.1 provides the Equatable protocol, which automatically generates the == method.
Of course, you can still implement the == method yourself (for example, businesses have attributes like ID).
It’s also a hassle to implement an object hash, which you might need to implement manually:
var hashValue: Int {
return firstName.hashValue ^ lastName.hashValue &* 16777619
}
Copy the code
Swift 4.1 provides the Hashable protocol for automatically generating hashValues, which you can still implement yourself.
struct Person2: Equatable.Hashable {
var firstName: String
var lastName: String
var age: Int
var city: String
}
let person11 = Person2(firstName: "hicc", lastName: "w", age: 20, city: "shenzhen")
let person22 = Person2(firstName: "hicc", lastName: "w", age: 20, city: "shenzhen")
print("person11 1 == person22 : \(person11 == person22).\(person11.hashValue)")
// person11 1 == person22 : true, 5419288582170212869
Copy the code
Codable
Protocol and Key value conversion policy
Swift 4 offers a handy Codable protocol, but it uses the underscore snake_case instead of the camel’s back to convert keys, which is less liberal.
Swift 4.1 provides keyDecodingStrategy for this situation, along with the keyEncodingStrategy attribute (default. UseDefaultKeys) to address these issues.
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
do {
let macs = try decoder.decode([Mac].self, from: jsonData)
print(macs)
} catch {
print(error.localizedDescription)
}
let encoder = JSONEncoder()
encoder.keyEncodingStrategy = .convertToSnakeCase
let encoded = try encoder.encode(someObject)
Copy the code
Follow the agreement conditionally
Swift 4.1 implements the SE-0143 proposal, allowing you to follow a protocol only under certain circumstances.
extension Array: Purchaseable where Element: Purchaseable {
func buy(a) {
for item in self {
item.buy()
}
}
}
Copy the code
This will make your code more secure. The following code is rejected for compilation in Swift because it does not comply with the Coodable protocol.
import Foundation
struct Person {
var name = "Taylor"
}
var people = [Person()]
var encoder = JSONEncoder(a)try encoder.encode(people)
Copy the code
Recursive constraints in association types
Swift 4.1 implements the SE-0157 proposal, where an association type can be limited by the protocol that defines it in a recursive protocol.
protocol Employee {
associatedtype Manager: Employee
var manager: Manager? { get set}}Copy the code
// TODO: I am not sure about my feelings now, but I will add further information later.
canImport
function
Implementation of the SE-0075 proposal. Swift 4.1 introduced the canImport function, which allows you to check whether a module can be imported.
#if canImport(SpriteKit)
// this will be true for iOS, macOS, tvOS, and watchOS
#else
// this will be true for other platforms, such as Linux
#endif
Copy the code
There’s been a similar approach before
#if! os(Linux)
// Matches macOS, iOS, watchOS, tvOS, and any other future platforms
#endif
#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
// Matches only Apple platforms, but needs to be kept up to date as new platforms are added
#endif
Copy the code
targetEnvironment
function
Implementation of the SE-0190 proposal, Swift 4.1 provides targetEnvironment functions to detect whether it is an emulator or real hardware.
#if targetEnvironment(simulator)
// code for the simulator here
#else
// code for real devices here
#endif
Copy the code
FlatMap was renamed compactMap
A useful function of flatMap was the ability to filter elements in an array that were nil, which Swift 4.2 renamed to the more powerful compactMap with a clear meaning
let array = ["1"."2"."Fish"]
let numbers = array.compactMap { Int($0)}/ / [1, 2]
Copy the code
Swift, 4.0
Coodable
agreement
Swift 4 previously used NSCoding to do encoding and decoding, but it requires some template codes and is prone to error. The Coodable protocol in Swift 4 exists for this purpose.
It’s incredibly simple to use.
struct Language: Codable {
var name: String
var version: Int
}
let swift = Language(name: "Swift", version: 4)
Copy the code
Complete use
let encoder = JSONEncoder(a)if let encoded = try? encoder.encode(swift) {
if let json = String(data: encoded, encoding: .utf8) {
print("swift strng\(json)")}let decoder = JSONDecoder(a)if let decoded = try? decoder.decode(Language.self, from: encoded) {
print("Swift name: \(decoded.name)")}}Copy the code
Multiline string literals
Strings that span multiple lines can be wrapped with “””.
let quotation = """
The White Rabbit put on his spectacles. "Where shall I begin,
please your Majesty?" he asked.
"Begin at the beginning," the King said gravely, "and go on
till you come to the end; then stop."
"""
Copy the code
Improve key-value encodingkeypaths
Keypaths are references to properties without actually reading the value of the property.
struct Crew {
var name: String
var rank: String
}
struct Starship {
var name: String
var maxWarp: Double
var captain: Crew
}
let janeway = Crew(name: "Kathryn Janeway", rank: "Captain")
let voyager = Starship(name: "Voyager", maxWarp: 9.975, captain: janeway)
let nameKeyPath = \Starship.name
let maxWarpKeyPath = \Starship.maxWarp
let captainName = \Starship.captain.name
let starshipName = voyager[keyPath: nameKeyPath]
let starshipMaxWarp = voyager[keyPath: maxWarpKeyPath]
let starshipCaptain = voyager[keyPath: captainName]
print("starshipName \(starshipName).\(starshipCaptain)")
// starshipName Voyager, Kathryn Janeway
Copy the code
Improving dictionary functions
Swift 4 improves many of the dictionary’s functions.
filter
It returns a dictionarymap
It still returns an arraymapValues
, returns a dictionarygrouping
Initialization method that handles an array as a dictionarydefault
It’s easier to assign and evaluate.
let cities = ["Shanghai": 24 _256_800."Karachi": 23 _500_000."Beijing": 21 _516_000."Seoul": 9 _995_000];
let massiveCities = cities.filter{$0.value > 10 _000_000 }
let populations = cities.map{$0.value * 2 }
let roundedCities = cities.mapValues { "\ [$0 / 1 _000_000) million people" }
let groupedCities = Dictionary(grouping: cities.keys) { $0.first! }
let groupedCities2 = Dictionary(grouping: cities.keys) { $0.count }
var favoriteTVShows = ["Red Dwarf"."Blackadder"."Fawlty Towers"."Red Dwarf"]
var favoriteCounts = [String: Int] ()for show in favoriteTVShows {
favoriteCounts[show, default: 0] + =1
}
print("dic\(massiveCities),\n\(populations),\n\(roundedCities),\n\(groupedCities),\n\(groupedCities2),\n\(favoriteCounts)")
// dic["Shanghai": 24256800, "Beijing": 21516000, "Karachi": 23500000],
// [43032000, 47000000, 19990000, 48513600]
///["Beijing": "21 million people", "Karachi": "23 million people", "Seoul": "9 million people", "Shanghai": "24 million people"],
// ["S": ["Seoul", "Shanghai"], "B": ["Beijing"], "K": ["Karachi"]],
// [8: ["Shanghai"], 5: ["Seoul"], 7: ["Beijing", "Karachi"]],
// ["Blackadder": 1, "Fawlty Towers": 1, "Red Dwarf": 2]
Copy the code
The string becomes a Collection type again
Strings are of Collection type, so there are a number of handy methods.
let quote = "It is a truth universally acknowledged that new Swift versions bring new features."
let reversed = quote.reversed()
for letter in quote {
print(letter)
}
Copy the code
Unilateral interval
Swift 4 supports single-sided ranges, with the missing side being 0 or the end of the set
let characters = ["Dr Horrible"."Captain Hammer"."Penny"."Bad Horse"."Moist"]
let bigParts = characters[..<3]
let smallParts = characters[3. ]print(bigParts)
print(smallParts)
// ["Dr Horrible", "Captain Hammer", "Penny"]
// ["Bad Horse", "Moist"]
Copy the code
Swift, 3.1
Optimization of extension limits
Swift supports restrictions on extensions.
extension Collection where Iterator.Element: Comparable {
func lessThanFirst(a)- > [Iterator.Element] {
guard let first = self.first else { return[]}return self.filter{$0 < first }
}
}
let items = [5.6.10.4.110.3].lessThanFirst()
print(items)
Copy the code
extension Array where Element: Comparable {
func lessThanFirst(a)- > [Element] {
guard let first = self.first else { return[]}return self.filter{$0 < first }
}
}
let items = [5.6.10.4.110.3].lessThanFirst()
print(items)
Copy the code
The above 3.0 extension restrictions are implemented by protocol. Swift 3.1 supports restrictions using types.
extension Array where Element= =Int {
func lessThanFirst(a)- > [Int] {
guard let first = self.first else { return[]}return self.filter{$0 < first }
}
}
let items = [5.6.10.4.110.3].lessThanFirst()
print(items)
Copy the code
Nested types support generics
Swift 3.1 supports the use of generics in nested types.
struct Message<T> {
struct Attachment {
var contents: T
}
var title: T
var attachment: Attachment
}
Copy the code
The Sequences protocol has been increasedprefix(while:)
.drop(while:)
Two methods
prefix(while:)
: Iterates through all elements until an element that does not meet the criteria is encountered, and the element that does is returneddrop(while:)
: returnprefix(while:)
The opposite is fine.
let names = ["Michael Jackson"."Michael Jordan"."Michael Caine"."Taylor Swift"."Adele Adkins"."Michael Douglas"]
let prefixed = names.prefix{$0.hasPrefix("Michael")}print(prefixed)
let dropped = names.drop { $0.hasPrefix("Michael")}print(dropped)
Copy the code
Swift, 3.0
Function calls must use parameter labels
Swift features that the function can specify the argument label and parameter name respectively.
func someFunction(argumentLabel parameterName: Int){}// Use with a parameter label
someFunction(argumentLabel: 1)
// If not specified, the parameter name can be used as the parameter label of the dish
func someFunction(firstParameterName: Int, secondParameterName: Int) {
}
someFunction(firstParameterName: 1, secondParameterName: 2)
Copy the code
If you don’t want to use parameter tags, use _ instead
func someFunction(_ firstParameterName: Int, secondParameterName: Int) {
}
someFunction(1, secondParameterName: 2)
Copy the code
Remove unnecessary code
Mainly built-in objects and platform-specific streamlining to make code more readable.
/ / Swift, 2.2
let blue = UIColor.blueColor()
let min = numbers.minElement()
attributedString.appendAttributedString(anotherString)
names.insert("Jane", atIndex: 0)
UIDevice.currentDevice()
// Swift 3
let blue = UIColor.blue
let min = numbers.min()
attributedString.append(anotherString)
names.insert("Jane", at: 0)
UIDevice.current
Copy the code
As well as
// The first line is Swift 2.2
// Dilhan is Swift 3
" Hello ".stringByTrimmingCharactersInSet(.whitespaceAndNewlineCharacterSet())
" Hello ".trimmingCharacters(in: .whitespacesAndNewlines)
"Taylor".containsString("ayl")
"Taylor".contains("ayl")
"1, 2, 3, 4, 5".componentsSeparatedByString(",")
"1, 2, 3, 4, 5".components(separatedBy: ",")
myPath.stringByAppendingPathComponent("file.txt")
myPath.appendingPathComponent("file.txt")
"Hello, world".stringByReplacingOccurrencesOfString("Hello", withString: "Goodbye")
"Hello, world".replacingOccurrences(of: "Hello", with: "Goodbye")
"Hello, world".substringFromIndex(7)
"Hello, world".substring(from: 7)
"Hello, world".capitalizedString
"Hello, world".capitalized
Copy the code
And lowercaseString -> lowercased(), uppercaseString ->uppercased()
dismissViewControllerAnimated(true, completion: nil)
dismiss(animated: true, completion: nil)
dismiss(animated: true)
prepareForSegue()
override func prepare(for segue: UIStoryboardSegue, sender: AnyObject?)
Copy the code
Enumerations and properties are replaced from large humps with small humps
As the title suggests, on the one hand this is the Swift recommended usage, and on the other is the change in built-in objects
UIInterfaceOrientationMask.Portrait // old
UIInterfaceOrientationMask.portrait // new
NSTextAlignment.Left // old
NSTextAlignment.left // new
SKBlendMode.Replace // old
SKBlendMode.replace // new
Copy the code
Also, Swift optional types are implemented through enumeration
enum Optional {
case None
case Some(Wrapped)}Copy the code
If.some is used to handle the optional, this also needs to be changed
for case let .some(datum) in data {
print(datum)
}
for case let datum? in data {
print(datum)
}
Copy the code
Improve C functions more quickly
Basically, let the C function use more Swift
/ / Swift, 2.2
let ctx = UIGraphicsGetCurrentContext(a)let rectangle = CGRect(x: 0, y: 0, width: 512, height: 512)
CGContextSetFillColorWithColor(ctx, UIColor.redColor().CGColor)
CGContextSetStrokeColorWithColor(ctx, UIColor.blackColor().CGColor)
CGContextSetLineWidth(ctx, 10)
CGContextAddRect(ctx, rectangle)
CGContextDrawPath(ctx, .FillStroke)
UIGraphicsEndImageContext(a)// Swift 3
if let ctx = UIGraphicsGetCurrentContext() {
let rectangle = CGRect(x: 0, y: 0, width: 512, height: 512)
ctx.setFillColor(UIColor.red.cgColor)
ctx.setStrokeColor(UIColor.black.cgColor)
ctx.setLineWidth(10)
ctx.addRect(rectangle)
ctx.drawPath(using: .fillStroke)
UIGraphicsEndImageContext()}Copy the code
As well as
// The first line is Swift 2.2
// The second line is Swift 3
CGAffineTransformIdentity
CGAffineTransform.identity
CGAffineTransformMakeScale(2.2)
CGAffineTransform(scaleX: 2, y: 2)
CGAffineTransformMakeTranslation(128.128)
CGAffineTransform(translationX: 128, y: 128)
CGAffineTransformMakeRotation(CGFloat(M_PI))
CGAffineTransform(rotationAngle: CGFloat(M_PI))
Copy the code
Placings and verbs
This is part of Swift’s more semantic improvements, which have been working on since 5.1, currently [swift.org-API Design Guidelines] (swift.org/documentati…) The method part is:
- Name functions and methods according to their side effects
- Those without side effects are named according to the rank.
x.distance(to: y)
.i.successor()
- Those with side effects are named after the verb.
print(x)
.x.sort()
.x.append(y)
- Name with and without modification
- In the verb method, the past tense is used without modification
ed
(usually, the original data is not modified, but the new one is returned), and the modified one is used in the present tenseing
. - In the noun method, use the noun without modification and add the modification before it
from
.
- In the verb method, the past tense is used without modification
- Those without side effects are named according to the rank.