Upgrade to Pro — share decks privately, control downloads, hide ads and more …

pixiv App Night 20240523 NumberFormatterのハマり事例

pixiv App Night 20240523 NumberFormatterのハマり事例

数値をテキストとして出力する際、整形に便利なNumberFormatterというクラスがあります。基本的な使い方で済む場合はよいのですが、望むような整形をしようとしてもなかなかうまくできないこともあります。本発表では実際にハマった事例を紹介します。

Avatar for glassfiber

glassfiber

May 23, 2024
Tweet

More Decks by glassfiber

Other Decks in Programming

Transcript

  1. glass fi ber w ৽نࣄۀ෦J04ΤϯδχΞ1BTUFMBͷ։ൃʹैࣄ w ೥݄ೖࣾ w લ৬͸ήʔϜ։ൃऀ 14

    9CPY J04 8JOEPXT  w J04ͷܦݧ͸͔Β͘Β͍·Ͱ J1IPOF(4ʙJ1IPOF  w ೥Ҏ্ͷϒϥϯΫ w J04ܦݧऀͱ͍͏ʹ͸ͪΐͬͱʜͰ͕͢࠾༻ͯ͠΋Β͑ͯ͋Γ͕͍ͨͰ͢
  2. SwiftͰ਺஋Λจࣈྻʹ͢Δํ๏ • NumberFormatterΫϥε • ਺΍௨՟Λ੔ܗͯ͠จࣈྻʹ͢Δ • ΊͪΌͪ͘Όଟػೳ • iOS2ͷࠒ͔Β͋Δ •

    ଞʹ೔࣌΍σʔλαΠζͳͲ֤छFormatter͕͋Δ • FormatStyle API • iOS15Ͱొ৔ • ͜Ε͔Βษڧ͠·͢ ←ࠓճ͸͜ΕΛ࢖͍·ͨ͠
  3. ԾͰද͍ࣔͯͨ͠࠷ॳͷঢ়ଶ • Ծͷදࣔ • ͍Ζ͍Ζؒҧ͍ͬͯΔ • %දهͳͷʹ100ഒ͍ͯ͠ͳ͍ • मਖ਼ •

    100ഒͨ͠஋Λ࢖͍๨ΕΔ • খ਺఺ҎԼ3ܻͰ੾Ζ͏ͱ͍ͯ͠Δ͕ 100ഒͰޡ͕ࠩग़ܻͯ਺͕૿͑Δ let value = floor(storageUsageRate * 1000) / 1000 return "\(value)%" let value = floor(storageUsageRate * 1000) / 1000 let percentValue = value * 100 return "\(value)%"
  4. NumberFormatterΛ࢖͍·͠ΐ͏ • খ਺఺ҎԼͷܻ਺Λࢦఆ • ύʔηϯτදهʹ let formatter = NumberFormatter() formatter.minimumFractionDigits

    = 0 formatter.maximumFractionDigits = 3 formatter.groupingSeparator = "" formatter.numberStyle = .percent return formatter.string(from: NSNumber(value: storageUsageRate)
  5. ৔߹෼͚Ͱখ਺఺ҎԼͷܻ਺Λ੾Γସ͑Δ • ஋͕ • 1%ະຬ • 10ˋະຬ • ͦΕҎ֎ •

    Ͱ෼͚Δ Self.numberFormatter.maximumFractionDigits = switch storageUsageRate { case ..<1: 2 case ..<10: 1 default: 0 } return formatter.string(from: NSNumber(value: storageUsageRate)
  6. ৔߹෼͚Ͱখ਺఺ҎԼͷܻ਺Λ੾Γସ͑Δ • ஋͕ • 1%ະຬ • 10ˋະຬ • ͦΕҎ֎ •

    Ͱ෼͚Δ Self.numberFormatter.maximumFractionDigits = switch storageUsageRate { case ..<0.01: 2 case ..<0.1: 1 default: 0 } return formatter.string(from: NSNumber(value: storageUsageRate) ͦͯ͠·ͨؒҧ͑Δ…
  7. ݟͨ໨͸͍͍ײ͡ʹͳ͚ͬͨͲ… • SwitchͰ৔߹෼͚͢Δͷ͕ͳΜ͔μα͍ • ݁ہͷͱ͜Ζ • ʙ0.99 → ੔਺0ܻɺখ਺2ܻ •

    1.0ʙ9.9 →੔਺1ܻɺখ਺1ܻ • 10ʙ →੔਺2ܻɺখ਺0ܻ • ༗ޮܻ਺2ܻͬͯ͜ͱͰΑͦ͞͏ Self.numberFormatter.maximumFractionDigi case ..<0.01: 2 case ..<0.1: 1 default: 0 } return formatter.string(from: NSNumber(v
  8. NumberFormatterʹ͸ͳΜͰ΋͋Δͳ • maximumSigni fi cantDigits: ༗ޮܻ਺ͷࢦఆ • usesSigni fi cantDigitsΛtrueʹ͢Δඞཁ͕͋Δ

    • ͍͍ײ͡ͳͷͰ͸ formatter.usesSignificantDigits = true formatter.maximumSignificantDigits = 2 formatter.groupingSeparator = "" formatter.numberStyle = .percent return formatter.string(from: NSNumber(value: storageUsageRate)
  9. ͓·͚ • ࢖༻཰ͱಉ࣌ʹ࢖༻ྔɾ࠷େ༰ྔ΋ද͍ࣔͯ͠·͢ • ByteCountFormatStyleΛ࢖͍·ͨ͠ • ҰൃͰ͍͍ײ͡ͷදهʹͳͬͯͱͯ΋ศར static func formatBytes(_

    bytes: Int) -> String { // όΠτදهจࣈྻ return bytes.formatted(ByteCountFormatStyle.byteCount(style: .binary, spellsOutZero: false)) }
  10. ·ͱΊ • ਺஋Λ͍͍ײ͡ʹ੔ܗ͢Δ͚ͩͰҙ֎ʹۤ࿑ͨ͠ • ʮ͍͍ײ͡ʯΛͪΌΜͱఆٛ͠·͠ΐ͏ • ࣗલͰ΍Δͱؒҧ͑Δ • ύʔηϯτͷ100ഒΛ๨ΕͨΓɺܭࢉͨ͠஋Λ࢖͍๨ΕͨΓ •

    NumberFormatter͸ศརʂɹ͚ͩͲ͋·Γʹ΋ଟػೳ • ༗ޮܻ਺ͷࢦఆͱ࠷େܻ਺ͷࢦఆ͸ഉଞͳͷͰɺ࠷େܻ਺Λ੍ݶ͢Δʹ͸޻෉͕ඞཁ • FormatStyle APIΑͦ͞͏ • ςετΛॻ͖·͠ΐ͏ • ҆৺ײ͕ҧ͍·͢