Skip to content

fix: Add macOS platform support via Chameleon typealias pattern#22

Open
doozMen wants to merge 2 commits intopeterfriese:mainfrom
doozMen:fix/macos-platform-support
Open

fix: Add macOS platform support via Chameleon typealias pattern#22
doozMen wants to merge 2 commits intopeterfriese:mainfrom
doozMen:fix/macos-platform-support

Conversation

@doozMen
Copy link

@doozMen doozMen commented Feb 23, 2026

Summary

  • Introduces PlatformTypes.swift with cross-platform abstractions following the Chameleon pattern: PlatformImage typealias, Image(platformImage:) initializer, and platform color extensions
  • Replaces all direct UIImage, UIRectCorner, UIBezierPath, and Color(uiColor:) references with cross-platform equivalents
  • Adds macOS 26.0 to #available checks alongside iOS 26.0 for glass effects
  • Wraps .navigationBarTitleDisplayMode(.inline) in #if os(iOS) guards

Test plan

  • swift build succeeds on macOS (previously failed with UIKit import errors)
  • swift test passes (1 test, 0 failures)
  • Verify iOS build still works (all platform abstractions resolve to UIKit types)
  • Verify previews render correctly on both platforms

🤖 Generated with Claude Code

doozMen and others added 2 commits February 22, 2026 16:54
MarkdownUI requires macOS 12.0+, but ConversationKit didn't declare
a macOS platform, defaulting to 10.13. SPM 6 enforces this strictly
when consumed via remote URLs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace all UIKit-specific types with cross-platform abstractions:
- PlatformImage typealias (UIImage on iOS, NSImage on macOS)
- Platform color extensions (separator, secondary background, gray4)
- Cross-platform RoundedCorner shape replacing UIBezierPath
- Availability guards for iOS 26/macOS 26 glass effects
- Conditional navigationBarTitleDisplayMode for iOS only

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@gemini-code-assist
Copy link

Summary of Changes

Hello @doozMen, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request enhances the ConversationKit framework by adding support for the macOS platform. It leverages the Chameleon pattern to abstract platform-specific types, allowing the codebase to be shared between iOS and macOS. The changes include adding macOS as a supported platform in the package manifest, introducing platform-agnostic type aliases, and using conditional compilation to handle platform-specific code.

Highlights

  • Cross-Platform Support: Introduces macOS platform support by abstracting UIKit-specific types to platform-agnostic equivalents.
  • Chameleon Pattern: Employs the Chameleon pattern to provide type aliases and extensions for PlatformImage, Image initialization, and platform-specific colors.
  • Conditional Compilation: Uses #if os(iOS) guards to wrap iOS-specific code, ensuring compatibility with macOS.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • Package.swift
    • Added macOS platform support.
  • Sources/ConversationKit/Model/ImageAttachment.swift
    • Replaced UIImage with PlatformImage for cross-platform compatibility.
  • Sources/ConversationKit/Platform/PlatformTypes.swift
    • Introduced PlatformTypes.swift with cross-platform type aliases and extensions.
  • Sources/ConversationKit/Views/AttachmentPreviewCard.swift
    • Added macOS availability check for glass effects and updated image initialization to use PlatformImage.
  • Sources/ConversationKit/Views/AttachmentPreviewScrollView.swift
    • Updated image initialization to use PlatformImage.
  • Sources/ConversationKit/Views/ConversationView.swift
    • Wrapped navigationBarTitleDisplayMode in #if os(iOS) guards and updated color references to platform-agnostic equivalents.
  • Sources/ConversationKit/Views/MessageComposerView.swift
    • Added macOS availability check for glass effects, updated color references to platform-agnostic equivalents, and updated image initialization to use PlatformImage.
  • Sources/ConversationKit/Views/MessageView.swift
    • Replaced UIRectCorner with a cross-platform RectCorner and updated color references to platform-agnostic equivalents.
Activity
  • Added macOS platform support to Package.swift
  • Replaced UIImage with PlatformImage in ImageAttachment.swift
  • Created PlatformTypes.swift with platform-specific type aliases
  • Added macOS availability checks and updated image initialization in AttachmentPreviewCard.swift
  • Updated image initialization in AttachmentPreviewScrollView.swift
  • Added conditional compilation for navigationBarTitleDisplayMode and updated color references in ConversationView.swift
  • Added macOS availability checks, updated color references, and updated image initialization in MessageComposerView.swift
  • Replaced UIRectCorner with RectCorner and updated color references in MessageView.swift
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request successfully introduces macOS platform support to the ConversationKit library by implementing cross-platform abstractions following the Chameleon pattern. The changes include updating the Package.swift file to support macOS, replacing UIKit-specific types like "UIImage" and "UIRectCorner" with platform-agnostic equivalents, and introducing a new "PlatformTypes.swift" file to centralize these abstractions. The "RoundedCorner" shape has been refactored to use pure SwiftUI Path primitives, ensuring full cross-platform compatibility. Overall, the changes are well-executed and significantly improve the library's maintainability and platform reach.

Comment on lines 38 to +66
func path(in rect: CGRect) -> Path {
let path = UIBezierPath(
roundedRect: rect,
byRoundingCorners: corners,
cornerRadii: CGSize(width: radius, height: radius)
)
return Path(path.cgPath)
let tl = corners.contains(.topLeft) ? radius : 0
let tr = corners.contains(.topRight) ? radius : 0
let bl = corners.contains(.bottomLeft) ? radius : 0
let br = corners.contains(.bottomRight) ? radius : 0

var path = Path()
path.move(to: CGPoint(x: rect.minX + tl, y: rect.minY))
path.addLine(to: CGPoint(x: rect.maxX - tr, y: rect.minY))
path.addArc(
tangent1End: CGPoint(x: rect.maxX, y: rect.minY),
tangent2End: CGPoint(x: rect.maxX, y: rect.minY + tr),
radius: tr)
path.addLine(to: CGPoint(x: rect.maxX, y: rect.maxY - br))
path.addArc(
tangent1End: CGPoint(x: rect.maxX, y: rect.maxY),
tangent2End: CGPoint(x: rect.maxX - br, y: rect.maxY),
radius: br)
path.addLine(to: CGPoint(x: rect.minX + bl, y: rect.maxY))
path.addArc(
tangent1End: CGPoint(x: rect.minX, y: rect.maxY),
tangent2End: CGPoint(x: rect.minX, y: rect.maxY - bl),
radius: bl)
path.addLine(to: CGPoint(x: rect.minX, y: rect.minY + tl))
path.addArc(
tangent1End: CGPoint(x: rect.minX, y: rect.minY),
tangent2End: CGPoint(x: rect.minX + tl, y: rect.minY),
radius: tl)
return path

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The "path(in rect: CGRect)" method in the "RoundedCorner" shape is quite verbose due to the repeated "addLine" and "addArc" calls for each corner. While functional, encapsulating the logic for adding a single rounded corner segment could improve readability and reduce repetition, making the code easier to maintain in the long run.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant