Skip to content

v1.0.5: Mirror-based Hashable/Equatable with Closure Support

Choose a tag to compare

@no-problem-kyoichi no-problem-kyoichi released this 05 Nov 22:29
· 58 commits to main since this release

🎉 新機能

Mirror-based Hashable/Equatable実装

すべてのプロトコルにenumのassociated values対応を追加しました。クロージャを含む複雑なenumでも、手動でのHashable/Equatable実装が不要になります。

対応プロトコル

  • ✅ FullScreenCoverable - フルスクリーンカバー
  • ✅ Sheetable - シート表示
  • ✅ Routable - 画面遷移
  • ✅ CustomHeightSheetable - カスタム高さシート
  • ✅ Alertable - アラート表示

使用例

// クロージャを含むenumが自動的に動作!
enum AppFullScreenCover: FullScreenCoverable {
    case camera
    case editor(itemId: String)
    case picker(onSelect: (Item) -> Void)  // ← クロージャも対応
    
    var body: some View {
        switch self {
        case .camera: CameraView()
        case .editor(let id): EditorView(itemId: id)
        case .picker(let onSelect): PickerView(onSelect: onSelect)
        }
    }
}

// Hashable実装は完全自動!
let cover1 = AppFullScreenCover.picker { print("Selected A") }
let cover2 = AppFullScreenCover.picker { print("Selected B") }

cover1 == cover2  // true - クロージャは無視されます

🚀 改善

Swift 6並行性対応

すべてのHashable/Equatable実装にnonisolatedを適用し、Swift 6の厳格な並行性チェックに完全対応しました。

  • ✅ Main Actor isolationとの競合を解消
  • ✅ 厳格な並行性チェック(Swift 6)に対応
  • ✅ データ競合の心配なし

ドキュメント充実

各プロトコルに、クロージャを含む使用例と注意書きを追加しました。

🔧 技術詳細

Mirror-based実装の仕組み

Swiftのリフレクション機能を使用して:

  1. enumのcase名で同一性を判定
  2. Hashable型のassociated valueのみを比較・ハッシュ化
  3. クロージャ型はAnyHashableに変換できないため自動除外
  4. 手動実装不要でボイラープレートを削減
// 実装例(自動で提供されます)
nonisolated static func == (lhs: Self, rhs: Self) -> Bool {
    let lhsMirror = Mirror(reflecting: lhs)
    let rhsMirror = Mirror(reflecting: rhs)
    
    // case名の比較
    guard lhsMirror.children.first?.label == rhsMirror.children.first?.label else {
        return false
    }
    
    // Hashable型のvalueのみ比較(クロージャは自動除外)
    let lhsValues = extractHashableValues(from: lhs)
    let rhsValues = extractHashableValues(from: rhs)
    
    return lhsValues == rhsValues
}

✅ 利点

  • 🎯 クロージャ対応: コンパイルエラーなしで柔軟な設計が可能
  • 🔒 型安全性: 静的型チェックを維持
  • ⚡ ボイラープレート削減: 手動実装不要
  • 🚀 Swift 6準拠: 厳格な並行性チェックに対応
  • 📦 後方互換性: 既存コードへの影響なし

📝 変更内容の詳細

追加されたファイル

  • Tests/UIRoutingTests/HashableEquatableTests.swift - 包括的なテストスイート

更新されたファイル

  • Sources/UIRouting/Protocols/FullScreenCoverable.swift
  • Sources/UIRouting/Protocols/Sheetable.swift
  • Sources/UIRouting/Protocols/Routable.swift
  • Sources/UIRouting/Protocols/CustomHeightSheetable.swift
  • Sources/UIRouting/Protocols/Alertable.swift
  • CHANGELOG.md
  • .gitignore

🔗 ドキュメント

オンラインドキュメント: https://no-problem-dev.github.io/swift-ui-routing/documentation/uirouting/


Full Changelog: v1.0.4...v1.0.5