Convert a Swift Range to Use String.Index

The Situation

I was working on a SwiftUI app where I wanted to select text in a text view and insert some text at the start of the selection. SwiftUI’s native text editor currently does not support getting the selection range so I had to wrap an AppKit text view and store the selection range when the selection changes.

The Problem

The code in the previous example gives me a Swift range, which uses integers, Range<Int>. I wanted to use the selection range’s start index as the destination to insert the string.

But the compiler gave me an error. The reason for the error is the String struct’s insert method takes a range that uses string indexes, Range<String.Index>, not integers.

The Solution

The solution is to create a string index for the string and use that as the argument to the insert method. The base for the string index is the string’s start index. The offset for the string index is the selection range’s lower bound.