問題
("Optional("10,00 €")") is not equal to ("Optional("10,00 €")"
とか言われてXCTAssertEqualがコケる。
調査
- Optionalとか
- 文字列型のポインタを比較してEqualじゃないよとか
- そういうのを予想してたけど、どうやら違う
- printしてみた出力をアサーションに使うとテストがパスする
- 文字コードか?ということで、Swiftで文字列→byte列の情報を漁る
原因
NSNumberFormatter
の.CurrencyStyle
で出力された10,00 €
のbyte列
[UInt8]("10,00 €".utf8) [49, 48, 44, 48, 48, 194, 160, 226, 130, 172]
一方、キーボードから入力した 10,00 €
のbyte列
[UInt8]("10,00 €".utf8) [49, 48, 44, 48, 48, 32, 226, 130, 172]
[49, 48, 44, 48, 48]
の部分は10,00
だと思われ、[226, 130, 172]
も共通なのできっと€
だと思うので、それをPlaygroundで以下のように確認
String(bytes: [194, 160], encoding: NSUTF8StringEncoding)// " " String(bytes: [32], encoding: NSUTF8StringEncoding)// " " String(bytes: [226, 130, 172], encoding: NSUTF8StringEncoding)// "€"
ということで、結論としては、
- キーボード入力のスペースは
[32]
- 一方
NSNumberFormatter
が吐いたスペースは[194, 160]
32は分かるんだけど、194,160って何の仕様だろうか
解決
とりあえずだけど、print
でNSUTF8StringEncoding
の出力をコピペしてテストコードに貼った。
雑感
- でも型があるの本当に気持ちいいです
- 8月第2週第3週は帰ります。おもにコミケのために。
追記
@otiai10 c2a0はnbspです。この罠おそろしい・・
— しゃある (@sharlm) 2016年7月29日
-   は半角スペースではないというお話 (フェンリル | デベロッパーズブログ)
- 文字列中の (C2A0) を正規表現で削除 - Qiita
- ソースコード中に0xC2A0(UTF-8のNO-BREAK SPACE)が混ざり実行できなくて困った話 - kk_Atakaの日記
- html - Problems with UTF-8 representation of nbsp in XML - Stack Overflow
- List of Unicode characters - Wikipedia, the free encyclopedia
- HTML Codes - Table of ascii characters and symbols
だいぶややこしそうだ... アプリケーションレイヤーに返す前にreplaceしといたほうがよさそうだと思った。あるいはNSNumberFormatterにそういうプロパティ無いか探してみる// TODO
DRYな備忘録として