ISwift 4.0

  1. Swift 4.0 Interview Questions
  2. Swift 4.0 Vs 5.0

The powerful programming language that is also easy to learn.

Swift is a new programming language for iOS, macOS, watchOS, and tvOS app development. Nonetheless, many parts of Swift will be familiar from your experience of developing in C and Objective-C.

Swift is a powerful and intuitive programming language for macOS, iOS, watchOS, tvOS and beyond. Writing Swift code is interactive and fun, the syntax is concise yet expressive, and Swift includes modern features developers love. Swift code is safe by design, yet also produces software that runs lightning-fast.

Introducing Swift 5.1

Swift 5.1 now makes it easier to create and share binary frameworks with others. It also includes features that make it easier to design better APIs and reduce the amount of common boilerplate code.

Key Features

  • Module stability defines a new text-based module interface file that describes the API of a binary framework.
  • Property wrappers introduce a general purpose syntax for defining custom access patterns for property values.
  • Opaque result types help hide implementation details in APIs.
  • 'Self' can now be used for classes and value types.
  • Support for handling and updating diffs on collections of appropriate types.
  • Improvements to SIMD and String types.

Modern

Swift is the result of the latest research on programming languages, combined with decades of experience building Apple platforms. Named parameters are expressed in a clean syntax that makes APIs in Swift even easier to read and maintain. Even better, you don’t even need to type semi-colons. Inferred types make code cleaner and less prone to mistakes, while modules eliminate headers and provide namespaces. To best support international languages and emoji, Strings are Unicode-correct and use a UTF-8 based encoding to optimize performance for a wide-variety of use cases. Memory is managed automatically using tight, deterministic reference counting, keeping memory usage to a minimum without the overhead of garbage collection.

Declare new types with modern, straightforward syntax. Provide default values for instance properties and define custom initializers.

Add functionality to existing types using extensions, and cut down on boilerplate with custom string interpolations.

Quickly extend your custom types to take advantage of powerful language features, such as automatic JSON encoding and decoding.

Perform powerful custom transformations using streamlined closures.

These forward-thinking concepts result in a language that is fun and easy to use.

Swift has many other features to make your code more expressive:

  • Generics that are powerful and simple to use
  • Protocol extensions that make writing generic code even easier
  • First class functions and a lightweight closure syntax
  • Fast and concise iteration over a range or collection
  • Tuples and multiple return values
  • Structs that support methods, extensions, and protocols
  • Enums can have payloads and support pattern matching
  • Functional programming patterns, e.g., map and filter
  • Native error handling using try / catch / throw

Designed for Safety

Swift eliminates entire classes of unsafe code. Variables are always initialized before use, arrays and integers are checked for overflow, memory is automatically managed, and enforcement of exclusive access to memory guards against many programming mistakes. Syntax is tuned to make it easy to define your intent — for example, simple three-character keywords define a variable ( var ) or constant ( let ). And Swift heavily leverages value types, especially for commonly used types like Arrays and Dictionaries. This means that when you make a copy of something with that type, you know it won’t be modified elsewhere.

Another safety feature is that by default Swift objects can never be nil. In fact, the Swift compiler will stop you from trying to make or use a nil object with a compile-time error. This makes writing code much cleaner and safer, and prevents a huge category of runtime crashes in your apps. However, there are cases where nil is valid and appropriate. For these situations Swift has an innovative feature known as optionals. An optional may contain nil, but Swift syntax forces you to safely deal with it using the ? syntax to indicate to the compiler you understand the behavior and will handle it safely.

Use optionals when you might have an instance to return from a function, or you might not.

Features such as optional binding, optional chaining, and nil coalescing let you work safely and efficiently with optional values.

Fast and Powerful

From its earliest conception, Swift was built to be fast. Using the incredibly high-performance LLVM compiler technology, Swift code is transformed into optimized native code that gets the most out of modern hardware. The syntax and standard library have also been tuned to make the most obvious way to write your code also perform the best whether it runs in the watch on your wrist or across a cluster of servers.

Swift is a successor to both the C and Objective-C languages. It includes low-level primitives such as types, flow control, and operators. It also provides object-oriented features such as classes, protocols, and generics, giving Cocoa and Cocoa Touch developers the performance and power they demand.

Great First Language

Swift can open doors to the world of coding. In fact, it was designed to be anyone’s first programming language, whether you’re still in school or exploring new career paths. For educators, Apple created free curriculum to teach Swift both in and out of the classroom. First-time coders can download Swift Playgrounds—an app for iPad that makes getting started with Swift code interactive and fun.

Aspiring app developers can access free courses to learn to build their first apps in Xcode. And Apple Stores around the world host Today at Apple Coding & Apps sessions where you can get hands-on experience with Swift code.

Source and Binary Compatibility

With Swift 5, you don’t have to modify any of your Swift 4 code to use the new version of the compiler. Instead you can start using the new compiler and migrate at your own pace, taking advantage of new Swift 5 features, one module at a time. And Swift 5 now introduces binary compatibility for apps. That means you no longer need to include Swift libraries in apps that target current and future OS releases, because the Swift libraries will be included in every OS release going forward. Your apps will leverage the latest version of the library in the OS, and your code will continue to run without recompiling. This not only makes developing your app simpler, it also reduces the size of your app and its launch time.

Open Source

Swift is developed in the open at Swift.org, with source code, a bug tracker, forums, and regular development builds available for everyone. This broad community of developers, both inside Apple as well as hundreds of outside contributors, work together to make Swift even more amazing. There is an even broader range of blogs, podcasts, conferences and meetups where developers in the community share their experiences of how to realize Swift’s great potential.

Cross Platform

Swift already supports all Apple platforms and Linux, with community members actively working to port to even more platforms. With SourceKit-LSP, the community is also working to integrate Swift support into a wide-variety of developer tools. We’re excited to see more ways in which Swift makes software safer and faster, while also making programming more fun.

Swift for Server

While Swift powers many new apps on Apple platforms, it’s also being used for a new class of modern server applications. Swift is perfect for use in server apps that need runtime safety, compiled performance and a small memory footprint. To steer the direction of Swift for developing and deploying server applications, the community formed the Swift Server work group. The first product of this effort was SwiftNIO, a cross-platform asynchronous event-driven network application framework for high performance protocol servers and clients. It serves as the foundation for building additional server-oriented tools and technologies, including logging, metrics and database drivers which are all in active development.

To learn more about the open source Swift community and the Swift Server work group, visit Swift.org

Playgrounds and Read-Eval-Print-Loop (REPL)

Much like Swift Playgrounds for iPad, playgrounds in Xcode make writing Swift code incredibly simple and fun. Type a line of code and the result appears immediately. You can then Quick Look the result from the side of your code, or pin that result directly below. The result view can display graphics, lists of results, or graphs of a value over time. You can open the Timeline Assistant to watch a complex view evolve and animate, great for experimenting with new UI code, or to play an animated SpriteKit scene as you code it. When you’ve perfected your code in the playground, simply move that code into your project. Swift is also interactive when you use it in Terminal or within Xcode’s LLDB debugging console. Use Swift syntax to evaluate and interact with your running app, or write new code to see how it works in a script-like environment.

Package Manager

Swift Package Manager is a single cross-platform tool for building, running, testing and packaging your Swift libraries and executables. Swift packages are the best way to distribute libraries and source code to the Swift community. Configuration of packages is written in Swift itself, making it easy to configure targets, declare products and manage package dependencies. New to Swift 5, the swift run command now includes the ability to import libraries in a REPL without needing to build an executable. Swift Package Manager itself is actually built with Swift and included in the Swift open source project as a package.

Objective-C Interoperability

You can create an entirely new application with Swift today, or begin using Swift code to implement new features and functionality in your app. Swift code co-exists along side your existing Objective-C files in the same project, with full access to your Objective-C API, making it easy to adopt.

Get Started

Download Xcode and learn how to build apps using Swift with documentation and sample code.

On This Page
  • Strings and Characters
    • String Literals
    • Unicode
    • Accessing and Modifying a String
    • Comparing Strings
    • Unicode Representations of Strings

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 representations.

Note

Swift’s String type is bridged with Foundation’s NSString class. Foundation also extends String to expose methods defined by NSString. This means, if you import Foundation, you can access those NSString methods on String without casting.

For more information about using String with Foundation and Cocoa, see Bridging Between String and NSString.

String Literals¶

You can include predefined String values within your code as string literals. A string literal is a sequence of characters surrounded by double quotation marks (').

Use a string literal as an initial value for a constant or variable:

Note that Swift infers a type of String for the someString constant because it’s initialized with a string literal value.

Multiline String Literals¶

If you need a string that spans several lines, use a multiline string literal—a sequence of characters surrounded by three double quotation marks:

  1. letquotation = ''
  2. The White Rabbit put on his spectacles. 'Where shall I begin,
  3. please your Majesty?' he asked.
  4. 'Begin at the beginning,' the King said gravely, 'and go on
  5. till you come to the end; then stop.'
  6. ''

A multiline string literal includes all of the lines between its opening and closing quotation marks. The string begins on the first line after the opening quotation marks ('') and ends on the line before the closing quotation marks, which means that neither of the strings below start or end with a line break:

  1. letsingleLineString = 'These are the same.'
  2. letmultilineString = ''
  3. These are the same.
  4. ''

When your source code includes a line break inside of a multiline string literal, that line break also appears in the string’s value. If you want to use line breaks to make your source code easier to read, but you don’t want the line breaks to be part of the string’s value, write a backslash () at the end of those lines:

  1. letsoftWrappedQuotation = ''
  2. The White Rabbit put on his spectacles. 'Where shall I begin,
  3. please your Majesty?' he asked.
  4. 'Begin at the beginning,' the King said gravely, 'and go on
  5. till you come to the end; then stop.'
  6. ''

To make a multiline string literal that begins or ends with a line feed, write a blank line as the first or last line. For example:

  1. letlineBreaks = ''
  2. This string starts with a line break.
  3. It also ends with a line break.
  4. ''

A multiline string can be indented to match the surrounding code. The whitespace before the closing quotation marks ('') tells Swift what whitespace to ignore before all of the other lines. However, if you write whitespace at the beginning of a line in addition to what’s before the closing quotation marks, that whitespace is included.

In the example above, even though the entire multiline string literal is indented, the first and last lines in the string don’t begin with any whitespace. The middle line has more indentation than the closing quotation marks, so it starts with that extra four-space indentation.

Special Characters in String Literals¶

String literals can include the following special characters:

  • The escaped special characters 0 (null character), (backslash), t (horizontal tab), n (line feed), r (carriage return), ' (double quotation mark) and ' (single quotation mark)
  • An arbitrary Unicode scalar value, written as u{n}, where n is a 1–8 digit hexadecimal number (Unicode is discussed in Unicode below)

The code below shows four examples of these special characters. The wiseWords constant contains two escaped double quotation marks. The dollarSign, blackHeart, and sparklingHeart constants demonstrate the Unicode scalar format:

  1. letwiseWords = 'Imagination is more important than knowledge' - Einstein'
  2. // 'Imagination is more important than knowledge' - Einstein
  3. letdollarSign = 'u{24}'// $, Unicode scalar U+0024
  4. letblackHeart = 'u{2665}'// ♥, Unicode scalar U+2665
  5. letsparklingHeart = 'u{1F496}'// 💖, Unicode scalar U+1F496

Because multiline string literals use three double quotation marks instead of just one, you can include a double quotation mark (') inside of a multiline string literal without escaping it. To include the text '' in a multiline string, escape at least one of the quotation marks. For example:

  1. letthreeDoubleQuotationMarks = ''
  2. Escaping the first quotation mark ''
  3. Escaping all three quotation marks ''
  4. ''

Extended String Delimiters¶

You can place a string literal within extended delimiters to include special characters in a string without invoking their effect. You place your string within quotation marks (') and surround that with number signs (#). For example, printing the string literal #'Line1nLine2'# prints the line feed escape sequence (n) rather than printing the string across two lines.

If you need the special effects of a character in a string literal, match the number of number signs within the string following the escape character (). For example, if your string is #'Line1nLine2'# and you want to break the line, you can use #'Line1#nLine2'# instead. Similarly, ###'Line1###nLine2'### also breaks the line.

String literals created using extended delimiters can also be multiline string literals. You can use extended delimiters to include the text '' in a multiline string, overriding the default behavior that ends the literal. For example:

  1. letthreeMoreDoubleQuotationMarks = #''
  2. Here are three more double quotes: ''
  3. ''#

Initializing an Empty String¶

To create an empty String value as the starting point for building a longer string, either assign an empty string literal to a variable, or initialize a new String instance with initializer syntax:

  1. varemptyString = '// empty string literal
  2. varanotherEmptyString = String() // initializer syntax
  3. // these two strings are both empty, and are equivalent to each other

Find out whether a String value is empty by checking its Boolean isEmpty property:

  1. ifemptyString.isEmpty {
  2. print('Nothing to see here')
  3. }
  4. // Prints 'Nothing to see here'

String Mutability¶

You indicate whether a particular String can be modified (or mutated) by assigning it to a variable (in which case it can be modified), or to a constant (in which case it can’t be modified):

  1. varvariableString = 'Horse'
  2. variableString += ' and carriage'
  3. // variableString is now 'Horse and carriage'
  4. letconstantString = 'Highlander'
  5. constantString += ' and another Highlander'
  6. // this reports a compile-time error - a constant string cannot be modified

Note

This approach is different from string mutation in Objective-C and Cocoa, where you choose between two classes (NSString and NSMutableString) to indicate whether a string can be mutated.

Strings Are Value Types¶

Swift’s String type is a value type. If you create a new String value, that String value is copied when it’s passed to a function or method, or when it’s assigned to a constant or variable. In each case, a new copy of the existing String value is created, and the new copy is passed or assigned, not the original version. Value types are described in Structures and Enumerations Are Value Types.

Swift’s copy-by-default String behavior ensures that when a function or method passes you a String value, it’s clear that you own that exact String value, regardless of where it came from. You can be confident that the string you are passed won’t be modified unless you modify it yourself.

Behind the scenes, Swift’s compiler optimizes string usage so that actual copying takes place only when absolutely necessary. This means you always get great performance when working with strings as value types.

Working with Characters¶

You can access the individual Character values for a String by iterating over the string with a for-in loop:

  1. forcharacterin'Dog!🐶' {
  2. print(character)
  3. }
  4. // D
  5. // o
  6. // g
  7. // !
  8. // 🐶

The for-in loop is described in For-In Loops.

Alternatively, you can create a stand-alone Character constant or variable from a single-character string literal by providing a Character type annotation:

String values can be constructed by passing an array of Character values as an argument to its initializer:

  1. letcatCharacters: [Character] = ['C', 'a', 't', '!', '🐱']
  2. letcatString = String(catCharacters)
  3. print(catString)
  4. // Prints 'Cat!🐱'

Concatenating Strings and Characters¶

String values can be added together (or concatenated) with the addition operator (+) to create a new String value:

  1. letstring1 = 'hello'
  2. letstring2 = ' there'
  3. varwelcome = string1 + string2
  4. // welcome now equals 'hello there'

You can also append a String value to an existing String variable with the addition assignment operator (+=):

  1. varinstruction = 'look over'
  2. instruction += string2
  3. // instruction now equals 'look over there'

You can append a Character value to a String variable with the String type’s append() method:

  1. letexclamationMark: Character = '!'
  2. welcome.append(exclamationMark)
  3. // welcome now equals 'hello there!'

Note

You can’t append a String or Character to an existing Character variable, because a Character value must contain a single character only.

If you’re using multiline string literals to build up the lines of a longer string, you want every line in the string to end with a line break, including the last line. For example:

  1. letbadStart = ''
  2. one
  3. two
  4. ''
  5. letend = ''
  6. three
  7. ''
  8. print(badStart + end)
  9. // Prints two lines:
  10. // one
  11. // twothree
  12. letgoodStart = ''
  13. one
  14. two
  15. ''
  16. print(goodStart + end)
  17. // Prints three lines:
  18. // one
  19. // two
  20. // three

In the code above, concatenating badStart with end produces a two-line string, which isn’t the desired result. Because the last line of badStart doesn’t end with a line break, that line gets combined with the first line of end. In contrast, both lines of goodStart end with a line break, so when it’s combined with end the result has three lines, as expected.

String Interpolation¶

String interpolation is a way to construct a new String value from a mix of constants, variables, literals, and expressions by including their values inside a string literal. You can use string interpolation in both single-line and multiline string literals. Each item that you insert into the string literal is wrapped in a pair of parentheses, prefixed by a backslash ():

  1. letmultiplier = 3
  2. letmessage = '(multiplier) times 2.5 is (Double(multiplier) * 2.5)'
  3. // message is '3 times 2.5 is 7.5'

In the example above, the value of multiplier is inserted into a string literal as (multiplier). This placeholder is replaced with the actual value of multiplier when the string interpolation is evaluated to create an actual string.

The value of multiplier is also part of a larger expression later in the string. This expression calculates the value of Double(multiplier)*2.5 and inserts the result (7.5) into the string. In this case, the expression is written as (Double(multiplier)*2.5) when it’s included inside the string literal.

You can use extended string delimiters to create strings containing characters that would otherwise be treated as a string interpolation. For example:

  1. print(#'Write an interpolated string in Swift using (multiplier).'#)
  2. // Prints 'Write an interpolated string in Swift using (multiplier).'

To use string interpolation inside a string that uses extended delimiters, match the number of number signs before the backslash to the number of number signs at the beginning and end of the string. For example:

  1. print(#'6 times 7 is #(6 * 7).'#)
  2. // Prints '6 times 7 is 42.'

Note

The expressions you write inside parentheses within an interpolated string can’t contain an unescaped backslash (), a carriage return, or a line feed. However, they can contain other string literals.

Unicode¶

Unicode is an international standard for encoding, representing, and processing text in different writing systems. It enables you to represent almost any character from any language in a standardized form, and to read and write those characters to and from an external source such as a text file or web page. Swift’s String and Character types are fully Unicode-compliant, as described in this section.

Unicode Scalar Values¶

Behind the scenes, Swift’s native String type is built from Unicode scalar values. A Unicode scalar value is a unique 21-bit number for a character or modifier, such as U+0061 for LATINSMALLLETTERA ('a'), or U+1F425 for FRONT-FACINGBABYCHICK ('🐥').

Note that not all 21-bit Unicode scalar values are assigned to a character—some scalars are reserved for future assignment or for use in UTF-16 encoding. Scalar values that have been assigned to a character typically also have a name, such as LATINSMALLLETTERA and FRONT-FACINGBABYCHICK in the examples above.

Extended Grapheme Clusters¶

Every instance of Swift’s Character type represents a single extended grapheme cluster. An extended grapheme cluster is a sequence of one or more Unicode scalars that (when combined) produce a single human-readable character.

Here’s an example. The letter é can be represented as the single Unicode scalar é (LATINSMALLLETTEREWITHACUTE, or U+00E9). However, the same letter can also be represented as a pair of scalars—a standard letter e (LATINSMALLLETTERE, or U+0065), followed by the COMBININGACUTEACCENT scalar (U+0301). The COMBININGACUTEACCENT scalar is graphically applied to the scalar that precedes it, turning an e into an é when it’s rendered by a Unicode-aware text-rendering system.

In both cases, the letter é is represented as a single Swift Character value that represents an extended grapheme cluster. In the first case, the cluster contains a single scalar; in the second case, it’s a cluster of two scalars:

  1. leteAcute: Character = 'u{E9}'// é
  2. letcombinedEAcute: Character = 'u{65}u{301}'// e followed by ́
  3. // eAcute is é, combinedEAcute is é

Extended grapheme clusters are a flexible way to represent many complex script characters as a single Character value. For example, Hangul syllables from the Korean alphabet can be represented as either a precomposed or decomposed sequence. Both of these representations qualify as a single Character value in Swift:

  1. letprecomposed: Character = 'u{D55C}'// 한
  2. letdecomposed: Character = 'u{1112}u{1161}u{11AB}'// ᄒ, ᅡ, ᆫ
  3. // precomposed is 한, decomposed is 한

Extended grapheme clusters enable scalars for enclosing marks (such as COMBININGENCLOSINGCIRCLE, or U+20DD) to enclose other Unicode scalars as part of a single Character value:

  1. letenclosedEAcute: Character = 'u{E9}u{20DD}'
  2. // enclosedEAcute is é⃝

Unicode scalars for regional indicator symbols can be combined in pairs to make a single Character value, such as this combination of REGIONALINDICATORSYMBOLLETTERU (U+1F1FA) and REGIONALINDICATORSYMBOLLETTERS (U+1F1F8):

  1. letregionalIndicatorForUS: Character = 'u{1F1FA}u{1F1F8}'
  2. // regionalIndicatorForUS is 🇺🇸

Counting Characters¶

To retrieve a count of the Character values in a string, use the count property of the string:

  1. letunusualMenagerie = 'Koala 🐨, Snail 🐌, Penguin 🐧, Dromedary 🐪'
  2. print('unusualMenagerie has (unusualMenagerie.count) characters')
  3. // Prints 'unusualMenagerie has 40 characters'

Note that Swift’s use of extended grapheme clusters for Character values means that string concatenation and modification may not always affect a string’s character count.

For example, if you initialize a new string with the four-character word cafe, and then append a COMBININGACUTEACCENT (U+0301) to the end of the string, the resulting string will still have a character count of 4, with a fourth character of , not e:

  1. varword = 'cafe'
  2. print('the number of characters in (word) is (word.count)')
  3. // Prints 'the number of characters in cafe is 4'
  4. word += 'u{301}'// COMBINING ACUTE ACCENT, U+0301
  5. print('the number of characters in (word) is (word.count)')
  6. // Prints 'the number of characters in café is 4'

Note

Extended grapheme clusters can be composed of multiple Unicode scalars. This means that different characters—and different representations of the same character—can require different amounts of memory to store. Because of this, characters in Swift don’t each take up the same amount of memory within a string’s representation. As a result, the number of characters in a string can’t be calculated without iterating through the string to determine its extended grapheme cluster boundaries. If you are working with particularly long string values, be aware that the count property must iterate over the Unicode scalars in the entire string in order to determine the characters for that string.

The count of the characters returned by the count property isn’t always the same as the length property of an NSString that contains the same characters. The length of an NSString is based on the number of 16-bit code units within the string’s UTF-16 representation and not the number of Unicode extended grapheme clusters within the string.

Accessing and Modifying a String¶

You access and modify a string through its methods and properties, or by using subscript syntax.

String Indices¶

Each String value has an associated index type, String.Index, which corresponds to the position of each Character in the string.

As mentioned above, different characters can require different amounts of memory to store, so in order to determine which Character is at a particular position, you must iterate over each Unicode scalar from the start or end of that String. For this reason, Swift strings can’t be indexed by integer values.

4.0

Use the startIndex property to access the position of the first Character of a String. The endIndex property is the position after the last character in a String. As a result, the endIndex property isn’t a valid argument to a string’s subscript. If a String is empty, startIndex and endIndex are equal.

You access the indices before and after a given index using the index(before:) and index(after:) methods of String. To access an index farther away from the given index, you can use the index(_:offsetBy:) method instead of calling one of these methods multiple times.

You can use subscript syntax to access the Character at a particular String index.

  1. letgreeting = 'Guten Tag!'
  2. greeting[greeting.startIndex]
  3. // G
  4. greeting[greeting.index(before: greeting.endIndex)]
  5. // !
  6. greeting[greeting.index(after: greeting.startIndex)]
  7. // u
  8. letindex = greeting.index(greeting.startIndex, offsetBy: 7)
  9. greeting[index]
  10. // a

Attempting to access an index outside of a string’s range or a Character at an index outside of a string’s range will trigger a runtime error.

  1. greeting[greeting.endIndex] // Error
  2. greeting.index(after: greeting.endIndex) // Error

Use the indices property to access all of the indices of individual characters in a string.

  1. forindexingreeting.indices {
  2. print('(greeting[index]) ', terminator: ')
  3. }
  4. // Prints 'G u t e n T a g ! '

Note

You can use the startIndex and endIndex properties and the index(before:), index(after:), and index(_:offsetBy:) methods on any type that conforms to the Collection protocol. This includes String, as shown here, as well as collection types such as Array, Dictionary, and Set.

Inserting and Removing¶

To insert a single character into a string at a specified index, use the insert(_:at:) method, and to insert the contents of another string at a specified index, use the insert(contentsOf:at:) method.

  1. varwelcome = 'hello'
  2. welcome.insert('!', at: welcome.endIndex)
  3. // welcome now equals 'hello!'
  4. welcome.insert(contentsOf: ' there', at: welcome.index(before: welcome.endIndex))
  5. // welcome now equals 'hello there!'

To remove a single character from a string at a specified index, use the remove(at:) method, and to remove a substring at a specified range, use the removeSubrange(_:) method:

  1. welcome.remove(at: welcome.index(before: welcome.endIndex))
  2. // welcome now equals 'hello there'
  3. letrange = welcome.index(welcome.endIndex, offsetBy: -6)..<welcome.endIndex
  4. welcome.removeSubrange(range)
  5. // welcome now equals 'hello'

Note

You can use the insert(_:at:), insert(contentsOf:at:), remove(at:), and removeSubrange(_:) methods on any type that conforms to the RangeReplaceableCollection protocol. This includes String, as shown here, as well as collection types such as Array, Dictionary, and Set.

Substrings¶

When you get a substring from a string—for example, using a subscript or a method like prefix(_:)—the result is an instance of Substring, not another string. Substrings in Swift have most of the same methods as strings, which means you can work with substrings the same way you work with strings. However, unlike strings, you use substrings for only a short amount of time while performing actions on a string. When you’re ready to store the result for a longer time, you convert the substring to an instance of String. For example:

  1. letgreeting = 'Hello, world!'
  2. letindex = greeting.firstIndex(of: ',') ?? greeting.endIndex
  3. letbeginning = greeting[..<index]
  4. // beginning is 'Hello'
  5. // Convert the result to a String for long-term storage.
  6. letnewString = String(beginning)

Like strings, each substring has a region of memory where the characters that make up the substring are stored. The difference between strings and substrings is that, as a performance optimization, a substring can reuse part of the memory that’s used to store the original string, or part of the memory that’s used to store another substring. (Strings have a similar optimization, but if two strings share memory, they are equal.) This performance optimization means you don’t have to pay the performance cost of copying memory until you modify either the string or substring. As mentioned above, substrings aren’t suitable for long-term storage—because they reuse the storage of the original string, the entire original string must be kept in memory as long as any of its substrings are being used.

In the example above, greeting is a string, which means it has a region of memory where the characters that make up the string are stored. Because beginning is a substring of greeting, it reuses the memory that greeting uses. In contrast, newString is a string—when it’s created from the substring, it has its own storage. The figure below shows these relationships:

Note

Both String and Substring conform to the StringProtocol protocol, which means it’s often convenient for string-manipulation functions to accept a StringProtocol value. You can call such functions with either a String or Substring value.

Comparing Strings¶

Swift provides three ways to compare textual values: string and character equality, prefix equality, and suffix equality.

String and Character Equality¶

String and character equality is checked with the “equal to” operator () and the “not equal to” operator (!=), as described in Comparison Operators:

  1. letquotation = 'We're a lot alike, you and I.'
  2. letsameQuotation = 'We're a lot alike, you and I.'
  3. ifquotationsameQuotation {
  4. print('These two strings are considered equal')
  5. }
  6. // Prints 'These two strings are considered equal'

Two String values (or two Character values) are considered equal if their extended grapheme clusters are canonically equivalent. Extended grapheme clusters are canonically equivalent if they have the same linguistic meaning and appearance, even if they’re composed from different Unicode scalars behind the scenes.

For example, LATINSMALLLETTEREWITHACUTE (U+00E9) is canonically equivalent to LATINSMALLLETTERE (U+0065) followed by COMBININGACUTEACCENT (U+0301). Both of these extended grapheme clusters are valid ways to represent the character é, and so they’re considered to be canonically equivalent:

  1. // 'Voulez-vous un café?' using LATIN SMALL LETTER E WITH ACUTE
  2. leteAcuteQuestion = 'Voulez-vous un cafu{E9}?'
  3. // 'Voulez-vous un café?' using LATIN SMALL LETTER E and COMBINING ACUTE ACCENT
  4. letcombinedEAcuteQuestion = 'Voulez-vous un cafu{65}u{301}?'
  5. ifeAcuteQuestioncombinedEAcuteQuestion {
  6. print('These two strings are considered equal')
  7. }
  8. // Prints 'These two strings are considered equal'

Conversely, LATINCAPITALLETTERA (U+0041, or 'A'), as used in English, is not equivalent to CYRILLICCAPITALLETTERA (U+0410, or 'А'), as used in Russian. The characters are visually similar, but don’t have the same linguistic meaning:

  1. letlatinCapitalLetterA: Character = 'u{41}'
  2. letcyrillicCapitalLetterA: Character = 'u{0410}'
  3. iflatinCapitalLetterA != cyrillicCapitalLetterA {
  4. print('These two characters are not equivalent.')
  5. }
  6. // Prints 'These two characters are not equivalent.'

Note

String and character comparisons in Swift are not locale-sensitive.

Prefix and Suffix Equality¶

To check whether a string has a particular string prefix or suffix, call the string’s hasPrefix(_:) and hasSuffix(_:) methods, both of which take a single argument of type String and return a Boolean value.

The examples below consider an array of strings representing the scene locations from the first two acts of Shakespeare’s Romeo and Juliet:

  1. letromeoAndJuliet = [
  2. 'Act 1 Scene 1: Verona, A public place',
  3. 'Act 1 Scene 2: Capulet's mansion',
  4. 'Act 1 Scene 3: A room in Capulet's mansion',
  5. 'Act 1 Scene 4: A street outside Capulet's mansion',
  6. 'Act 1 Scene 5: The Great Hall in Capulet's mansion',
  7. 'Act 2 Scene 1: Outside Capulet's mansion',
  8. 'Act 2 Scene 2: Capulet's orchard',
  9. 'Act 2 Scene 3: Outside Friar Lawrence's cell',
  10. 'Act 2 Scene 4: A street in Verona',
  11. 'Act 2 Scene 5: Capulet's mansion',
  12. 'Act 2 Scene 6: Friar Lawrence's cell'
  13. ]

You can use the hasPrefix(_:) method with the romeoAndJuliet array to count the number of scenes in Act 1 of the play:

ISwift 4.0
  1. varact1SceneCount = 0
  2. forsceneinromeoAndJuliet {
  3. ifscene.hasPrefix('Act 1 ') {
  4. act1SceneCount += 1
  5. }
  6. }
  7. print('There are (act1SceneCount) scenes in Act 1')
  8. // Prints 'There are 5 scenes in Act 1'

Similarly, use the hasSuffix(_:) method to count the number of scenes that take place in or around Capulet’s mansion and Friar Lawrence’s cell:

  1. varmansionCount = 0
  2. varcellCount = 0
  3. forsceneinromeoAndJuliet {
  4. ifscene.hasSuffix('Capulet's mansion') {
  5. mansionCount += 1
  6. } elseifscene.hasSuffix('Friar Lawrence's cell') {
  7. cellCount += 1
  8. }
  9. }
  10. print('(mansionCount) mansion scenes; (cellCount) cell scenes')
  11. // Prints '6 mansion scenes; 2 cell scenes'

Note

The hasPrefix(_:) and hasSuffix(_:) methods perform a character-by-character canonical equivalence comparison between the extended grapheme clusters in each string, as described in String and Character Equality.

Unicode Representations of Strings¶

When a Unicode string is written to a text file or some other storage, the Unicode scalars in that string are encoded in one of several Unicode-defined encoding forms. Each form encodes the string in small chunks known as code units. These include the UTF-8 encoding form (which encodes a string as 8-bit code units), the UTF-16 encoding form (which encodes a string as 16-bit code units), and the UTF-32 encoding form (which encodes a string as 32-bit code units).

Swift provides several different ways to access Unicode representations of strings. You can iterate over the string with a for-in statement, to access its individual Character values as Unicode extended grapheme clusters. This process is described in Working with Characters.

Alternatively, access a String value in one of three other Unicode-compliant representations:

  • A collection of UTF-8 code units (accessed with the string’s utf8 property)
  • A collection of UTF-16 code units (accessed with the string’s utf16 property)
  • A collection of 21-bit Unicode scalar values, equivalent to the string’s UTF-32 encoding form (accessed with the string’s unicodeScalars property)

Each example below shows a different representation of the following string, which is made up of the characters D, o, g, (DOUBLEEXCLAMATIONMARK, or Unicode scalar U+203C), and the 🐶 character (DOGFACE, or Unicode scalar U+1F436):

UTF-8 Representation¶

You can access a UTF-8 representation of a String by iterating over its utf8 property. This property is of type String.UTF8View, which is a collection of unsigned 8-bit (UInt8) values, one for each byte in the string’s UTF-8 representation:

  1. forcodeUnitindogString.utf8 {
  2. print('(codeUnit) ', terminator: ')
  3. }
  4. print(')
  5. // Prints '68 111 103 226 128 188 240 159 144 182 '

In the example above, the first three decimal codeUnit values (68, 111, 103) represent the characters D, o, and g, whose UTF-8 representation is the same as their ASCII representation. The next three decimal codeUnit values (226, 128, 188) are a three-byte UTF-8 representation of the DOUBLEEXCLAMATIONMARK character. The last four codeUnit values (240, 159, 144, 182) are a four-byte UTF-8 representation of the DOGFACE character.

UTF-16 Representation¶

You can access a UTF-16 representation of a String by iterating over its utf16 property. This property is of type String.UTF16View, which is a collection of unsigned 16-bit (UInt16) values, one for each 16-bit code unit in the string’s UTF-16 representation:

  1. forcodeUnitindogString.utf16 {
  2. print('(codeUnit) ', terminator: ')
  3. }
  4. print(')
  5. // Prints '68 111 103 8252 55357 56374 '

Again, the first three codeUnit values (68, 111, 103) represent the characters D, o, and g, whose UTF-16 code units have the same values as in the string’s UTF-8 representation (because these Unicode scalars represent ASCII characters).

The fourth codeUnit value (8252) is a decimal equivalent of the hexadecimal value 203C, which represents the Unicode scalar U+203C for the DOUBLEEXCLAMATIONMARK character. This character can be represented as a single code unit in UTF-16.

The fifth and sixth codeUnit values (55357 and 56374) are a UTF-16 surrogate pair representation of the DOGFACE character. These values are a high-surrogate value of U+D83D (decimal value 55357) and a low-surrogate value of U+DC36 (decimal value 56374).

Unicode Scalar Representation¶

Swift 4.0 Interview Questions

You can access a Unicode scalar representation of a String value by iterating over its unicodeScalars property. This property is of type UnicodeScalarView, which is a collection of values of type UnicodeScalar.

Each UnicodeScalar has a value property that returns the scalar’s 21-bit value, represented within a UInt32 value:

Swift 4.0 Vs 5.0

  1. forscalarindogString.unicodeScalars {
  2. print('(scalar.value) ', terminator: ')
  3. }
  4. print(')
  5. // Prints '68 111 103 8252 128054 '

The value properties for the first three UnicodeScalar values (68, 111, 103) once again represent the characters D, o, and g.

The fourth codeUnit value (8252) is again a decimal equivalent of the hexadecimal value 203C, which represents the Unicode scalar U+203C for the DOUBLEEXCLAMATIONMARK character.

The value property of the fifth and final UnicodeScalar, 128054, is a decimal equivalent of the hexadecimal value 1F436, which represents the Unicode scalar U+1F436 for the DOGFACE character.

As an alternative to querying their value properties, each UnicodeScalar value can also be used to construct a new String value, such as with string interpolation:

  1. forscalarindogString.unicodeScalars {
  2. print('(scalar) ')
  3. }
  4. // D
  5. // o
  6. // g
  7. // ‼
  8. // 🐶