-
-
Save hebertialmeida/d868bd58efe8b5240e4ef8b542107099 to your computer and use it in GitHub Desktop.
import Foundation | |
struct WeightRange { | |
let range: ClosedRange<UInt32> | |
let weight: Int | |
} | |
struct TwitterText { | |
static func lengthOf(tweet: String) -> Int { | |
let defaultWeight = 200 | |
let scale = 100 | |
let ranges = [ | |
WeightRange(range: 0...4351, weight: 100), | |
WeightRange(range: 8192...8205, weight: 100), | |
WeightRange(range: 8208...8223, weight: 100), | |
WeightRange(range: 8242...8247, weight: 100) | |
] | |
let (cleanText, urlLength) = cleanAndCountURLs(text: tweet) | |
var weightedLength = urlLength * scale | |
for char in cleanText.unicodeScalars { | |
var weight = defaultWeight | |
for item in ranges where item.range ~= char.value { | |
weight = item.weight | |
continue | |
} | |
weightedLength += weight | |
} | |
weightedLength /= scale | |
return weightedLength | |
} | |
private static func cleanAndCountURLs(text: String) -> (String, Int) { | |
var output = text | |
var lenght = 0 | |
let detector = try! NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue) | |
let matches = detector.matches(in: text, options: [], range: NSRange(location: 0, length: text.utf16.count)) | |
matches.forEach { | |
output = (text as NSString).replacingCharacters(in: $0.range, with: "") | |
lenght += 23 | |
} | |
return (output, lenght) | |
} | |
} |
@hebertialmeida this was super helpful thanks a lot. There is one tiny issue though, NSDataDetector
fails to handle some short URLs for example url like es.pn returns a length of 5 where as the twitter app correctly calculates it as 23. I have faced this issue and I am not sure how to go about solving this.
I see this note in the Objective C library for URL-
IFUnicodeURL is a category for NSURL which will allow it to support Internationalized domain names in URLs.
This uses code from IDN SDK from Verisign, Inc. The entire IDN SDK source package is included in IDNSDK-1.1.0.zip. I have pulled out and slightly modified (to avoid compiler and analyzer warnings) the files and headers needed so that building this in XCode is as easy as adding the IFUnicodeURL folder to your project.
Sample: