Mobile Development 10 min read

Understanding Swift Collection Protocols: StringProtocol, CustomStringConvertible, and Related Literals

This article explores Swift's collection‑type protocols, focusing on StringProtocol and related protocols such as CustomStringConvertible, CustomDebugStringConvertible, LosslessStringConvertible, and various ExpressibleBy… literals, providing code examples and explanations of their usage in mobile development.

Sohu Tech Products
Sohu Tech Products
Sohu Tech Products
Understanding Swift Collection Protocols: StringProtocol, CustomStringConvertible, and Related Literals

This article is the second part of a series analyzing Swift collection‑type protocols, with a focus on string‑related protocols.

StringProtocol abstracts the behavior of strings as collections of characters, enabling methods like uppercased() , lowercased() , and comparison operators. Both String and Substring conform to this protocol, allowing direct equality checks without conversion.

let helloSwift = "Hello Swift"
let swift = helloSwift[helloSwift.index(helloSwift.startIndex, offsetBy: 6)...]
// comparing a substring to a string
swift == "Swift"  // true

The protocol is also used as a parameter type for functions such as init(text: StringProtocol) , which lets callers avoid explicit type conversions.

CustomStringConvertible & CustomDebugStringConvertible provide custom textual representations for printing. The article lists the functions associated with each protocol:

Function

Protocol

Required Property

print

CustomStringConvertible

description

debugPrint

CustomDebugStringConvertible

debugDescription

dump

CustomReflectable

customMirror

Example of implementing CustomStringConvertible for a BankCard struct:

struct BankCard {
    let bankName: String
    let cardNumber: Int
}
let bankcard = BankCard(bankName: "CBC", cardNumber: 123232324565)
extension BankCard: CustomStringConvertible {
    var description: String { "\(self.bankName) \(self.cardNumber)" }
}
print(bankcard) // CBC 123232324565

Similarly, implementing CustomDebugStringConvertible provides a multi‑line debug description:

extension BankCard: CustomDebugStringConvertible {
    var debugDescription: String {
        """
        BankName: \(self.bankName)
        CardNumber: \(self.cardNumber)
        """
    }
}

The dump function prints detailed, hierarchical representations of values, useful for large collections:

let names = ["apple", "orange", "banana"]
dump(names)
let iPhones = ["iPhoneX": 9688, "iPhone8 plus": 7888, "iphone8": 6888]
dump(iPhones)

LosslessStringConvertible allows lossless conversion between a type and its string representation. Types such as Int , Bool , Double , etc., conform to this protocol. An example implementation for a FlightCode type shows how to parse and reconstruct the value:

extension FlightCode: LosslessStringConvertible {
    public init?(_ description: String) {
        let components = description.split(separator: " ")
        guard components.count == 2,
              let airlineCode = components.first,
              let number = components.last,
              let flightNumber = Int(number) else { return nil }
        self.airlineCode = String(airlineCode)
        self.flightNumber = flightNumber
    }
}
let flight = FlightCode(airlineCode: "AA", flightNumber: 1)
String(flight) // "AA 1"
FlightCode(String(flight)) // FlightCode(airlineCode: "AA", flightNumber: 1)

The article also covers the literal protocols ExpressibleByUnicodeScalarLiteral , ExpressibleByExtendedGraphemeClusterLiteral , and ExpressibleByStringLiteral , showing how to create values directly from string literals:

let unicodeScalar: Unicode.Scalar = "A"
let character: Character = "A"
let string: String = "A"

It explains extended grapheme clusters, demonstrating that a single Swift Character can represent composed or decomposed Unicode sequences, such as the character "é".

let eAcute: Character = "\u{E9}" // é
let combinedEAcute: Character = "\u{65}\u{301}" // é

Finally, the article shows how to make existing types conform to literal protocols, e.g., extending URL to be initializable from a string literal, and introduces ExpressibleByStringInterpolation , which enables custom interpolation behavior.

SwiftCodeExamplesCustomStringConvertibleLosslessStringConvertibleStringInterpolationStringProtocol
Sohu Tech Products
Written by

Sohu Tech Products

A knowledge-sharing platform for Sohu's technology products. As a leading Chinese internet brand with media, video, search, and gaming services and over 700 million users, Sohu continuously drives tech innovation and practice. We’ll share practical insights and tech news here.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.