Aquí hay una extensión que le permitirá acceder a los límites de una subcadena como Int
s en lugar de String.Index
valores:
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))
}
}
Solo tenga en cuenta que esto puede generar rarezas, razón por la cual Apple ha optado por hacerlo difícil. (Aunque esa es una decisión de diseño discutible: ocultar algo peligroso simplemente haciéndolo difícil ...)
Puede leer más en la documentación de String de Apple , pero el tldr es que se deriva del hecho de que estos "índices" son en realidad específicos de la implementación. Representan los índices en la cadena después de que el sistema operativo la haya representado, por lo que pueden cambiar de un sistema operativo a otro según la versión de la especificación Unicode que se esté utilizando. Esto significa que acceder a los valores por índice ya no es una operación de tiempo constante, porque la especificación UTF debe ejecutarse sobre los datos para determinar el lugar correcto en la cadena. Estos índices tampoco se alinearán con los valores generados por NSString, si se conecta a él, o con los índices en los escalares UTF subyacentes. Desarrollador de advertencia.