swift-idを使ってデータクラスの固有型でIDを定義する
-
Identifiable
に準拠したデータクラスはIDを持ちますが、例えばこのIDの型をStringすると、複数のデータクラスがあった際にIDを混同して使ってしまう懸念があります - そこでIDをデータクラス固有の型にしたいことがあり、その際はkoher/swift-idのライブラリを使うのが便利です
- ライブラリのREADMEの通りIDを定義して利用できます
struct User: Identifiable, Sendable, Hashable, Codable {
let id: ID
var name: String
// 🙂 Easy to implement!!
struct ID: StringIDProtocol {
let rawValue: String
init(rawValue: String) {
self.rawValue = rawValue
}
}
}
- ここでデータクラスが多い場合に毎回ID型を定義するのが手間なので、下記のようにジェネリクスを使って汎用型を定義すると便利です
import SwiftID
// クラス固有のIDを定義するための汎用型
public struct SwiftID<T>: StringIDProtocol {
public let rawValue: String
public init(rawValue: String) {
self.rawValue = rawValue
}
}
/// GitHubAPIで扱うDTOクラス用のプロトコル(こちらは一例d必須ではないです)
public protocol GitHubItem: Identifiable, Codable, Sendable, Hashable, Equatable {
associatedtype T
var id: SwiftID<T> { get } // 各クラスにユニークな型のIDを定義させる
}
- 利用例としては以下の通りです
public struct MyRepo: GitHubItem {
// MARK: - 検索結果から取得される値
private enum CodingKeys: String, CodingKey {
case rawID = "id"
case name
case owner
case starsCount = "stargazers_count"
}
public let rawID: Int
public var name: String // e.g. "Tetris"
public var owner: User
public var starsCount: Int
// MARK: - Identifiable
/// 固有型のID
public var id: SwiftID<Self> { "\(rawID)" }
}