first commit

This commit is contained in:
2026-01-11 16:21:23 +03:00
commit a92b0d2081
3 changed files with 385 additions and 0 deletions

173
macOS_Development_Rules.md Normal file
View File

@@ -0,0 +1,173 @@
# 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?