Skip to content

Instantly share code, notes, and snippets.

@sanekgusev
Created August 29, 2016 20:27
Show Gist options
  • Save sanekgusev/1fc00c66b6333044dffcb4a69416054e to your computer and use it in GitHub Desktop.
Save sanekgusev/1fc00c66b6333044dffcb4a69416054e to your computer and use it in GitHub Desktop.
Convert an NSRange in NSString into a Range<String.Index>
//: Convert an NSRange from NSString into a Range<String.Index>
import Foundation
let swiftString: String = "🤖 This is an über-👍 string"
let swiftStringCharCount = swiftString.characters.count
let nsString = (swiftString as NSString).decomposedStringWithCanonicalMapping as NSString
let nsStringLength = nsString.length
let invalidNsRange: NSRange = NSMakeRange(1, 2)
let validNsRange: NSRange = NSMakeRange(20, 2)
let invalidNsSubstring: NSString = nsString.substring(with: invalidNsRange) as NSString
let validNsSubstring: NSString = nsString.substring(with: validNsRange) as NSString
func characterRangeFrom(nsRange: NSRange, nsString: NSString) -> Range<String.Index>? {
let swiftString: String = nsString.precomposedStringWithCanonicalMapping as String
var lowerBound: String.Index? = nil
var upperBound = swiftString.startIndex
var lowerBoundValid = false
var upperBoundValid = false
nsString.enumerateSubstrings(in: NSRange(location: 0, length: nsRange.location + nsRange.length),
options: .byComposedCharacterSequences) { (substring, substringRange, enclosingRange, stop) in
if substringRange.location <= nsRange.location {
lowerBound = lowerBound == nil ? swiftString.startIndex : swiftString.index(after: lowerBound!)
if substringRange.location == nsRange.location {
lowerBoundValid = true
}
}
if substringRange.location + substringRange.length <= nsRange.location + nsRange.length {
upperBound = swiftString.index(after: upperBound)
if substringRange.location + substringRange.length == nsRange.location + nsRange.length {
upperBoundValid = true
}
}
}
guard lowerBoundValid && upperBoundValid else {
return nil
}
return Range(uncheckedBounds: (lowerBound!, upperBound))
}
if let validRange = characterRangeFrom(nsRange: validNsRange, nsString: nsString) {
let validSubstring = swiftString[validRange]
}
if let invalidRange = characterRangeFrom(nsRange: invalidNsRange, nsString: nsString) {
let invalidSubstring = swiftString[invalidRange]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment