Last active
May 3, 2016 22:31
-
-
Save acchou/cdfb86f61f9c36de1165cd3f53be4bff to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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.") | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.