How to Convert Hex to String in Swift (A Practical Guide)

Many developers encounter the need to convert a hexadecimal string into a regular human-readable string in their Swift projects. Whether you’re handling network data, parsing files, or cleaning up encoded text, hex-to-string conversion is actually a common scenario—you might even use a dedicated hex to string tool for quick manual checks before integrating code.
In reality, it’s quite simple once you grasp the method. This guide will walk you through the implementation step by step, with copyable code to help you get started quickly.

Why Do You Need Hex to String Conversion?

Let’s first talk about real-world use cases: Hexadecimal strings are often used to represent binary data in a human-readable format. For example, "Hello World" might be expressed as 48656c6c6f20576f726c64—a scenario common in API interactions (when backends return binary-encoded data), encryption processes, color code handling, or checksum calculations.

If you receive hex-encoded data from an external source, you’ll need to decode it back into a regular string—and that’s where Swift’s Data type comes in handy.

Step-by-Step Implementation: Hex String to Regular String

Below is the detailed implementation, broken down for easy understanding.

Step 1: Convert the Hex String to a Data Object

First, you need to convert the hex string (e.g., 48656c6c6f) into a Data object. Swift doesn’t have a built-in method for this, so we’ll create a utility function using a String extension for convenience.

 extension String {
    func hexToString() -> String? {
        // Hex string length must be even (each byte corresponds to two hex characters)
        guard self.count % 2 == 0 else {
            print("Hex string has an odd length; cannot convert")
            return nil
        }
        
        var data = Data()
        
        // Process two characters at a time (corresponding to one byte)
        for i in stride(from: 0, to: self.count, by: 2) {
            let startIndex = self.index(self.startIndex, offsetBy: i)
            let endIndex = self.index(startIndex, offsetBy: 2)
            let hexPair = String(self[startIndex..<endIndex])
            
            // Convert the two hex characters to a UInt8 (byte)
            guard let byte = UInt8(hexPair, radix: 16) else {
                print("Invalid hex character(s): \(hexPair)")
                return nil
            }
            
            data.append(byte)
        }
        
        // Convert Data to string using UTF-8 encoding
        return String(data: data, encoding: .utf8)
    }
}

Step 2: Call the Method in Your Code

With this extension, you can call the method directly on any hex string. Here’s a practical example:

 // Hex string corresponding to "Hello World"
let hexString = "48656c6c6f20576f726c64"

if let normalString = hexString.hexToString() {
    print(normalString)  // Output: Hello World
} else {
    print("Conversion failed!")
}

How the Code Works

The conversion process follows a clear logic, broken down into key steps:

  1. Length Check: First, we use a guard statement to verify if the string length is even. Since each byte maps to two hex characters, an odd-length string is inherently invalid.
  2. Batch Processing: We use the stride method to extract two characters at a time (representing one hex byte), avoiding index out-of-bounds errors in loops.
  3. Byte Conversion: The UInt8(_:radix: 16) initializer converts the two hex characters into a byte (of type UInt8), where radix: 16 specifies parsing in hexadecimal.
  4. Build the Data Object: Each converted byte is appended to a Data object, which is essentially a wrapper for a sequence of bytes.
  5. Decode to String: Finally, String(data:encoding:) decodes the Data into a regular string using UTF-8 encoding.

Common Pitfalls & Tips

Summary

Hex to string conversion is a basic yet practical skill in Swift development. Save this extension to your toolbox, and you’ll be able to reuse it for debugging, log parsing, or network client development.

Always handle errors gracefully (e.g., with optional binding) when working with external data or user input. Now copy the code into your project and give it a try!

If you encounter a hex string that fails to convert, feel free to leave it in the comments and we’ll troubleshoot it together!