You're right that String, as a Collection, refers to position using index. However, Swift makes a distinction between index and offset. What you're thinking of is an offset, which starts at zero and increases by one after every item.
Collections don't use offsets. They instead use index, which does not need to start at zero, e.g. ArraySlice, and doesn't even need to be Int, e.g. String.
To move around, you start from a valid index (startIndex, endIndex) and use the Collection's APIs, such as index(after:) to create another, valid index. In your example, you want an item at offset one, you can fetch an index after the startIndex:
let index = string.index(after: string.startIndex)
string[index] // B
string.unicodeScalars[index] // 66
You can mutate the valid index in-place:
var index = string.startIndex
string.formIndex(after: &index)
string[index] // B
There's also a variation to move by multiple offsets:
let index1 = string.index(string.startIndex, offsetBy: 1)
var index2 = string.startIndex
string.formIndex(&index2, offsetBy: 1)
string[index1] // B
string[index2] // B
Here's a little something, String also adopts the concept of Views, which means that a valid String index is also a valid index for other collections in its possession, including unicodeScalars, utf8, utf16, etc. So you can (largely) interchanges indices between different views.