Files
Code-Agents/macOS_Development_Rules.md
2026-01-11 16:21:23 +03:00

173 lines
8.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# RULESET: macOS App Development with SwiftUI (Based on 'macOS by Tutorials')
Bu dosya, "macOS by Tutorials" (Ray Wenderlich / Kodeco) kitabındaki best practice'lere dayanarak yüksek kaliteli, native hissettiren bir macOS uygulaması geliştirmek için gerekli kuralları, mimari desenleri ve kod standartlarını içerir.
**GÖREV:** Bir macOS uygulaması geliştirirken aşağıdaki kurallara kesinlikle uy. iOS alışkanlıklarını (NavigationLink vb.) macOS'e aynen kopyalama. Mac kullanıcılarının beklentilerine (Menü çubuğu, Çoklu Pencere, Klavye Kısayolları) öncelik ver.
---
## 1. TEMEL FELSEFE VE MİMARİ (Core Philosophy)
### iOS Portu Değil, Mac Uygulaması
* **Kural:** Uygulamayı sadece "büyük ekranlı bir iPad uygulaması" gibi tasarlama. Mac kullanıcıları fare/trackpad kullanır, pencereleri boyutlandırır ve klavye kısayollarına bağımlıdır.
* **Kural:** `SFSafariViewController` macOS'te yoktur ve kullanılmamalıdır. Kullanıcıyı tarayıcıya (`Link` veya `NSWorkspace.open`) yönlendirmek Mac kültürüne daha uygundur.
### Uygulama Yaşam Döngüsü (App Lifecycle)
* **Yapı:** `@main` struct'ı `App` protokolüne uymalıdır.
* **WindowGroup:** Ana arayüzü `WindowGroup` içine al. Bu, macOS'in otomatik olarak çoklu pencere (multi-window) ve sekme (tab) desteği sunmasını sağlar.
```swift
@main
struct MyApp: App {
@StateObject var appState = AppState() // Global state
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(appState)
}
.commands {
// Menü komutları buraya
SidebarCommands()
ToolbarCommands()
}
}
}
```
---
## 2. PENCERE YÖNETİMİ (Window Management)
### Pencere Boyutlandırma (Sizing)
* **Kural:** iOS'in aksine, Mac'te pencereler serbestçe boyutlandırılabilir. Ancak mantıklı sınırlar koymalısın.
* **Kod:** `ContentView`'un en dış katmanına `.frame()` modifier ekle.
* `minWidth` / `minHeight`: UI'ın bozulmayacağı en küçük boyut.
* `maxWidth` / `maxHeight`: Genellikle `.infinity` olmalı.
* `idealWidth` / `idealHeight`: Uygulama ilk açıldığında önerilen boyut.
```swift
.frame(minWidth: 700, idealWidth: 1000, maxWidth: .infinity,
minHeight: 400, idealHeight: 800, maxHeight: .infinity)
```
### Pencere Başlıkları (Titles)
* **Kural:** Çoklu pencerelerde her pencerenin içeriğine göre dinamik başlığı olmalıdır.
* **Kod:** `.navigationTitle(_:)` kullan. Eğer sidebar'da bir seçim varsa başlık ona göre değişmeli, yoksa varsayılan uygulama adı görünmelidir.
---
## 3. NAVİGASYON VE SIDEBAR (Navigation)
### NavigationView Yapısı
* **Kural (KRİTİK):** `NavigationLink` kullanma. macOS'te "push" navigasyonu (bir ekranın diğerinin üzerine kayması) nadirdir.
* **Desen:** Sidebar + Detail (Split View) yapısını kullan.
* **Uygulama:** `NavigationView` içine tüm panelleri (Sidebar, Detail) en baştan koy. Görünürlük, bir `@Binding` selection değişkeni ile yönetilir.
```swift
NavigationView {
SidebarView(selection: $selection) // Sol Panel
DetailView(selection: selection) // Sağ Panel
}
```
### Sidebar Tasarımı
* **List Style:** `.listStyle(.sidebar)` kullan. Bu, satırların hafif transparan olmasını ve seçimin sistem rengiyle (AccentColor) vurgulanmasını sağlar.
* **Selection:** `List(selection: $selection)` bağlamasını kullan. `Tag` yapısını `NavigationLink` yerine tercih et.
* **Kategoriler:** Listeyi `Section`'lara böl. Başlıkları büyük harfle yazma (iOS gibi değil), Mac standartlarına uy.
---
## 4. UI BİLEŞENLERİ (UI Components)
### Grid (Izgara) Görünümü
* **Kullanım:** Çok sayıda öğe gösterirken `LazyVGrid` kullan.
* **Sütunlar:** Sabit sütun sayısı yerine `.adaptive(minimum:maximum:)` kullanarak pencere genişletildiğinde sütun sayısının artmasını sağla.
```swift
let columns = [GridItem(.adaptive(minimum: 250, maximum: 250), spacing: 20)]
```
### Table (Tablo) Görünümü (macOS Exclusive)
* **Kural:** Veri yoğunluklu listeler için `List` yerine SwiftUI `Table` görünümünü kullan.
* **Özellikler:** Sıralama (`sortOrder`), Çoklu seçim (`selection: Set<ID>`), ve Sütun genişlikleri (`width(min:ideal:max)`) mutlaka eklenmeli.
* **Alternatif Satır Renkleri:** `Table`, varsayılan olarak satırları alternatif renklerle (zebra stripe) boyar. Bunu koru.
### Kart Tasarımı ve Hover Efektleri
* **Kural:** Mac kullanıcıları "tıklanabilir" alanları anlamak için fare imlecini kullanır.
* **İpucu:** Tıklanabilir alanlarda imleci değiştirmek için `.onHover` ve `NSCursor` kullan.
```swift
.onHover { inside in
inside ? NSCursor.pointingHand.push() : NSCursor.pop()
}
```
* **Bug Fix:** Kartlara gölge (`shadow`) eklerken `.clipped()` kullanmayı unutma, aksi takdirde gölge iç elementlere de uygulanabilir (SwiftUI bug workaround).
---
## 5. MENÜLER (Menus)
### Command Protocol
* **Yapı:** Menüleri `View` dosyalarından ayır ve `Commands` protokolüne uyan ayrı bir dosyada (örn. `Menus.swift`) tut.
* **Hazır Gruplar:** Apple'ın hazır menü gruplarını mutlaka ekle:
* `SidebarCommands()`: View menüsüne "Toggle Sidebar" ekler.
* `ToolbarCommands()`: View menüsüne Toolbar özelleştirme seçeneklerini ekler.
### Özel Menü Öğeleri
* **Yerleşim:** `CommandGroup(before: .help)` veya `CommandGroup(after: .newItem)` gibi yerleşimler kullan.
* **Klavye Kısayolları:** `.keyboardShortcut(_:modifiers:)` ile her önemli aksiyona kısayol ata.
* *Not:* Menülerde kısayollar otomatik olarak büyük harf görünür, ekstra Shift eklemene gerek yoktur.
* **Picker Entegrasyonu:** Ayarlar için (örn. Tema seçimi) menü içine `Picker` koy. Otomatik olarak alt menü (submenu) ve tik işareti (checkmark) oluşturur.
---
## 6. ARAÇ ÇUBUĞU (Toolbar)
### Yapı ve Özelleştirme
* **Kural:** `ToolbarItem` veya `ToolbarItemGroup` kullan.
* **Customizable:** Kullanıcının sağ tıkla toolbar'ı düzenleyebilmesi için toolbar'a ve öğelere `.id()` ver.
```swift
.toolbar(id: "mainToolbar") {
ToolbarItem(id: "refresh", placement: .primaryAction) { ... }
}
```
* **Placement:** * `.navigation`: Sol taraf (Sidebar toggle vb.)
* `.primaryAction`: Sağ taraf (En önemli buton)
* `.automatic`: Sistem karar verir.
### Arama (Search)
* **Kullanım:** `.searchable(text: $searchText)` modifier'ını `NavigationView`'a ekle. Bu, toolbar'a otomatik olarak native bir arama çubuğu yerleştirir.
---
## 7. VERİ VE STATE YÖNETİMİ (Data Persistence)
### Sandboxing & Network
* **Kritik:** macOS uygulamaları varsayılan olarak internete çıkamaz. "Signing & Capabilities" altından **Outgoing Connections (Client)** tikini açmalısın.
### Ayarların Saklanması (Persistence)
* **Global Ayarlar:** Uygulama geneli ayarlar (örn. Tema, "Show Totals") için `@AppStorage` kullan (UserDefaults wrapper).
* **Pencere Bazlı Ayarlar:** Her pencerenin kendi durumunu hatırlaması için (örn. Seçili sekme, Arama metni) `@SceneStorage` kullan.
```swift
@SceneStorage("viewMode") var viewMode: ViewMode = .grid
```
---
## 8. SWIFTUI & APPKIT ENTEGRASYONU
### Ne Zaman AppKit Kullanılmalı?
* SwiftUI'ın yetersiz kaldığı durumlarda (örn. Sidebar'ı kod ile açıp kapatmak, Window odağını değiştirmek, First Responder yönetimi) `NSApp`, `NSWindow` veya `NSCursor`'a erişmekten çekinme.
* **Örnek (Sidebar Toggle):**
```swift
func toggleSidebar() {
NSApp.keyWindow?.firstResponder?.tryToPerform(#selector(NSSplitViewController.toggleSidebar(_:)), with: nil)
}
```
---
## 9. CHECKLIST FOR AGENTS
Bir özellik eklerken şu soruları sor:
1. **Pencere:** Bu özellik yeni bir pencerede açıldığında nasıl davranacak? (`@SceneStorage` kullanıldı mı?)
2. **Menü:** Bu aksiyonun Menü çubuğunda bir karşılığı ve klavye kısayolu var mı?
3. **Mouse:** Hover efektleri var mı? Tıklanabilir alanlar belli mi?
4. **Platform:** Bu bir iOS davranışı mı (örn. Bottom Sheet, Navigation Push)? Eğer öyleyse macOS karşılığını (Sheet, Split View değişimi) kullan.
5. **Boyut:** Pencere küçüldüğünde veya büyüdüğünde (`GridItem.adaptive`, `Table` sütunları) arayüz uyum sağlıyor mu?