So my Character.isMemberOfSet() is a poor general-purpose method, and I need to ditch it.
I like your code. I had to modify it a bit so it wouldn’t fall on strings composed entirely of whitespace: let testString = " \n\n \t\t" let attrStr = NSAttributedString( string:testString ) let str = attrStr.string as NSString let notWhitespace = NSCharacterSet.whitespaceAndNewlineCharacterSet().invertedSet var resultRange:NSRange let startRange = str.rangeOfCharacterFromSet( notWhitespace, options:NSStringCompareOptions.allZeros ) if startRange.length > 0 { let endRange = str.rangeOfCharacterFromSet( notWhitespace, options:NSStringCompareOptions.BackwardsSearch ) let startIndex = startRange.location let endIndex = endRange.location + endRange.length resultRange = NSRange( location:startIndex, length:endIndex - startIndex ) } else { // String is empty or all whitespace resultRange = NSRange( location:0, length:0 ) } let resultStr = attrStr.attributedSubstringFromRange( resultRange ) So, even though attrStr.string returns an NSString, you have use the “as” to explicitly keep the type and be able to do math on range indexes. Lacking that cast is what made rangeOfCharacterFromSet() useless to me yesterday. Your code seems way better. but is there a way in the playground for use to test addresses to make sure attrStr.string as NSString doesn’t perform a copy? — Charles On April 3, 2015 at 2:04:01 PM, Quincey Morris (quinceymor...@rivergatesoftware.com) wrote: On Apr 3, 2015, at 04:00 , Charles Jenkins <cejw...@gmail.com> wrote: for char in String( self ).utf16 { if set.characterIsMember( char ) { return true } Now we’re back to the place we started. This code is wrong. It fails for any code point that isn’t representable a single UTF-16 code value, and it fails for any grapheme that isn’t representable as a single code point. This is what I would do (playground version): import Cocoa let notWhitespace = NSCharacterSet.whitespaceAndNewlineCharacterSet().invertedSet let attrStr = NSAttributedString( string:" Fourscore and seven years ago... \n\n \t\t" ) let str = attrStr.string as NSString let startRange = str.rangeOfCharacterFromSet(notWhitespace, options: NSStringCompareOptions.allZeros) let endRange = str.rangeOfCharacterFromSet(notWhitespace, options: NSStringCompareOptions.BackwardsSearch) let startIndex = startRange.length != 0 ? startRange.location : 0 let endIndex = endRange.length != 0 ? endRange.location + 1 : str.length let resultRange = NSRange (location: startIndex, length: endIndex - startIndex) let resultStr = attrStr.attributedSubstringFromRange (resultRange) It’s the Obj-C code, just written in Swift. The ‘as NSString’ in the 3rd line makes it work. The practical difficulty in your original approach is that (e.g.) String.rangeOfCharacterFromSet returns a Range<String.Index>, but AFAICT that isn’t convertible back to a NSRange, or even just integer indexes. At the same time, AFAICT it isn’t useful with a String because it doesn’t contain Character indexes, just unichar indexes, which have no meaning for a String in general. Actually, my testing is with Swift 1.1, since I’m not in a position to move to Xcode 6.3 yet. It’s possible that the results are different in Swift 1.2. However, in the section of the release notes that talks about bridging between String and NSString, it says: Note that these Cocoa types in Objective-C headers are still automatically bridged to their corresponding Swift type so I suspect the results would be the same in 1.2. It seems to me there is an actual bug here: “String methods corresponding to NSString methods that return NSRange values actually return Range<String.Index> values, but these are not valid ranges, either for String objects (they represent UTF-16 code value positions, not Character positions) or for NSString objects (they’re not convertible back to NSRange). The String methods ought to return NSRange values just like their NSString counterparts.” _______________________________________________ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com