こんにちは
SwiftでiOSアプリを作っています。
Intとして持っている価格を表す変数 price
を、
- 0なら
無料
と表示 - それ以外なら3桁ごとにカンマで区切って
-
¥
マークを先頭につけてStringとして返す
関数を作りましたが、これが複数のモデルにおいて必要になったので
今回はこれをプロトコル指向でまとめた PriceFormattable
を紹介します
TL; DR
プロトコル側
PriceFormattable.swift
import Foundation
protocol PriceFormattable {
var price: Int? { get set }
func priceString() -> String?
}
extension PriceFormattable {
func priceString() -> String? {
guard let price = price else {
return nil
}
guard price != 0 else {
return "無料"
}
let numberFormatter = NumberFormatter()
numberFormatter.numberStyle = NumberFormatter.Style.decimal
guard let formattedPriceString = numberFormatter.string(from: NSNumber(value: price)) else {
return ""
}
return "¥\(formattedPriceString)"
}
}
構造体側
Item.swift
import Foundation
struct Item: PriceFormattable {
var name: String?
var price: Int?
}
やってること
プロトコル側
PriceFormattable.swift
protocol PriceFormattable {
var price: Int? { get set }
func priceString() -> String?
}
PriceFormattable
を採用するクラスや構造体は、 price
を持っていることを必須とします。
priceString()
関数を生やします。
PriceFormattable.swift
extension PriceFormattable {
func priceString() -> String? {
guard let price = price else {
return nil
}
guard price != 0 else {
return "無料"
}
let numberFormatter = NumberFormatter()
numberFormatter.numberStyle = NumberFormatter.Style.decimal
guard let formattedPriceString = numberFormatter.string(from: NSNumber(value: price)) else {
return ""
}
return "¥\(formattedPriceString)"
}
}
すぐ下に Protocol Extension を書きます。中身は地味なので割愛します
これで price
変数を持って PriceFormattable
を採用するだけで priceString()
関数が使えるようになります。
実装側
Item.swift
struct Item: PriceFormattable {
...
}
PriceFormattable
プロトコルを採用します。これで
なんとかViewController.swift
var item = Item()
item.price = 100
print(item.priceString()) // => "¥ 100"
とかいうことができるようになります。