Release v1.18.0: Add iOS-APP-developer and promptfoo-evaluation skills
### 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>
This commit is contained in:
190
iOS-APP-developer/references/swiftui-compatibility.md
Normal file
190
iOS-APP-developer/references/swiftui-compatibility.md
Normal file
@@ -0,0 +1,190 @@
|
||||
# SwiftUI iOS Version Compatibility
|
||||
|
||||
## iOS 17 vs iOS 16 API Differences
|
||||
|
||||
### View Modifiers
|
||||
|
||||
#### onChange
|
||||
|
||||
```swift
|
||||
// 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+)
|
||||
|
||||
```swift
|
||||
// iOS 17+
|
||||
.sensoryFeedback(.impact, trigger: triggerValue)
|
||||
|
||||
// iOS 16 fallback
|
||||
UIImpactFeedbackGenerator(style: .medium).impactOccurred()
|
||||
```
|
||||
|
||||
### Views
|
||||
|
||||
#### ContentUnavailableView (iOS 17+)
|
||||
|
||||
```swift
|
||||
// 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+)
|
||||
|
||||
```swift
|
||||
// iOS 17+
|
||||
.inspector(isPresented: $showInspector) {
|
||||
InspectorContent()
|
||||
}
|
||||
|
||||
// iOS 16 fallback: Use sheet or sidebar
|
||||
.sheet(isPresented: $showInspector) {
|
||||
InspectorContent()
|
||||
}
|
||||
```
|
||||
|
||||
### Observation
|
||||
|
||||
#### @Observable Macro (iOS 17+)
|
||||
|
||||
```swift
|
||||
// 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+)
|
||||
|
||||
```swift
|
||||
// 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+)
|
||||
|
||||
```swift
|
||||
// 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+)
|
||||
|
||||
```swift
|
||||
// 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:
|
||||
|
||||
```swift
|
||||
if #available(iOS 17.0, *) {
|
||||
ContentUnavailableView("Title", systemImage: "icon")
|
||||
} else {
|
||||
LegacyEmptyView()
|
||||
}
|
||||
```
|
||||
|
||||
For view modifiers:
|
||||
|
||||
```swift
|
||||
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 |
|
||||
Reference in New Issue
Block a user