スキル一覧に戻る
ronaldeddings

swift-ios-macos-expert

by ronaldeddings

VRAM is my life OS FS

0🍴 0📅 2026年1月18日
GitHubで見るManusで実行

SKILL.md


name: swift-ios-macos-expert description: Expert iOS/macOS development with Swift 6, SwiftUI, SwiftData, CloudKit, and modern Apple frameworks. Use when writing Swift code, building iOS/macOS apps, implementing SwiftData models, creating SwiftUI views, handling concurrency, or working with Apple platform APIs. Covers cross-platform patterns, testing, and Xcode workflows.

Swift iOS/macOS Expert

Expert-level guidance for modern Apple platform development targeting iOS 18+/macOS 15+ with Swift 6.

Cross-Platform First

Critical Rule: All features MUST work identically on iOS and macOS. Prefer horizontalSizeClass over #if os().

@Environment(\.horizontalSizeClass) var sizeClass

var body: some View {
    if sizeClass == .compact {
        // iPhone/compact layout
    } else {
        // iPad/Mac/regular layout
    }
}

SwiftData Models

Basic Model Definition

@Model
final class Task {
    @Attribute(.unique) var id: UUID
    var title: String
    @Attribute(.spotlight) var content: String  // CoreSpotlight searchable
    var dueDate: Date?

    @Relationship(deleteRule: .nullify, inverse: \Project.tasks)
    var project: Project?

    init(title: String) {
        self.id = UUID()
        self.title = title
    }
}

Relationship Patterns

Delete RuleBehaviorUse Case
.cascadeDeletes related objectsParent → children
.nullifySets relationship to nilOptional refs
.denyPrevents deletionProtect integrity

Bidirectional: Set one side, SwiftData updates inverse automatically.

Query Patterns

// Basic query with sorting
@Query(sort: \.dueDate) var tasks: [Task]

// Dynamic filtering
init(searchText: String) {
    let predicate = #Predicate<Task> { task in
        searchText.isEmpty || task.title.localizedStandardContains(searchText)
    }
    _tasks = Query(filter: predicate, sort: \.dueDate)
}

Container Setup

@main
struct App: App {
    var body: some Scene {
        WindowGroup { ContentView() }
            .modelContainer(for: [Organization.self, Project.self, Task.self])
    }
}

// CloudKit sync
let config = ModelConfiguration(
    cloudKitDatabase: .private("iCloud.com.hackervalley.RonOS")
)

For advanced patterns: See SWIFTDATA.md

SwiftUI Patterns

NavigationSplitView {
    Sidebar()          // Column 1
} content: {
    ContentList()      // Column 2
} detail: {
    DetailView()       // Column 3
}

@Bindable for Model Editing

struct TaskDetail: View {
    @Bindable var task: Task

    var body: some View {
        Form {
            TextField("Title", text: $task.title)
            DatePicker("Due", selection: $task.dueDate)
        }
    }
}

Sheet Pattern

@State private var newTask: Task?

var body: some View {
    List { /* ... */ }
        .sheet(item: $newTask) { task in
            NavigationStack {
                TaskDetail(task: task, isNew: true)
                    .interactiveDismissDisabled()
            }
        }
}

For view patterns: See SWIFTUI.md

Swift 6 Concurrency

@MainActor Pattern

@MainActor
@Observable
final class AppState {
    var selectedDomain: Domain = .personal
    var isLoading = false
}

ModelActor for Background Work

@ModelActor
actor DataService {
    func fetchTasks() async throws -> [Task] {
        let descriptor = FetchDescriptor<Task>(
            predicate: #Predicate { !$0.completed }
        )
        return try modelContext.fetch(descriptor)
    }
}

Sendable Requirements

// Make models Sendable-safe
@Model
final class Task: @unchecked Sendable {
    // SwiftData models are implicitly Sendable when used correctly
}

For concurrency details: See CONCURRENCY.md

Service Layer Patterns

EventKit (iOS 17+)

let store = EKEventStore()

// Full access (read/write)
try await store.requestFullAccessToEvents()

// Write-only (calendar creation)
try await store.requestWriteOnlyAccessToEvents()

Contacts (iOS 18+)

let store = CNContactStore()

switch CNContactStore.authorizationStatus(for: .contacts) {
case .limited:
    // User selected specific contacts only
case .authorized:
    // Full access
case .denied, .notDetermined, .restricted:
    try await store.requestAccess(for: .contacts)
}

UserNotifications

let center = UNUserNotificationCenter.current()
let settings = await center.notificationSettings()

if settings.authorizationStatus == .notDetermined {
    try await center.requestAuthorization(options: [.alert, .badge, .sound])
}

Testing (Swift Testing)

Basic Test

import Testing

@Test func taskCreation() {
    let task = Task(title: "Test")
    #expect(task.title == "Test")
    #expect(task.id != UUID())
}

Parameterized Tests

@Test(arguments: ["", "  ", "\t"])
func emptyTitleValidation(title: String) {
    let task = Task(title: title)
    #expect(task.isValid == false)
}

Async Testing

@Test func asyncDataFetch() async throws {
    let service = DataService(modelContainer: testContainer)
    let tasks = try await service.fetchTasks()
    #expect(tasks.isEmpty)
}

SwiftData Test Setup

@MainActor
@Test func testWithSwiftData() throws {
    let config = ModelConfiguration(isStoredInMemoryOnly: true)
    let container = try ModelContainer(for: Task.self, configurations: [config])
    let context = container.mainContext

    let task = Task(title: "Test")
    context.insert(task)

    #expect(try context.fetch(FetchDescriptor<Task>()).count == 1)
}

For testing patterns: See TESTING.md

Xcode Build Commands

# macOS build
xcodebuild -scheme RonOS -destination 'platform=macOS'

# iOS Simulator
xcodebuild -scheme RonOS -destination 'platform=iOS Simulator,name=iPhone 16'

# Swift Package
swift build && swift test

# SwiftLint
swift package plugin --allow-writing-to-package-directory swiftlint

Key Conventions

  1. Swift 6 strict concurrency: @MainActor, Sendable, @ModelActor
  2. Use @Query for data fetching, not manual state
  3. Use @Bindable for model editing in detail views
  4. In-memory containers for previews and tests
  5. Test on BOTH iOS Simulator AND macOS before complete
  6. Prefer horizontalSizeClass over #if os() for layouts

Project Identifiers

Bundle ID:    com.hackervalley.RonOS
CloudKit:     iCloud.com.hackervalley.RonOS
App Group:    group.com.hackervalley.RonOS

Reference Documentation

Local docs in this project:

  • SwiftData: DeveloperDocs/SwiftData/
  • SwiftUI: DeveloperDocs/SwiftUI/
  • CloudKit: DeveloperDocs/CloudKit/
  • Testing: DeveloperDocs/Testing/
  • Tutorials: DeveloperTutorials/

スコア

総合スコア

40/100

リポジトリの品質指標に基づく評価

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

0/10
説明文

100文字以上の説明がある

0/10
人気

GitHub Stars 100以上

0/15
最近の活動

3ヶ月以内に更新がある

0/10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

0/5

レビュー

💬

レビュー機能は近日公開予定です