Swift Uikit
Cursor-Regel für klassische iOS-Entwicklung mit Swift und UIKit statt SwiftUI.
Cursor-Regel für klassische iOS-Entwicklung mit Swift und UIKit statt SwiftUI.
Original-Beschreibung der Autoren: Cursor rules for Swift Uikit.
Die Regel
---
description: "Cursor rules for Swift Uikit."
globs: **/*
alwaysApply: false
---
# .cursorrules-mvvm-rxswift
# Swift UIKit MVVM + RxSwift Development Rules
You are an expert Swift iOS developer specializing in UIKit with MVVM architecture and RxSwift for reactive programming. Write clean, maintainable, and scalable code following Apple's Human Interface Guidelines and Swift best practices.
## Core Technologies
- **Language**: Swift 5.9+
- **Framework**: UIKit
- **Architecture**: MVVM (Model-View-ViewModel)
- **Reactive Programming**: RxSwift/RxCocoa
- **Dependency Management**: Swift Package Manager or CocoaPods
## Project Structure
MyApp/ ├── App/ │ ├── AppDelegate.swift │ ├── SceneDelegate.swift │ └── Info.plist ├── Models/ │ ├── User.swift │ ├── Product.swift │ └── APIResponse.swift ├── Views/ │ ├── Controllers/ │ │ ├── HomeViewController.swift │ │ ├── ProfileViewController.swift │ │ └── BaseViewController.swift │ ├── Custom/ │ │ ├── CustomButton.swift │ │ ├── CustomTextField.swift │ │ └── LoadingView.swift │ └── Cells/ │ ├── UserTableViewCell.swift │ └── ProductCollectionViewCell.swift ├── ViewModels/ │ ├── HomeViewModel.swift │ ├── ProfileViewModel.swift │ └── BaseViewModel.swift ├── Services/ │ ├── NetworkService.swift │ ├── AuthService.swift │ ├── CacheService.swift │ └── UserDefaultsService.swift ├── Repositories/ │ ├── UserRepository.swift │ └── ProductRepository.swift ├── Utilities/ │ ├── Extensions/ │ ├── Constants/ │ ├── Helpers/ │ └── Coordinators/ └── Resources/ ├── Assets.xcassets ├── Localizable.strings └── Storyboards/
## MVVM Architecture Guidelines
### Model
- Use `Codable` for JSON parsing
- Implement `Equatable` when needed
- Keep models immutable when possible
- Use structs for simple data containers
```swift
struct User: Codable, Equatable {
let id: Int
let name: String
let email: String
let profileImageURL: String?
private enum CodingKeys: String, CodingKey {
case id, name, email
case profileImageURL = "profile_image_url"
}
}
View (UIViewController)
- Keep view controllers lightweight
- Handle only UI-related logic
- Bind to ViewModels using RxSwift
- Use weak references to avoid retain cycles
class HomeViewController: UIViewController {
@IBOutlet weak var tableView: UITableView!
private let viewModel = HomeViewModel()
private let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
setupUI()
bindViewModel()
}
private func bindViewModel() {
viewModel.users
.bind(to: tableView.rx.items(cellIdentifier: "UserCell")) { _, user, cell in
// Configure cell
}
.disposed(by: disposeBag)
viewModel.isLoading
.bind(to: loadingIndicator.rx.isAnimating)
.disposed(by: disposeBag)
}
}
ViewModel
- Use RxSwift subjects for data binding
- Handle business logic and data transformation
- Expose observables for the view to subscribe to
- Implement input/output pattern
class HomeViewModel {
// MARK: - Inputs
let refreshTrigger = PublishSubject<Void>()
let loadMoreTrigger = PublishSubject<Void>()
// MARK: - Outputs
let users: Observable<[User]>
let isLoading: Observable<Bool>
let error: Observable<Error>
private let userRepository: UserRepositoryProtocol
private let disposeBag = DisposeBag()
init(userRepository: UserRepositoryProtocol = UserRepository()) {
self.userRepository = userRepository
// Setup reactive streams
users = refreshTrigger
.startWith(())
.flatMapLatest { [unowned self] in
self.userRepository.getUsers()
.catchErrorJustReturn([])
}
.share(replay: 1)
isLoading = Observable.merge(
refreshTrigger.map { true },
users.map { _ in false }
)
.startWith(false)
error = userRepository.getUsers()
.materialize()
.compactMap { $0.error }
}
}
RxSwift Best Practices
Binding Guidelines
- Always use
disposed(by: disposeBag)to prevent memory leaks - Use
weak selfin closures to avoid retain cycles - Prefer
drive()for UI binding instead ofbind(to:) - Use
share(replay: 1)for expensive operations
Error Handling
userRepository.getUsers()
.observe(on: MainScheduler.instance)
.catch { error in
self.handleError(error)
return Observable.empty()
}
.bind(to: tableView.rx.items)
.disposed(by: disposeBag)
Networking with RxSwift
protocol NetworkServiceProtocol {
func request<T: Codable>(_ endpoint: Endpoint) -> Observable<T>
}
class NetworkService: NetworkServiceProtocol {
func request<T: Codable>(_ endpoint: Endpoint) -> Observable<T> {
return Observable.create { observer in
let task = URLSession.shared.dataTask(with: endpoint.request) { data, response, error in
if let error = error {
observer.onError(error)
return
}
guard let data = data else {
observer.onError(NetworkError.noData)
return
}
do {
let result = try JSONDecoder().decode(T.self, from: data)
observer.onNext(result)
observer.onCompleted()
} catch {
observer.onError(error)
}
}
task.resume()
return Disposables.create {
task.cancel()
}
}
}
}
Code Style Guidelines
… (hier gekürzt — Kopieren/Download liefert die vollständige Regel)
## So nutzt du sie
Die Regel kopieren (Button oben) oder als Datei herunterladen und im Projekt unter `.cursor/rules/` ablegen — Cursor lädt sie beim nächsten Start automatisch. Ältere Cursor-Versionen lesen alternativ eine einzelne `.cursorrules`-Datei im Projektstamm; dort einfach den Regel-Text ohne den Kopfblock zwischen den `---`-Zeilen einfügen.
Der Regel-Text ist englisch — Cursor versteht ihn unabhängig von der Sprache, in der Sie mit dem Editor chatten.
## Im Detail
Cursor-Regel für native iOS-Entwicklung mit Swift und UIKit — also dem klassischen, view-controller-basierten Framework, nicht SwiftUI. Relevant für bestehende UIKit-Codebasen oder Projekte, die aus Kompatibilitäts- oder Teamgründen bei UIKit bleiben. Gibt Konventionen für View-Controller-Struktur, Delegate-Pattern und Auto-Layout-Code vor, damit Cursor keinen SwiftUI-Code vorschlägt, der im Projekt nicht passt. Für neue Projekte ohne Altlasten ist SwiftUI heute meist die modernere Wahl — diese Regel ist gezielt für UIKit-Bestandsprojekte gedacht.
## Praxis-Tipp
Beispiel: „erstelle einen UITableViewController mit Diffable Data Source für eine Kontaktliste“ — Cursor hält sich an UIKit-Idiome statt SwiftUI-Views vorzuschlagen.
## Lizenz & Quelle
- **Lizenz:** CC0 1.0
- **Quelle:** [PatrickJS/awesome-cursorrules (GitHub)](https://github.com/PatrickJS/awesome-cursorrules)
Inhalt ansehen (swift-uikit.mdc)
Lade …
Erfahrungen & Kommentare.
Funktioniert der Regel bei Ihnen? Tipps, Stolperfallen, Varianten — teilen Sie es mit der Community.
Lade Kommentare …
Passt dazu.
AI Agent Specialist
Cursor-Regel, die den KI-Editor auf diszipliniertes, spezialisiertes Agenten-Verhalten trimmt.
Alpha Skills Quant Factor Research
Cursor-Regel für quantitative Faktor-Recherche im Trading/Finance-Bereich — leitet die KI zu methodisch sauberer Analyse an.
Android Jetpack Compose
Cursor-Regel für Android-Entwicklung mit Jetpack Compose — sorgt für idiomatischen, deklarativen Kotlin-UI-Code.
