### Added - **New Skill**: iOS-APP-developer v1.1.0 - iOS development with XcodeGen, SwiftUI, and SPM - XcodeGen project.yml configuration - SPM dependency resolution - Device deployment and code signing - Camera/AVFoundation debugging - iOS version compatibility handling - Library not loaded @rpath framework error fixes - State machine testing patterns for @MainActor classes - Bundled references: xcodegen-full.md, camera-avfoundation.md, swiftui-compatibility.md, testing-mainactor.md - **New Skill**: promptfoo-evaluation v1.0.0 - LLM evaluation framework using Promptfoo - Promptfoo configuration (promptfooconfig.yaml) - Python custom assertions - llm-rubric for LLM-as-judge evaluations - Few-shot example management - Model comparison and prompt testing - Bundled reference: promptfoo_api.md ### Changed - Updated marketplace version from 1.16.0 to 1.18.0 - Updated marketplace skills count from 23 to 25 - Updated skill-creator to v1.2.2: - Fixed best practices documentation URL (platform.claude.com) - Enhanced quick_validate.py to exclude file:// prefixed paths from validation - Updated marketplace.json metadata description to include new skills 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
3.6 KiB
3.6 KiB
SwiftUI iOS Version Compatibility
iOS 17 vs iOS 16 API Differences
View Modifiers
onChange
// iOS 17+ (dual parameter)
.onChange(of: value) { oldValue, newValue in
// Can compare old and new
}
// iOS 16 (single parameter)
.onChange(of: value) { newValue in
// Only new value available
}
sensoryFeedback (iOS 17+)
// iOS 17+
.sensoryFeedback(.impact, trigger: triggerValue)
// iOS 16 fallback
UIImpactFeedbackGenerator(style: .medium).impactOccurred()
Views
ContentUnavailableView (iOS 17+)
// iOS 17+
ContentUnavailableView(
"No Results",
systemImage: "magnifyingglass",
description: Text("Try a different search")
)
// iOS 16 fallback
VStack(spacing: 16) {
Image(systemName: "magnifyingglass")
.font(.system(size: 48))
.foregroundStyle(.secondary)
Text("No Results")
.font(.title2.bold())
Text("Try a different search")
.font(.subheadline)
.foregroundStyle(.secondary)
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
Inspector (iOS 17+)
// iOS 17+
.inspector(isPresented: $showInspector) {
InspectorContent()
}
// iOS 16 fallback: Use sheet or sidebar
.sheet(isPresented: $showInspector) {
InspectorContent()
}
Observation
@Observable Macro (iOS 17+)
// iOS 17+ with @Observable
@Observable
class ViewModel {
var count = 0
}
struct ContentView: View {
var viewModel = ViewModel()
var body: some View {
Text("\(viewModel.count)")
}
}
// iOS 16 with ObservableObject
class ViewModel: ObservableObject {
@Published var count = 0
}
struct ContentView: View {
@StateObject var viewModel = ViewModel()
var body: some View {
Text("\(viewModel.count)")
}
}
Audio
AVAudioApplication (iOS 17+)
// iOS 17+
let permission = AVAudioApplication.shared.recordPermission
AVAudioApplication.requestRecordPermission { granted in }
// iOS 16
let permission = AVAudioSession.sharedInstance().recordPermission
AVAudioSession.sharedInstance().requestRecordPermission { granted in }
Animations
Symbol Effects (iOS 17+)
// iOS 17+
Image(systemName: "heart.fill")
.symbolEffect(.bounce, value: isFavorite)
// iOS 16 fallback
Image(systemName: "heart.fill")
.scaleEffect(isFavorite ? 1.2 : 1.0)
.animation(.spring(), value: isFavorite)
Data
SwiftData (iOS 17+)
// iOS 17+ with SwiftData
@Model
class Item {
var name: String
var timestamp: Date
}
// iOS 16: Use CoreData or third-party (Realm)
// CoreData: NSManagedObject subclass
// Realm: Object subclass with @Persisted properties
Conditional Compilation
For features that must use iOS 17 APIs when available:
if #available(iOS 17.0, *) {
ContentUnavailableView("Title", systemImage: "icon")
} else {
LegacyEmptyView()
}
For view modifiers:
extension View {
@ViewBuilder
func onChangeCompat<V: Equatable>(of value: V, perform: @escaping (V) -> Void) -> some View {
if #available(iOS 17.0, *) {
self.onChange(of: value) { _, newValue in
perform(newValue)
}
} else {
self.onChange(of: value, perform: perform)
}
}
}
Minimum Deployment Targets by Feature
| Feature | Minimum iOS |
|---|---|
| SwiftUI basics | 13.0 |
| @StateObject | 14.0 |
| AsyncImage | 15.0 |
| .searchable | 15.0 |
| NavigationStack | 16.0 |
| .navigationDestination | 16.0 |
| @Observable | 17.0 |
| ContentUnavailableView | 17.0 |
| SwiftData | 17.0 |
| .onChange (dual param) | 17.0 |