Nearly two years after the SDK was launched, Apple realized the limitations of Objective-C and started working on a new language for iOS and OS X developers around 2010, namely, Swift.
Objective-C was already outdated, being 30 years old in the industry. A lot of developers suffered through learning the arcane syntax and other limitations of the language.
Finally in June 2014, Swift was first introduced by Apple as a general purpose and modern programming language. Since then, versions 1, 2, 3 and 4 have been released in addition to other changes like being open sourced. (Note: See a Version History below.)
Swift is a fantastic way to write software, whether it’s for phones, desktops, or, servers. It’s a safe, fast, and interactive programming language that draws inspiration from the best in modern language thinking and combines it with the wisdom of Apple’s engineering culture and diverse valuable contributions from its open-source community. The compiler is optimised for performance and the language is optimised for development, excelling in both department without compromising on either.
Swift also does away with large classes of common programming errors by adopting modern programming patterns, such as:
- Variables are always initialized before use.
- Array indices are checked for out-of-bounds errors.
- Integers are checked for overflow.
- Optionals ensure that nil values are handled explicitly.
- Memory is managed automatically.
- Error handling allows controlled recovery from unexpected failures.
Swift code is compiled and optimized to get the most out of modern hardware. The syntax and standard library have been designed with the notion that the obvious way to write your code should also perform the best. Its combination of safety and speed make Swift an excellent choice for everything – from “Hello, world!” to an entire operating system.
Swift combines powerful type inference and pattern matching with a modern, lightweight syntax, allowing complex ideas to be expressed in a clear and concise manner. As a result, code is easier to write, read and maintain.
Moreover, Swift is friendly to new programmers. It’s an expressive and industrial-quality scripting programming language. Writing Swift code lets you experiment with code and see the results immediately, without the overhead of building and running an app.
Implications for Developers
As mentioned earlier, Swift is an open source language. It allows developers to prototype, write and maintain apps for Apple platforms in a faster and more accurate manner. Thus, it supports propagation of businesses and enterprises over Apple’s platforms.
Swift being open sourced means that the language will be expanded over to other platforms as well. In fact, it has already been ported to Linux. This, eventually, expands the usability of Swift over web apps based on low-cost, low-maintenance Linux servers as well. In addition, there are frameworks built for Swift so that Linux-based server apps can be built inside of Xcode, allowing businesses to utilize existing Swift developers to build the APIs and services that iOS and OS X apps often consume.
Versions of Swift
Timeline –
- Mid 2010: Development begins
- July 17, 2010: First Swift commit to the Swift GitHub repository.
- June 2, 2014: Apple announces Swift at Worldwide Developer’s Conference (WWDC) 2014, giving developers a pre-release version of Swift and Xcode 6.
- June 8, 2015: Apple announces Swift 2.0 at WWDC 2015, giving developers a pre-release version of Swift 2 and Xcode 7.
- September 15, 2015: Apple releases Swift 2.0 with the Xcode 7 Gold Master build.
- December 3, 2015: Apple announces the Swift 3.0 roadmap on GitHub.
- September 13, 2016: Apple releases Swift 3.0 with the release of Xcode 8.
- June 5, 2017: Apple announces Swift 4.0 at WWDC ’17.
- September 19, 2017: Apple releases Swift 4.0 with XCode 9.
Highlights of Swift 2.0 –
- Swift is open source with a new Linux port available.
- A new error handling model is introduced using try, throw, and catch keywords.
- It targets older versions of iOS and OS X. It’s also safer, with the #available block that lets you wrap lines of code that will be executed on systems where the framework is available.
- SDKs are now Swift-ier, since adding of generics and nullability to existing Objective-C frameworks to make them interface better with Swift code.
Highlights of Swift 3.0 –
- Refinements to the core language and standard library to rid the language of NS prefixes and other Objective-C holdovers.
- Major additions to the Linux port of Swift.
- The addition of the Swift Package Manager to make it easier to manage dependencies.
Highlights of Swift 4.0 –
- New Codeable protocol that allows for easy serialization of data wrapped in structs.
- String literals can now break into multiple lines using the new “”” declaration (three sets of quote marks) to open and close the multiline string.
- Strings received a major overhaul, making them collections of characters.
Using Swift
To use Swift, you need to download and install Xcode 6. Once installed, open it and select File from the Menu > New > Select Source on the left under either iOS or OS X > Playground. Give your playground a name and get started.
Alternatively, you can use the Read Evaluate Print Loop (REPL) from the terminal, as instructed below:
- Open up terminal
- Select Xcode 6 as default if you have more than one versions of Xcode installed –
[java]sudo xcode-select -s /Applications/Xcode6-Beta.app/Contents/Developer/[/java] - Start the REPL by typing
– xcrun swift
While the minimum basics of using Swift are mentioned above, Swift 4 is packaged along with Xcode 9 and has a Swift Migrator tool that helps you migrate your project to Swift 4.
Also, Xcode 9 supports Swift 4 and Swift 3.2 equally and compile them together, just like the Swift 4 compiler can. That means you decide when and if you’d like to migrate on a per-target basis when it makes sense for your project. While migrating to Swift 4 is definitely encouraged, it’s not an all-or-nothing process, as Swift 3.2 and Swift 4 targets can coexist and link together.
Fundamentals of Swift
1.Value Types
Like C, Swift uses variable to store and refer to values by an identifying name. It also makes extensive use of variables, also known as constants, that is, their values can’t be changed. Constants are used throughout Swift to make code safer and clearer in intent when you work with values that don’t need to change. A few familiar value types include Int
for integers, Double
and Float
for floating-point values, Bool
for Boolean values and String
for textual data. In addition to familiar types, Swift introduces advanced types, such as tuples and optionals. Tuples enable you to create and pass around groupings of values. You can use a tuple to return multiple values from a function as a single compound value. Optional types handle the absence of a value. Optionals say either “there is a value, and it equals x” or “there isn’t a value at all”. Constants and variables associate a name with a value of a particular type. The value of a constant can’t be changed once it has been set, whereas a variable can be set to a different value in the future. Both constants and variables must be declared before they’re used. You declare constants with the let
keyword and variables with the var
keyword. For instance, to track the login attempts made by a user, you can use –
let maximumNumberOfLoginAttempts = 10 var currentLoginAttempt = 0
2.Strings and Characters
A string is a series of characters, such as “hello, world”
or “albatross”
. Swift strings are represented by the String type. The contents of a String
can be accessed in various ways, including as a collection of Character
values.Swift’s String
and Character types provide a fast, Unicode-compliant way to work with text in your code. The syntax for string creation and manipulation is lightweight and readable, with a string literal syntax that is similar to C. String concatenation is as simple as combining two strings with the + operator, and string mutability is managed by choosing between a constant or a variable, just like any other value in Swift. You can also use strings to insert constants, variables, literals, and expressions into longer strings, in a process known as string interpolation. This makes it easy to create custom string values for display, storage, and printing.Despite this simplicity of syntax, Swift’s String type is a fast, modern string implementation. Every string is composed of encoding-independent Unicode characters, and provides support for accessing those characters in various Unicode representatio
3.Collection Types
Swift provides three primary collection types, known as arrays, sets, and dictionaries, for storing collections of values. Arrays are ordered collections of values. Sets are unordered collections of unique values. Dictionaries are unordered collections of key-value associations.Collection types in Swift are well-defined about the types of value and keys they can store, thus eliminating the chances of error in inserting a value of wrong type in a collection by mistake. In other words, you can be sure about the value types you will retrieve from a particular collection.The mutability of collection depends on the type of value type it has been assigned to – a collection type assigned to a variable will be mutable, whereas a collection type assigned to a constant will be immutable.
3.1 Array
An empty array can be created using initializer syntax –
var someInts = [Int]() print(“someInts is of type [Int] with \(someInts.count) items.”) // Prints “someInts is of type [Int] with 0 items.”
Similarly, you can also create an array of a certain size with all of its values set to the same default as shown below –
var threeDoubles = Array (repeating: 0.0, count: 3) // threeDoubles is of type [Double], and equals [0.0, 0.0. 0.0]
To access or modify an array, you can use its methods or properties, or use subscript syntax.
First of all, find out the number of items in an array through its count property –
Print(“The shopping list contains \(shoppingList.count) items.”) // Prints “The shopping list contains 2 items.”
You can add a new item to the end of an array by append(_:)
method. Alternatively, you can append an array of one or more compatible items with the addition assignment operator (+=)
. Moreover, you can retrieve a value from the array by using subscript syntax, passing the index of the value you want to retrieve within square brackets immediately after the name of the array. You can also use subscript syntax to change an existing value at a given index, or to change a range of values at once, even if the replacement set of values has a different length than the range you are replacing. To insert an item into the array at a specified index, use the array’s insert(_:at:)
method.
Similarly, you remove an item from the array with the remove(at:)
method. However, to remove the final item from an array, use the removeLast()
method rather than the remove(at:)
method to avoid the need to query the array’s count property.
3.2 Sets
A set stores distinct values of the same type in a collection with no defined ordering. You can use a set instead of an array when the order of items is not important, or when you need to ensure that no item is being repeated.A type must be hashable in order to be stored in a set—that is, the type must provide a way to compute a hash value for itself. All of Swift’s basic types (such as String, Int, Double, and Bool) are hashable by default, and can be used as set value types or dictionary key types.
The type of a Swift set is written as Set
, where Element
is the type that the set is allowed to store. Unlike arrays, sets do not have an equivalent shorthand form. You can create an empty set of a certain type using initializer syntax –
var letters = Set<Character>() print(“letters is of type Set<Character> with \(letters.count) itmes.”) // Prints “letters is of type Set<Characher> with 0 items.”
You access and modify a set through its methods and properties. You can add a new item into a set by calling insert(_:)
method. You can remove an item from a set by calling the remove(_:)
method. Alternatively, all items in a set can be removed with its removeAll()
method. To check whether a set contains a particular item, use the contains(_:)
method.
3.3 Dictionaries
A dictionary stores associations between keys of the same type and values of the same type in a collection with no defined ordering. Each value is associated with a unique key, which acts as an identifier for that value within the dictionary. You use a dictionary when you need to look up values based on their identifier, much like using a real-world dictionary is to look up the definition for a particular word.The type of a Swift dictionary is written in full as Dictionary<Key, Value>
, where Key
is the type of value that can be used as a dictionary key, and Value
is the type of value that the dictionary stores for those keys. You can also write the type of a dictionary in shorthand form as [Key: Value]
.
Similar to a Set, the value types in a Dictionary need to be hashable, and need not follow a particular order.
Similar to an Array, you can create an empty Dictionary of a certain type by using initializer syntax –
var namesOfIntegers = [Int: String]() // namesOfIntegers is an empty [Int: String] dictionary
You can also initialize a dictionary with a dictionary literal, which is a shorthand way to write one or more key-value pairs as a Dictionary collection. A key-value pair is a combination of a key and a value. In a dictionary literal, the key and value in each key-value pair are separated by a colon. The key-value pairs are written as a list, separated by commas, surrounded by a pair of square brackets – [key 1: value 1, key 2: value 2, key 3: value 3]
You access and modify a dictionary through its methods and properties, or by using subscript syntax.
4.Control Flow
Swift provides a variety of control flow statements, such as while
loops to perform a task multiple times; if
, guard
, and switch
statements to execute different branches of code based on certain conditions; and statements like break
and continue
to transfer the flow of execution to another point in your code. Swift also provides a for-in
loop that makes it easy to iterate over arrays, dictionaries, ranges, strings, and other sequences.Swift’s switch
statement can match many different patterns, including interval matches, tuples, and casts to a specific type. Matched values in a switch
case can be bound to temporary constants or variables for use within the case’s body, and complex matching conditions can be expressed with a where
clause for each case.
4.1 For-in Loops
You use the for-in
loop to iterate over a sequence, such as items in an array, ranges of numbers, or characters in a string. For example, the for-in loop is used here to iterate over the items in an array –
let names = [“Anna”, “Alex”, “Brian”, “Jack”] for name in names { print(“Hello, \(name)!’) { // Hello, Anna! // Hello, Alex! // Hello, Brian! // Hello, Jack!
You can also iterate over a dictionary to access its key-value pairs. The contents of a Dictionary
are inherently unordered, and iterating over them does not guarantee the order in which they will be retrieved. In other words, the order you insert items into a Dictionary
doesn’t define the order they are iterated.
- 4.2. While Loops
Awhile
loop performs a set of statements until a condition becomes false. These kinds of loops are best used when the number of iterations is not known before the first iteration begins. Swift provides two kinds ofwhile
loops:while
evaluates its condition at the start of each pass through the loop.repeat-while
evaluates its condition at the end of each pass through the loop.- 4.2.1 While Loop
A while loop starts by evaluating a single condition. If the condition is true, a set of statements is repeated until the condition becomes false. Here’s the general form of a while loop:while condition { statements }
- 4.2.2 Repeat-While Loop
The other variation of thewhile
loop, known as therepeat-while
loop, performs a single pass through the loop block first, before considering the loop’s condition. It then continues to repeat the loop until the condition is false. Here’s the general form of arepeat-while
loop:repeat { statements } while condition
- 4.3 Conditional StatementMore often than not, you may require to make parts of your code conditional, so as to run an extra piece of code when an error occurs, or to display a message when a value becomes too high or too low. Swift provides two ways to add conditional branches to your code: the if statement and the switch statement.
Ideally, the
if
statement is used to evaluate simple conditions with only a few possible outcomes. In contrast, theswitch
statement is better suited to more complex conditions with multiple possible permutations and is more useful in situations where pattern matching can help select an appropriate code branch to execute.- 4.3.1 If Statement
In its simplest form, the if statement has a singleif
condition. It executes a set of statements only if that condition is true. For example –var temperaturInFahrenheit = 30 if temperatureInFahrenheit <= 32 { Print(“It’s very temperatureInFahrenheit <= 32”) } // Prints “It’s very cold. Consider wearing a scarf.”
The
if
statement can provide an alternative set of statements, known as anelse
clause, for situations when the if condition is false. These statements are indicated by the else keyword.temperatureInFahrenheit = 40 if temperatureInFahrenheit <= 32 { print(“It’s very cold. Consider wearing a scarf.”) } else { print(“It’s not that cold. Wear a t-shirt.”) } // Prints “It’s not that cold. Wear a t-shirt.”
In such cases, one of these two branches is always executed. You can also chain multiple if
temperatureInFahrenheit = 90 if temperatureInFahrenheit <= 32 { print(“It’s very cold. Consider wearing a scarf.”) } else if temperatureInFahrenheit >= 86 { print(“It’s really warm. Don’t forget to wear sunscreen.”) } else { print(“It’s not that cold. Wear a t-shirt.”) } // Prints “It’s really warm. Don’t forget to wear sunscreen.”
- 4.3.2 Switch StatementA
switch
statement considers a value and compares it against several possible matching patterns. It then executes an appropriate block of code, based on the first pattern that matches successfully. Aswitch
statement provides an alternative to theif
statement for responding to multiple potential states. In its simplest form, aswitch
statement compares a value against one or more values of the same type –switch some value to consider { case value 1: respond to value 1 case value 2, value 3: respond to value 2 or 3 default: otherwise, do something else }
Every
switch
statement consists of multiple possible cases, each of which begins with the case keyword. In addition to comparing against specific values, Swift provides several ways for each case to specify more complex matching patterns.Like the body of an
if
statement, each case is a separate branch of code execution. Theswitch
statement determines which branch should be selected. This procedure is known as switching on the value that is being considered.Moreover, every
switch
statement must be exhaustive – that is –every possible value of the type being considered must be matched by one of the switch cases. If it’s not appropriate to provide a case for every possible value, you can define a default case to cover any values that are not addressed explicitly. This default case is indicated by thedefault
keyword, and must always appear last. For instance, we can use aswitch
statement to consider a single lowercase character called someCharacter –let someCharacter: Character = “z” switch someCharacter { case “a”: print(“The first letter of the alphabet”) case “z”: print(“The last letter of the alphabet”) default: print(“Some other character”) } // Prints “The last letter of the alphabet”
The
switch
statement’s first case matches the first letter of the English alphabet, a, and its second case matches the last letter, z. Because the switch must have a case for every possible character, not just every alphabetic character, thisswitch
statement uses a default case to match all characters other than a and z. This provision ensures that theswitch
statement is exhaustive.
- 4.3.1 If Statement
5.Generics
Generic code enables programmers to write flexible, reusable functions and types that can work with any type, subject to requirements that you define. Using a generic code in Swift, you can write code that avoids duplication and expresses its intent in a clear, abstracted manner.Generics are one of the most powerful features of Swift, and much of the Swift standard library is built with generic code. For example, Swift’s Array
and Dictionary
types are both generic collections. You can create an array that holds Int
values, or an array that holds String
values, or indeed an array for any other type that can be created in Swift. Similarly, you can create a dictionary to store values of any specified type, and there are no limitations on what that type can be.
To make a generic function or type, you just have to write a name inside angle brackets –
func makeArray<Item>(repeating item: Item, numberOfTimes: Int) -> [Item] { var result = [Item]() for _ in 0..<numberOfTimes { result.append(item) } return result } makeArray(repeating: “knock”, numberOfTimes: 4)
Conclusion
The above guide illustrates many basic aspects of programming in Swift. However, there is a lot more Swift is capable of. To understand how Swift and Apple’s platforms can help you propagate your business to a wider audience, get in touch with us at hello@codetoart.com with our Swift experts.
(NOTE: Sample codes mentioned in the article and detailed guides can also be studied here.)