All skills

Generates shareable card images from app content (achievements, stats, quotes) for social media sharing. Use when user wants to create share images, social cards, shareable content cards, or export app content as images with ShareLink integration.

Use this Skill: https://skilld.dev/gh/rshankras/claude-code-apple-skills/share-card

This session only. Nothing lands on disk.

templates.md

≈7.3k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Share Card Code Templates

Production-ready Swift templates for shareable card image generation. All code targets iOS 16+ / macOS 13+ (iOS 17+ / macOS 14+ for @Observable) and uses modern Swift concurrency.

Platform Compatibility

#if canImport(UIKit)
import UIKit
typealias PlatformImage = UIImage
#elseif canImport(AppKit)
import AppKit
typealias PlatformImage = NSImage
#endif

extension Image {
    init(platformImage: PlatformImage) {
        #if canImport(UIKit)
        self.init(uiImage: platformImage)
        #elseif canImport(AppKit)
        self.init(nsImage: platformImage)
        #endif
    }
}

ShareCardContent.swift

import Foundation

/// Protocol defining content that can be rendered as a share card.
///
/// Conform to this protocol to create custom card content types.
/// The renderer uses these properties to lay out the card.
protocol ShareCardContent: Sendable {
    /// Primary title displayed prominently on the card.
    var title: String { get }

    /// Optional subtitle or description below the title.
    var subtitle: String? { get }

    /// App or brand name shown in the card footer.
    var brandName: String { get }

    /// Optional SF Symbol name for a decorative icon.
    var iconName: String? { get }
}

// MARK: - Achievement Card Content

/// Content for achievement or milestone share cards.
///
/// Usage:
/// ```swift
/// let content = AchievementCardContent(
///     title: "First 5K Run",
///     subtitle: "Completed on March 15, 2025",
///     metric: "500 pts",
///     iconName: "figure.run",
///     brandName: "FitTracker"
/// )
/// ```
struct AchievementCardContent: ShareCardContent, Sendable {
    let title: String
    let subtitle: String?
    let metric: String
    let iconName: String?
    let brandName: String

    init(
        title: String,
        subtitle: String? = nil,
        metric: String,
        iconName: String? = nil,
        brandName: String
    ) {
        self.title = title
        self.subtitle = subtitle
        self.metric = metric
        self.iconName = iconName
        self.brandName = brandName
    }
}

// MARK: - Statistics Card Content

/// A single statistic item displayed in a statistics card.
struct StatItem: Sendable, Identifiable {
    let id = UUID()
    let label: String
    let value: String
    let trend: Trend?

    enum Trend: Sendable {
        case up, down, neutral
    }

    init(label: String, value: String, trend: Trend? = nil) {
        self.label = label
        self.value = value
        self.trend = trend
    }
}

/// Content for statistics or progress share cards.
///
/// Usage:
/// ```swift
/// let content = StatisticsCardContent(
///     title: "Weekly Progress",
///     stats: [
///         StatItem(label: "Steps", value: "52,340", trend: .up),
///         StatItem(label: "Calories", value: "3,200", trend: .neutral),
///     ],
///     dateRange: "Mar 10 - Mar 16",
///     brandName: "FitTracker"
/// )
/// ```
struct StatisticsCardContent: ShareCardContent, Sendable {
    let title: String
    let subtitle: String?
    let stats: [StatItem]
    let dateRange: String?
    let brandName: String

    var iconName: String? { nil }

    init(
        title: String,
        subtitle: String? = nil,
        stats: [StatItem],
        dateRange: String? = nil,
        brandName: String
    ) {
        self.title = title
        self.subtitle = subtitle
        self.stats = stats
        self.dateRange = dateRange
        self.brandName = brandName
    }
}

// MARK: - Quote Card Content

/// Content for quote or text share cards.
///
/// Usage:
/// ```swift
/// let content = QuoteCardContent(
///     quote: "The only way to do great work is to love what you do.",
///     attribution: "Steve Jobs",
///     brandName: "DailyQuotes"
/// )
/// ```
struct QuoteCardContent: ShareCardContent, Sendable {
    let quote: String
    let attribution: String?
    let brandName: String

    var title: String { quote }
    var subtitle: String? { attribution }
    var iconName: String? { nil }

    init(
        quote: String,
        attribution: String? = nil,
        brandName: String
    ) {
        self.quote = quote
        self.attribution = attribution
        self.brandName = brandName
    }
}

ShareCardStyle.swift

import SwiftUI

/// Predefined visual styles for share cards.
///
/// Each style defines colors, fonts, spacing, and layout
/// parameters used by the card renderer.
enum ShareCardStyle: String, CaseIterable, Identifiable, Sendable {
    case minimal
    case branded
    case statistics

    var id: String { rawValue }

    var displayName: String {
        switch self {
        case .minimal: return "Minimal"
        case .branded: return "Branded"
        case .statistics: return "Statistics"
        }
    }

    // MARK: - Colors

    var backgroundColor: Color {
        switch self {
        case .minimal: return .white
        case .branded: return Color(red: 0.1, green: 0.1, blue: 0.15)
        case .statistics: return Color(red: 0.05, green: 0.05, blue: 0.1)
        }
    }

    var primaryTextColor: Color {
        switch self {
        case .minimal: return .black
        case .branded: return .white
        case .statistics: return .white
        }
    }

    var secondaryTextColor: Color {
        switch self {
        case .minimal: return Color(white: 0.4)
        case .branded: return Color(white: 0.7)
        case .statistics: return Color(white: 0.6)
        }
    }

    var accentColor: Color {
        switch self {
        case .minimal: return .blue
        case .branded: return Color(red: 0.4, green: 0.7, blue: 1.0)
        case .statistics: return Color(red: 0.3, green: 0.85, blue: 0.6)
        }
    }

    // MARK: - Typography

    var titleFont: Font {
        switch self {
        case .minimal: return .system(size: 28, weight: .semibold, design: .default)
        case .branded: return .system(size: 32, weight: .bold, design: .rounded)
        case .statistics: return .system(size: 24, weight: .bold, design: .monospaced)
        }
    }

    var subtitleFont: Font {
        switch self {
        case .minimal: return .system(size: 16, weight: .regular, design: .default)
        case .branded: return .system(size: 18, weight: .medium, design: .rounded)
        case .statistics: return .system(size: 14, weight: .regular, design: .monospaced)
        }
    }

    var metricFont: Font {
        switch self {
        case .minimal: return .system(size: 48, weight: .bold, design: .rounded)
        case .branded: return .system(size: 56, weight: .heavy, design: .rounded)
        case .statistics: return .system(size: 44, weight: .bold, design: .monospaced)
        }
    }

    var brandFont: Font {
        .system(size: 14, weight: .medium, design: .default)
    }

    // MARK: - Layout

    var cornerRadius: CGFloat {
        switch self {
        case .minimal: return 16
        case .branded: return 24
        case .statistics: return 20
        }
    }

    var contentPadding: EdgeInsets {
        switch self {
        case .minimal: return EdgeInsets(top: 40, leading: 32, bottom: 40, trailing: 32)
        case .branded: return EdgeInsets(top: 48, leading: 36, bottom: 48, trailing: 36)
        case .statistics: return EdgeInsets(top: 36, leading: 28, bottom: 36, trailing: 28)
        }
    }
}

// MARK: - Card Size Presets

/// Predefined card sizes optimized for different sharing platforms.
enum ShareCardSize: String, CaseIterable, Identifiable, Sendable {
    case square      // 1080x1080 — Instagram, general
    case story       // 1080x1920 — Instagram Stories, TikTok
    case wide        // 1200x630  — Twitter/X, Open Graph
    case compact     // 800x600   — Messages, lightweight

    var id: String { rawValue }

    var size: CGSize {
        switch self {
        case .square:  return CGSize(width: 1080, height: 1080)
        case .story:   return CGSize(width: 1080, height: 1920)
        case .wide:    return CGSize(width: 1200, height: 630)
        case .compact: return CGSize(width: 800, height: 600)
        }
    }

    var displayName: String {
        switch self {
        case .square:  return "Square (1080x1080)"
        case .story:   return "Story (1080x1920)"
        case .wide:    return "Wide (1200x630)"
        case .compact: return "Compact (800x600)"
        }
    }

    /// Aspect ratio (width / height) for preview scaling.
    var aspectRatio: CGFloat {
        size.width / size.height
    }
}

ShareCardRenderer.swift

import SwiftUI

/// Renders share card SwiftUI views into raster images using `ImageRenderer`.
///
/// Must be called from the main actor since `ImageRenderer` requires it.
///
/// Usage:
/// ```swift
/// let renderer = ShareCardRenderer()
/// let image = await renderer.render(
///     content: achievementContent,
///     style: .branded,
///     size: .square
/// )
/// ```
@MainActor
struct ShareCardRenderer {

    /// Render a share card to a platform image.
    ///
    /// - Parameters:
    ///   - content: The card content to render.
    ///   - style: The visual style to apply.
    ///   - size: The card size preset (default: square).
    ///   - qrCodeURL: Optional URL to encode as a QR code overlay.
    ///   - scale: The render scale factor (default: 2.0 for Retina).
    /// - Returns: A rendered platform image, or nil if rendering fails.
    func render(
        content: any ShareCardContent,
        style: ShareCardStyle,
        size: ShareCardSize = .square,
        qrCodeURL: URL? = nil,
        scale: CGFloat = 2.0
    ) -> PlatformImage? {
        let cardView = ShareCardView(
            content: content,
            style: style,
            cardSize: size,
            qrCodeURL: qrCodeURL
        )
        .frame(width: size.size.width, height: size.size.height)

        let renderer = ImageRenderer(content: cardView)
        renderer.scale = scale

        // Propose the exact card size so the layout doesn't compress
        renderer.proposedSize = ProposedViewSize(size.size)

        #if canImport(UIKit)
        return renderer.uiImage
        #elseif canImport(AppKit)
        return renderer.nsImage
        #endif
    }

    /// Render a share card and return PNG data suitable for sharing.
    ///
    /// PNG preserves text sharpness, which is ideal for cards with typography.
    func renderPNGData(
        content: any ShareCardContent,
        style: ShareCardStyle,
        size: ShareCardSize = .square,
        qrCodeURL: URL? = nil,
        scale: CGFloat = 2.0
    ) -> Data? {
        guard let image = render(
            content: content,
            style: style,
            size: size,
            qrCodeURL: qrCodeURL,
            scale: scale
        ) else { return nil }

        #if canImport(UIKit)
        return image.pngData()
        #elseif canImport(AppKit)
        guard let tiffData = image.tiffRepresentation,
              let bitmap = NSBitmapImageRep(data: tiffData) else { return nil }
        return bitmap.representation(using: .png, properties: [:])
        #endif
    }

    /// Render a share card and return JPEG data with configurable quality.
    ///
    /// JPEG is smaller but may show compression artifacts on text.
    /// Use quality >= 0.9 for text-heavy cards.
    func renderJPEGData(
        content: any ShareCardContent,
        style: ShareCardStyle,
        size: ShareCardSize = .square,
        qrCodeURL: URL? = nil,
        scale: CGFloat = 2.0,
        quality: CGFloat = 0.92
    ) -> Data? {
        guard let image = render(
            content: content,
            style: style,
            size: size,
            qrCodeURL: qrCodeURL,
            scale: scale
        ) else { return nil }

        #if canImport(UIKit)
        return image.jpegData(compressionQuality: quality)
        #elseif canImport(AppKit)
        guard let tiffData = image.tiffRepresentation,
              let bitmap = NSBitmapImageRep(data: tiffData) else { return nil }
        return bitmap.representation(
            using: .jpeg,
            properties: [.compressionFactor: quality]
        )
        #endif
    }
}

ShareCardView.swift

import SwiftUI

/// The SwiftUI view that composes the card layout.
///
/// This view is rendered to an image by `ShareCardRenderer`.
/// It should NOT be used directly in the app UI — use `ShareCardSheet` instead.
struct ShareCardView: View {
    let content: any ShareCardContent
    let style: ShareCardStyle
    let cardSize: ShareCardSize
    let qrCodeURL: URL?

    init(
        content: any ShareCardContent,
        style: ShareCardStyle,
        cardSize: ShareCardSize = .square,
        qrCodeURL: URL? = nil
    ) {
        self.content = content
        self.style = style
        self.cardSize = cardSize
        self.qrCodeURL = qrCodeURL
    }

    var body: some View {
        ZStack {
            // Background
            RoundedRectangle(cornerRadius: style.cornerRadius)
                .fill(style.backgroundColor)

            // Content
            VStack(spacing: 0) {
                Spacer(minLength: style.contentPadding.top)

                contentBody

                Spacer(minLength: 16)

                footerView
                    .padding(.bottom, style.contentPadding.bottom)
            }
            .padding(.horizontal, style.contentPadding.leading)

            // QR Code overlay (bottom-right corner)
            if let qrCodeURL {
                qrOverlay(url: qrCodeURL)
            }
        }
        .clipShape(RoundedRectangle(cornerRadius: style.cornerRadius))
    }

    // MARK: - Content Body

    @ViewBuilder
    private var contentBody: some View {
        if let achievement = content as? AchievementCardContent {
            AchievementCardBody(content: achievement, style: style)
        } else if let statistics = content as? StatisticsCardContent {
            StatisticsCardBody(content: statistics, style: style)
        } else if let quote = content as? QuoteCardContent {
            QuoteCardBody(content: quote, style: style)
        } else {
            GenericCardBody(content: content, style: style)
        }
    }

    // MARK: - Footer

    private var footerView: some View {
        HStack {
            Text(content.brandName)
                .font(style.brandFont)
                .foregroundStyle(style.secondaryTextColor)

            Spacer()

            if qrCodeURL == nil {
                // Show a subtle divider dot when there's no QR code
                Circle()
                    .fill(style.accentColor.opacity(0.5))
                    .frame(width: 6, height: 6)
            }
        }
    }

    // MARK: - QR Code Overlay

    private func qrOverlay(url: URL) -> some View {
        VStack {
            Spacer()
            HStack {
                Spacer()
                QRCodeOverlay(url: url, style: style)
                    .frame(width: cardSize.size.width * 0.12,
                           height: cardSize.size.width * 0.12)
                    .padding(style.contentPadding.trailing)
                    .padding(.bottom, style.contentPadding.bottom)
            }
        }
    }
}

// MARK: - Achievement Card Body

/// Renders achievement/milestone content within a share card.
private struct AchievementCardBody: View {
    let content: AchievementCardContent
    let style: ShareCardStyle

    var body: some View {
        VStack(spacing: 20) {
            // Icon
            if let iconName = content.iconName {
                Image(systemName: iconName)
                    .font(.system(size: 56))
                    .foregroundStyle(style.accentColor)
                    .padding(.bottom, 8)
            }

            // Metric
            Text(content.metric)
                .font(style.metricFont)
                .foregroundStyle(style.accentColor)

            // Title
            Text(content.title)
                .font(style.titleFont)
                .foregroundStyle(style.primaryTextColor)
                .multilineTextAlignment(.center)

            // Subtitle
            if let subtitle = content.subtitle {
                Text(subtitle)
                    .font(style.subtitleFont)
                    .foregroundStyle(style.secondaryTextColor)
                    .multilineTextAlignment(.center)
            }
        }
    }
}

// MARK: - Statistics Card Body

/// Renders statistics/progress content within a share card.
private struct StatisticsCardBody: View {
    let content: StatisticsCardContent
    let style: ShareCardStyle

    var body: some View {
        VStack(spacing: 24) {
            // Title
            Text(content.title)
                .font(style.titleFont)
                .foregroundStyle(style.primaryTextColor)

            // Date range
            if let dateRange = content.dateRange {
                Text(dateRange)
                    .font(style.subtitleFont)
                    .foregroundStyle(style.secondaryTextColor)
            }

            // Stats grid
            let columns = Array(
                repeating: GridItem(.flexible(), spacing: 16),
                count: min(content.stats.count, 3)
            )

            LazyVGrid(columns: columns, spacing: 20) {
                ForEach(content.stats) { stat in
                    StatItemView(stat: stat, style: style)
                }
            }
        }
    }
}

/// Renders a single statistic item with label, value, and optional trend.
private struct StatItemView: View {
    let stat: StatItem
    let style: ShareCardStyle

    var body: some View {
        VStack(spacing: 8) {
            HStack(spacing: 4) {
                Text(stat.value)
                    .font(style.metricFont)
                    .foregroundStyle(style.primaryTextColor)

                if let trend = stat.trend {
                    trendIndicator(trend)
                }
            }

            Text(stat.label)
                .font(style.subtitleFont)
                .foregroundStyle(style.secondaryTextColor)
        }
    }

    @ViewBuilder
    private func trendIndicator(_ trend: StatItem.Trend) -> some View {
        switch trend {
        case .up:
            Image(systemName: "arrow.up.right")
                .font(.system(size: 14, weight: .bold))
                .foregroundStyle(.green)
        case .down:
            Image(systemName: "arrow.down.right")
                .font(.system(size: 14, weight: .bold))
                .foregroundStyle(.red)
        case .neutral:
            Image(systemName: "arrow.right")
                .font(.system(size: 14, weight: .bold))
                .foregroundStyle(style.secondaryTextColor)
        }
    }
}

// MARK: - Quote Card Body

/// Renders quote/text content within a share card.
private struct QuoteCardBody: View {
    let content: QuoteCardContent
    let style: ShareCardStyle

    var body: some View {
        VStack(spacing: 24) {
            // Decorative quotation mark
            Text("\u{201C}")
                .font(.system(size: 72, weight: .bold))
                .foregroundStyle(style.accentColor.opacity(0.3))
                .frame(height: 50)

            // Quote text
            Text(content.quote)
                .font(style.titleFont)
                .foregroundStyle(style.primaryTextColor)
                .multilineTextAlignment(.center)
                .lineSpacing(6)

            // Attribution
            if let attribution = content.attribution {
                HStack(spacing: 8) {
                    Rectangle()
                        .fill(style.accentColor)
                        .frame(width: 24, height: 2)

                    Text(attribution)
                        .font(style.subtitleFont)
                        .foregroundStyle(style.secondaryTextColor)
                }
            }
        }
    }
}

// MARK: - Generic Card Body

/// Fallback renderer for custom `ShareCardContent` conformances.
private struct GenericCardBody: View {
    let content: any ShareCardContent
    let style: ShareCardStyle

    var body: some View {
        VStack(spacing: 20) {
            if let iconName = content.iconName {
                Image(systemName: iconName)
                    .font(.system(size: 48))
                    .foregroundStyle(style.accentColor)
            }

            Text(content.title)
                .font(style.titleFont)
                .foregroundStyle(style.primaryTextColor)
                .multilineTextAlignment(.center)

            if let subtitle = content.subtitle {
                Text(subtitle)
                    .font(style.subtitleFont)
                    .foregroundStyle(style.secondaryTextColor)
                    .multilineTextAlignment(.center)
            }
        }
    }
}

ShareCardSheet.swift

import SwiftUI

/// A complete sharing sheet with live card preview, style picker, and ShareLink.
///
/// Presents a preview of the share card with options to change style and size,
/// then share via the system share sheet.
///
/// Usage:
/// ```swift
/// .sheet(isPresented: $showShareCard) {
///     ShareCardSheet(
///         content: AchievementCardContent(
///             title: "First Run",
///             metric: "500 pts",
///             brandName: "FitApp"
///         )
///     )
/// }
/// ```
struct ShareCardSheet: View {
    let content: any ShareCardContent
    let qrCodeURL: URL?

    @State private var selectedStyle: ShareCardStyle = .branded
    @State private var selectedSize: ShareCardSize = .square
    @State private var renderedImage: PlatformImage?
    @State private var isRendering = false
    @Environment(\.dismiss) private var dismiss

    init(content: any ShareCardContent, qrCodeURL: URL? = nil) {
        self.content = content
        self.qrCodeURL = qrCodeURL
    }

    var body: some View {
        NavigationStack {
            ScrollView {
                VStack(spacing: 24) {
                    cardPreview
                    stylePickerSection
                    sizePickerSection
                    shareSection
                }
                .padding()
            }
            .navigationTitle("Share Card")
            #if os(iOS)
            .navigationBarTitleDisplayMode(.inline)
            #endif
            .toolbar {
                ToolbarItem(placement: .cancellationAction) {
                    Button("Cancel") { dismiss() }
                }
            }
            .task(id: StyleSizeKey(style: selectedStyle, size: selectedSize)) {
                await renderCard()
            }
        }
    }

    // MARK: - Card Preview

    private var cardPreview: some View {
        Group {
            if let renderedImage {
                Image(platformImage: renderedImage)
                    .resizable()
                    .aspectRatio(selectedSize.aspectRatio, contentMode: .fit)
                    .clipShape(RoundedRectangle(cornerRadius: 12))
                    .shadow(color: .black.opacity(0.15), radius: 12, y: 4)
            } else {
                RoundedRectangle(cornerRadius: 12)
                    .fill(Color.secondary.opacity(0.1))
                    .aspectRatio(selectedSize.aspectRatio, contentMode: .fit)
                    .overlay(ProgressView())
            }
        }
        .padding(.horizontal, 8)
    }

    // MARK: - Style Picker

    private var stylePickerSection: some View {
        VStack(alignment: .leading, spacing: 12) {
            Text("Style")
                .font(.headline)

            Picker("Style", selection: $selectedStyle) {
                ForEach(ShareCardStyle.allCases) { style in
                    Text(style.displayName).tag(style)
                }
            }
            .pickerStyle(.segmented)
        }
    }

    // MARK: - Size Picker

    private var sizePickerSection: some View {
        VStack(alignment: .leading, spacing: 12) {
            Text("Size")
                .font(.headline)

            Picker("Size", selection: $selectedSize) {
                ForEach(ShareCardSize.allCases) { size in
                    Text(size.displayName).tag(size)
                }
            }
            #if os(iOS)
            .pickerStyle(.menu)
            #else
            .pickerStyle(.automatic)
            #endif
        }
    }

    // MARK: - Share Section

    private var shareSection: some View {
        VStack(spacing: 12) {
            if let renderedImage {
                ShareLink(
                    item: Image(platformImage: renderedImage),
                    preview: SharePreview(
                        content.title,
                        image: Image(platformImage: renderedImage)
                    )
                ) {
                    Label("Share", systemImage: "square.and.arrow.up")
                        .font(.headline)
                        .frame(maxWidth: .infinity)
                        .padding(.vertical, 12)
                }
                .buttonStyle(.borderedProminent)
                .controlSize(.large)
            } else {
                Button(action: {}) {
                    Label("Rendering...", systemImage: "hourglass")
                        .font(.headline)
                        .frame(maxWidth: .infinity)
                        .padding(.vertical, 12)
                }
                .buttonStyle(.borderedProminent)
                .controlSize(.large)
                .disabled(true)
            }

            // Save to Photos button (iOS only)
            #if canImport(UIKit)
            if let renderedImage {
                Button {
                    UIImageWriteToSavedPhotosAlbum(renderedImage, nil, nil, nil)
                } label: {
                    Label("Save to Photos", systemImage: "photo.on.rectangle.angled")
                        .frame(maxWidth: .infinity)
                        .padding(.vertical, 12)
                }
                .buttonStyle(.bordered)
                .controlSize(.large)
            }
            #endif
        }
    }

    // MARK: - Rendering

    @MainActor
    private func renderCard() async {
        isRendering = true
        let renderer = ShareCardRenderer()
        renderedImage = renderer.render(
            content: content,
            style: selectedStyle,
            size: selectedSize,
            qrCodeURL: qrCodeURL
        )
        isRendering = false
    }
}

/// Key for tracking style + size changes to trigger re-render.
private struct StyleSizeKey: Equatable {
    let style: ShareCardStyle
    let size: ShareCardSize
}

QRCodeOverlay.swift

import SwiftUI
import CoreImage
import CoreImage.CIFilterBuiltins

/// Generates and displays a QR code overlay for embedding deep links in share cards.
///
/// Uses CoreImage's built-in QR code generator for reliable encoding.
///
/// Usage:
/// ```swift
/// QRCodeOverlay(
///     url: URL(string: "https://myapp.com/share/123")!,
///     style: .branded
/// )
/// .frame(width: 120, height: 120)
/// ```
struct QRCodeOverlay: View {
    let url: URL
    let style: ShareCardStyle

    var body: some View {
        ZStack {
            // Background for contrast
            RoundedRectangle(cornerRadius: 8)
                .fill(.white)
                .padding(-4)

            if let qrImage = QRCodeGenerator.generate(
                from: url.absoluteString,
                size: CGSize(width: 200, height: 200)
            ) {
                Image(platformImage: qrImage)
                    .interpolation(.none)
                    .resizable()
                    .aspectRatio(1, contentMode: .fit)
            }
        }
    }
}

// MARK: - QR Code Generator

/// CoreImage-based QR code generator.
///
/// Generates high-resolution QR code images suitable for embedding in share cards.
/// The output is a crisp, black-on-transparent QR code.
enum QRCodeGenerator {

    private static let context = CIContext()

    /// Generate a QR code image from a string.
    ///
    /// - Parameters:
    ///   - string: The string to encode (typically a URL).
    ///   - size: The desired output size in points.
    /// - Returns: A platform image containing the QR code, or nil if generation fails.
    static func generate(from string: String, size: CGSize) -> PlatformImage? {
        guard let data = string.data(using: .utf8) else { return nil }

        let filter = CIFilter.qrCodeGenerator()
        filter.message = data
        filter.correctionLevel = "M"  // Medium error correction

        guard let ciImage = filter.outputImage else { return nil }

        // Scale the QR code to the requested size
        let scaleX = size.width / ciImage.extent.width
        let scaleY = size.height / ciImage.extent.height
        let scaledImage = ciImage.transformed(
            by: CGAffineTransform(scaleX: scaleX, y: scaleY)
        )

        guard let cgImage = context.createCGImage(
            scaledImage,
            from: scaledImage.extent
        ) else { return nil }

        #if canImport(UIKit)
        return UIImage(cgImage: cgImage)
        #elseif canImport(AppKit)
        return NSImage(
            cgImage: cgImage,
            size: NSSize(width: size.width, height: size.height)
        )
        #endif
    }
}

Source: SKILL.md on GitHub

No alerts2mo3 checks · Risk SAFE
  • Gen Agent Trust Hub2mo

    The skill is a safe utility for generating iOS and macOS shareable card images. It uses standard developer tools for environment checks and provides local SwiftUI templates.

  • Socket2mo

    No alerts

  • Snyk2mo

    Risk: LOW · No issues

Signed by skilld at 32566aa. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 months ago.

Steadyupdated 3 months ago
What it can do
Reads files Edits files Runs commands
last_verified
2026-07-16
review_by
2027-06-22
os_version
iOS 27 / macOS 27
All 7 allowed tools
ReadWriteEditGlobGrepBashAskUserQuestion

README badge

README badge for rshankras/claude-code-apple-skills/share-card