Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
## 0.2.2

### 🐛 Bug Fixes
- **Fixed Xcode 27 build failure** ("switch must be exhaustive") in the iOS and macOS plugins. The Xcode 27 SDK adds new cases to the non-frozen Foundation Models enums `Transcript.Entry` (`.reasoning`) and `Transcript.Segment` (`.attachment`, `.custom`), which broke the exhaustive `switch` statements in `serializeSegment` and `mapTranscriptEntries`.
- Added `@unknown default` clauses to all `switch` statements over non-frozen Apple framework enums (`Transcript.Entry`, `Transcript.Segment`, and `LanguageModelSession.GenerationError`) so the plugin keeps compiling as Apple adds enum cases in future SDKs.

### ✨ Improvements
- **First-class handling of reasoning transcripts on Xcode 27+.** When built with a Swift 6.4+ toolchain (Xcode 27+), `.reasoning` transcript entries are serialized with a dedicated `reasoning` role and their segments are mapped just like other entries, and `.attachment`/`.custom` segments are serialized explicitly. This is gated behind `#if compiler(>=6.4)` so the plugin continues to build on Xcode 26 (where those cases do not exist), falling back to the `@unknown default` behavior there.

## 0.2.1

### 📚 Documentation Improvements
Expand Down
30 changes: 30 additions & 0 deletions ios/Classes/FoundationModelsFrameworkPlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,21 @@ import AppKit
role = "response"
segmentsText = response.segments.map(serializeSegment)
content = segmentsText.joined(separator: "\n")
#if compiler(>=6.4)
// `.reasoning` was added to `Transcript.Entry` in the Xcode 27 / iOS 26+ SDK.
// Gate it on the Swift 6.4+ toolchain (Xcode 27+) so this still builds on
// Xcode 26, where the case does not exist; older toolchains use `@unknown default`.
case .reasoning(let reasoning):
role = "reasoning"
segmentsText = reasoning.segments.map(serializeSegment)
content = segmentsText.joined(separator: "\n")
#endif
@unknown default:
// Handle any further entry kinds added in future SDKs without breaking the build.
role = "unknown"
let description = String(describing: entry)
segmentsText = [description]
content = description
}

return TranscriptEntry(id: entry.id, role: role, content: content, segments: segmentsText)
Expand All @@ -378,6 +393,18 @@ import AppKit
return textSegment.content
case .structure(let structuredSegment):
return String(describing: structuredSegment.content)
#if compiler(>=6.4)
// `.attachment` and `.custom` were added to `Transcript.Segment` in the
// Xcode 27 / iOS 26+ SDK. Gate them on the Swift 6.4+ toolchain (Xcode 27+) so
// this still builds on Xcode 26; older toolchains use `@unknown default`.
case .attachment(let attachmentSegment):
return String(describing: attachmentSegment)
case .custom(let customSegment):
return String(describing: customSegment)
#endif
@unknown default:
// Handle any further segment kinds added in future SDKs.
return String(describing: segment)
}
}
@available(iOS 26.0, macOS 15.0, *)
Expand Down Expand Up @@ -430,6 +457,9 @@ import AppKit
return FoundationModelsError.requestFailed("Unsupported guide")
case .unsupportedLanguageOrLocale(_):
return FoundationModelsError.requestFailed("Unsupported language or locale")
@unknown default:
// Handle generation error cases added in newer SDKs without breaking the build.
return FoundationModelsError.requestFailed("Generation failed")
}
}

Expand Down
30 changes: 30 additions & 0 deletions macos/Classes/FoundationModelsFrameworkPlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,21 @@ import AppKit
role = "response"
segmentsText = response.segments.map(serializeSegment)
content = segmentsText.joined(separator: "\n")
#if compiler(>=6.4)
// `.reasoning` was added to `Transcript.Entry` in the Xcode 27 / macOS 26+ SDK.
// Gate it on the Swift 6.4+ toolchain (Xcode 27+) so this still builds on
// Xcode 26, where the case does not exist; older toolchains use `@unknown default`.
case .reasoning(let reasoning):
role = "reasoning"
segmentsText = reasoning.segments.map(serializeSegment)
content = segmentsText.joined(separator: "\n")
#endif
@unknown default:
// Handle any further entry kinds added in future SDKs without breaking the build.
role = "unknown"
let description = String(describing: entry)
segmentsText = [description]
content = description
}

return TranscriptEntry(id: entry.id, role: role, content: content, segments: segmentsText)
Expand All @@ -378,6 +393,18 @@ import AppKit
return textSegment.content
case .structure(let structuredSegment):
return String(describing: structuredSegment.content)
#if compiler(>=6.4)
// `.attachment` and `.custom` were added to `Transcript.Segment` in the
// Xcode 27 / macOS 26+ SDK. Gate them on the Swift 6.4+ toolchain (Xcode 27+) so
// this still builds on Xcode 26; older toolchains use `@unknown default`.
case .attachment(let attachmentSegment):
return String(describing: attachmentSegment)
case .custom(let customSegment):
return String(describing: customSegment)
#endif
@unknown default:
// Handle any further segment kinds added in future SDKs.
return String(describing: segment)
}
}
@available(iOS 26.0, macOS 26.0, *)
Expand Down Expand Up @@ -430,6 +457,9 @@ import AppKit
return FoundationModelsError.requestFailed("Unsupported guide")
case .unsupportedLanguageOrLocale(_):
return FoundationModelsError.requestFailed("Unsupported language or locale")
@unknown default:
// Handle generation error cases added in newer SDKs without breaking the build.
return FoundationModelsError.requestFailed("Generation failed")
}
}

Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: foundation_models_framework
description: A Flutter package for integrating with Apple's Foundation Models framework on iOS and macOS devices. Provides session-based language model interactions with Apple Intelligence features.
version: 0.2.1
version: 0.2.2
homepage: https://github.com/dmakwt/flutter_foundation_models_framework
repository: https://github.com/dmakwt/flutter_foundation_models_framework
issue_tracker: https://github.com/dmakwt/flutter_foundation_models_framework/issues
Expand Down