Esta é uma extensão que permitirá que você acesse os limites de uma substring como Ints em vez de String.Indexvalores:
import Foundation
extension StringProtocol {
func countableRange<SearchType: StringProtocol>(
of search: SearchType,
options: String.CompareOptions = [],
range: Range<String.Index>? = nil,
locale: Locale? = nil
) -> CountableRange<Int>? {
guard let trueRange = self.range(of: search, options: options, range: range, locale: locale) else {
return nil
}
let intStart = self.distance(from: startIndex, to: trueRange.lowerBound)
let intEnd = self.distance(from: trueRange.lowerBound, to: trueRange.upperBound) + intStart
return Range(uncheckedBounds: (lower: intStart, upper: intEnd))
}
}
Esteja ciente de que isso pode causar estranheza, e é por isso que a Apple optou por tornar isso difícil. (Embora seja uma decisão de design discutível - esconder uma coisa perigosa apenas tornando-a difícil ...)
Você pode ler mais na documentação do String da Apple , mas o tldr é que decorre do fato de que esses "índices" são, na verdade, específicos de implementação. Eles representam os índices na string após ela ter sido processada pelo sistema operacional e, portanto, podem mudar de sistema operacional para sistema operacional, dependendo de qual versão da especificação Unicode está sendo usada. Isso significa que acessar valores por índice não é mais uma operação de tempo constante, porque a especificação UTF deve ser executada sobre os dados para determinar o local correto na string. Esses índices também não se alinham com os valores gerados por NSString, se você fizer uma ponte para ele, ou com os índices nos escalares UTF subjacentes. Aviso ao desenvolvedor.