Usando el range <Index> con NSRange en la API NSAttributedString

Estoy intentando determinar los índices de ocurrencias de una cadena dada en una String , luego generar un NSRange usando esos índices para agregar attributes a una NSMutableAttributedString . El problema es rangeOfString devuelve Range<Index> pero addAttributes:range: espera un NSRange . Mis bashs de crear un NSRange desde los índices de inicio y fin del Range han fallado, porque String.CharacterView.Index no es un Int , por lo tanto, no se comstackrá.

¿Cómo se puede usar valores Range<Index> para crear un NSRange ?

 var originalString = "Hello {world} and those who inhabit it." let firstBraceIndex = originalString.rangeOfString("{") //Range<Index> let firstClosingBraceIndex = originalString.rangeOfString("}") let range = NSMakeRange(firstBraceIndex.startIndex, firstClosingBraceIndex.endIndex) //compile time error: cannot convert value of type Index to expected argument type Int let attributedString = NSMutableAttributedString(string: originalString) attributedString.addAttributes([NSFontAttributeName: boldFont], range: range) 

Si comienzas con tu cadena original como un Cocoa NSString:

 var originalString = "Hello {world} and those who inhabit it." as NSString 

… entonces los resultados de su range serán NSRange y podrá devolverlos a Cocoa.

Para hacer un NSRange necesitas get la location inicial y la longitud del range como ints. Puede hacer esto usando la distance(from:to:) método en su originalString :

 let rangeStartIndex = firstBraceIndex!.lowerBound let rangeEndIndex = firstClosingBraceIndex!.upperBound let start = originalString.distance(from: originalString.startIndex, to: rangeStartIndex) let length = originalString.distance(from: rangeStartIndex, to: rangeEndIndex) let nsRange = NSMakeRange(start, length) let attributedString = NSMutableAttributedString(string: originalString) attributedString.addAttributes([NSFontAttributeName: boldFont], range: nsRange) 

Para get la location inicial, obtenga la distancia desde el índice de inicio original de la cadena, hasta el índice de inicio del range que desee (que en su caso sería el primer firstBraceIndex.lowerBound si desea include el { , o primer firstBraceIndex.upperBound si lo hace 't). Luego, para get la longitud de su range, obtenga la distancia desde el índice inicial de su range hasta su índice final.

Acabo de forzar firstBraceIndex su firstBraceIndex y firstClosingBraceIndex para que el código sea más fácil de leer, pero, por supuesto, sería mejor lidiar adecuadamente con estos potencialmente ser nulos.