Last active
September 15, 2021 01:59
-
-
Save mono0926/55093ffa124614b2d4b84b3eac9548a4 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
| // こういう相互変換が正しそう | |
| extension String { | |
| func nsRange(from range: Range<String.Index>) -> NSRange { | |
| let from = range.lowerBound.samePosition(in: utf16) | |
| let to = range.upperBound.samePosition(in: utf16) | |
| return NSRange(location: utf16.distance(from: utf16.startIndex, to: from), | |
| length: utf16.distance(from: from, to: to)) | |
| } | |
| func range(from nsRange: NSRange) -> Range<String.Index>? { | |
| guard | |
| let from16 = utf16.index(utf16.startIndex, offsetBy: nsRange.location, limitedBy: utf16.endIndex), | |
| let to16 = utf16.index(from16, offsetBy: nsRange.length, limitedBy: utf16.endIndex), | |
| let from = String.Index(from16, within: self), | |
| let to = String.Index(to16, within: self) | |
| else { return nil } | |
| return from ..< to | |
| } | |
| } | |
| // 利用例 | |
| let str = "a👿b🇩🇪c" | |
| let r1 = str.range(of: "🇩🇪")! | |
| // → Index(_base: Swift.String.UnicodeScalarView.Index(_position: 4), _countUTF16: 4)..<Index(_base: Swift.String.UnicodeScalarView.Index(_position: 8), _countUTF16: 1) | |
| // (意味的には、「startIndexから3進めたところ..<startIndexから4進めたところ」だが、UTF16でcountされている) | |
| // https://github.com/apple/swift/blob/master/stdlib/public/core/StringCharacterView.swift#L159-L191 | |
| // Range → NSRange: | |
| let n1 = str.nsRange(from: r1) | |
| print((str as NSString).substring(with: n1)) // 🇩🇪 | |
| // コードでNSRangeを生成したが、実際のアプリではUIKitからこういう範囲指定されたNSRangeが渡ってくる | |
| // NSRange → Range<Int> | |
| let r2 = n1.toRange()! // 標準メソッドでの変換は4..<8 となりNG | |
| print(str[sequentialAccess: r2]) // 範囲外でnil (正解は🇩🇪) | |
| // NSRange → 正しく計算したRange<Index> | |
| let r3 = str.range(from: n1)! | |
| print(str[r3]) // 🇩🇪 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment