0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

swift-idを使ってデータクラスの固有型でIDを定義する

Last updated at Posted at 2025-05-08

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)" }
}
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?