SwiftUI vs UIKit
Appleのモダンな宣言的フレームワークSwiftUIと、実戦で鍛えられたUIKitを徹底比較。2025年、どちらのフレームワークを選ぶべきか?
20年の成熟を誇る、Appleの実戦で鍛えられた永続化フレームワーク
WWDC 2023発表: Swiftネイティブ、@Modelマクロによるゼロボイラープレートの永続化
| カテゴリー | Core Data | SwiftData |
|---|---|---|
| パフォーマンス | 9/10 | 9/10 |
| 学習のしやすさ | 4/10 | 9/10 |
| エコシステム | 9/10 | 6/10 |
| コミュニティ | 9/10 | 5/10 |
| 求人市場 | 8/10 | 6/10 |
| 将来性 | 6/10 | 10/10 |
// Core Data - TodoリストのCRUD
import CoreData
import SwiftUI
// NSManagedObjectのサブクラス
@objc(TodoItem)
class TodoItem: NSManagedObject {
@NSManaged var id: UUID
@NSManaged var title: String
@NSManaged var isCompleted: Bool
@NSManaged var createdAt: Date
}
// ビューモデル
class TodoViewModel: ObservableObject {
let container: NSPersistentContainer
@Published var todos: [TodoItem] = []
init() {
container = NSPersistentContainer(name: "TodoModel")
container.loadPersistentStores { _, error in
if let error { fatalError("Core Data load failed: \(error)") }
}
fetchTodos()
}
func fetchTodos() {
let request = NSFetchRequest<TodoItem>(entityName: "TodoItem")
request.sortDescriptors = [NSSortDescriptor(key: "createdAt", ascending: false)]
do {
todos = try container.viewContext.fetch(request)
} catch {
print("Fetch error: \(error)")
}
}
func addTodo(title: String) {
let todo = TodoItem(context: container.viewContext)
todo.id = UUID()
todo.title = title
todo.isCompleted = false
todo.createdAt = Date()
saveContext()
}
func toggleTodo(_ todo: TodoItem) {
todo.isCompleted.toggle()
saveContext()
}
private func saveContext() {
try? container.viewContext.save()
fetchTodos()
}
}// SwiftData - TodoリストのCRUD
import SwiftData
import SwiftUI
// @Modelマクロ — ボイラープレートなし!
@Model
class TodoItem {
var id: UUID
var title: String
var isCompleted: Bool
var createdAt: Date
init(title: String) {
self.id = UUID()
self.title = title
self.isCompleted = false
self.createdAt = Date()
}
}
// SwiftUI View — @Queryによる自動更新
struct TodoListView: View {
@Environment(\.modelContext) private var context
@Query(sort: \.createdAt, order: .reverse) private var todos: [TodoItem]
@State private var newTitle = ""
var body: some View {
List {
ForEach(todos) { todo in
HStack {
Image(systemName: todo.isCompleted ? "checkmark.circle.fill" : "circle")
.foregroundStyle(todo.isCompleted ? .green : .gray)
.onTapGesture { todo.isCompleted.toggle() }
Text(todo.title)
.strikethrough(todo.isCompleted)
}
}
.onDelete { indexSet in
indexSet.forEach { context.delete(todos[$0]) }
}
}
.toolbar {
TextField("新しいTodo...", text: $newTitle)
Button("追加") {
guard !newTitle.isEmpty else { return }
context.insert(TodoItem(title: newTitle))
newTitle = ""
}
}
}
}iOS 17+をターゲットにするならSwiftDataから始めましょう — コード量が少なく、エラーが起きにくく、SwiftUIとの統合も優れています。古いデバイスのサポート、複雑なマイグレーション、あるいは大規模なプロダクションのCore Data基盤がある場合はCore Dataを選びましょう。両者は同じ基盤を共有しているため、理論上は併用も可能です。
無料相談を受ける長期的にはそうなるでしょう、Appleの投資の方向性がそちらを向いています。しかしCore Dataが廃止されるまでには何年もかかります — 既存のCore Dataプロジェクトは引き続きサポートされます。