Skip to content

Instantly share code, notes, and snippets.

@acchou
Last active May 3, 2016 22:31
Show Gist options
  • Save acchou/cdfb86f61f9c36de1165cd3f53be4bff to your computer and use it in GitHub Desktop.
Save acchou/cdfb86f61f9c36de1165cd3f53be4bff to your computer and use it in GitHub Desktop.
import Foundation
extension String {
// Return a String prefix with UTF8 representation limited to at most maxBytes. If maxBytes is negative, return the original string.
public func prefixUTF8(maxBytes: Int) -> String {
if maxBytes < 0 {
return self
}
// Select the prefix of the string, leaving behind the remaining bytes.
var prefix = self.utf8.prefix(maxBytes)
/* In UTF-8 there are at most 4 bytes per code point. String.init will return nil if there's an incomplete code point; we remove one byte at a time until we've gotten back to a complete code point. For Strings containing only ASCII, this will never happen because ASCII characters are represented by a single byte in UTF-8, and therefore won't be divided by our call to prefix.
*/
for _ in 1...3 {
if let rv = String(prefix) {
return rv
}
prefix = prefix.dropLast()
}
// If we get here, there's probably a bug in the Swift String implementation.
assert(false, "Unable to truncate string. Possible bug in Swift.")
}
}
@acchou
Copy link
Author

acchou commented May 3, 2016

Certain Apple APIs, such as MCPeerID specify size limits for Strings in UTF-8 representation, but the String class lacks a prefix function that works correctly with unicode code points. This simple String extension provides prefixUTF8 which solves this.

An even better solution would use characters to remove grapheme clusters from the end, but I thought this was sufficient for most purposes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment