The NSRange for a full string is NSRange(location: 0, length: (text as NSString).length). You cannot use text.count for this. NSRanges on strings are based on UTF-16 code points, not Swift Characters. A character like πŸ‘©β€πŸ‘©β€πŸ‘§β€πŸ‘§ has a .count of 1, but a .length of 11. ObjC-based NSRange APIs (even ones ported to Swift) need the latter. Swift interfaces (which use Range rather than NSRange) need the former.

Whenever possible, avoid NSRange. But when it’s needed, make sure to use it correctly. It’s very easy to make mistakes that break on non-ASCII, and especially on emoji.

(Side note: (text as NSString).length is the same as text.utf16.count. I don’t have a strong opinion on which to use. In both cases, future developers may get confused and try to β€œfix” the code back to text.count. (text as NSString) is nice because it ties it back to this being an NSString API and is easier IMO to see that something special is happening here, but it also looks like an auto-conversion barnacle. .utf16.count is shorter and calls out what is really happening, but I almost always type .utf8.count out of muscle-memory and it’s hard to see the mistake in code-review. So do what you want. A comment is probably warranted in either case. I hate NSRange in Swift…)