Skip to content

feat(ios): add Figma Code Connect generation for icons and images - #44

Merged
alexey1312 merged 1 commit into
mainfrom
alexey1312/code-connect
Jan 9, 2026
Merged

feat(ios): add Figma Code Connect generation for icons and images#44
alexey1312 merged 1 commit into
mainfrom
alexey1312/code-connect

Conversation

@alexey1312

Copy link
Copy Markdown
Collaborator

This pull request introduces Figma Code Connect integration for iOS asset exports, enabling generated Swift code to link assets directly to their corresponding Figma components. It adds support for specifying output paths for Code Connect Swift files in configuration and propagates this through the asset export pipeline. Additionally, it updates the ImagePack model to include Figma node and file IDs, which are essential for linking assets with Figma.

The most important changes are:

Figma Code Connect Integration:

  • Added support for specifying codeConnectSwift output paths in the iOS section of the configuration file (CONFIG.md), allowing users to generate Swift structs for Figma Code Connect. This is reflected in both the documentation and configuration schema. [1] [2] [3] [4] [5] [6] [7]
  • Updated the Params struct and related parsing logic to include the new codeConnectSwift field for both icons and images. [1] [2] [3] [4] [5] [6]

Asset Export Pipeline Updates:

  • Propagated the new codeConnectSwiftURL parameter through the iOS export commands (iOSIconsExport.swift, iOSImagesExport.swift) and the XcodeImagesOutput model, ensuring the Code Connect Swift file is generated as part of the export process. [1] [2] [3] [4] [5] [6] [7]

Model Enhancements for Figma Linking:

  • Extended the ImagePack struct to include optional nodeId and fileId properties, which store the Figma node and file IDs for each asset. This allows generated code to reference the original Figma components.
  • Updated image loading logic to extract and assign the primary Figma node and file IDs to each ImagePack, ensuring this metadata is available for Code Connect integration. [1] [2] [3] [4] [5]

Template and Documentation Updates:

  • Added new iOS template entry for CodeConnect.figma.swift in .claude/EXFIG.toon to support Code Connect file generation.
  • Updated documentation in CONFIG.md and README.md to describe the new Code Connect integration and configuration options. [1] [2] [3] [4] [5] [6] [7]

Add support for generating Figma Code Connect Swift files that link
exported assets back to their source Figma components.

- Add codeConnectSwift URL config option for iOS icons and images
- Store nodeId and fileId in ImagePack for Code Connect URLs
- Generate .figma.swift files with FigmaConnect protocol structs
- Add Stencil template for Code Connect output
- Add comprehensive tests for Code Connect generation
@alexey1312
alexey1312 merged commit 4304cde into main Jan 9, 2026
1 check passed
@alexey1312
alexey1312 deleted the alexey1312/code-connect branch January 9, 2026 13:30
@gemini-code-assist

Copy link
Copy Markdown

Summary of Changes

Hello @alexey1312, 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 significantly enhances the iOS asset export capabilities by integrating Figma Code Connect. It allows developers to generate Swift code that directly references the original Figma components for icons and images, improving design-to-code traceability. The changes involve updating configuration options, enriching asset metadata, modifying the export pipeline to handle the new file generation, and introducing a dedicated template for the Code Connect Swift files.

Highlights

  • Figma Code Connect Integration: Introduced the ability to generate Swift code that links iOS assets directly to their corresponding Figma components.
  • Configurable Output Paths: Added "codeConnectSwift" as an optional configuration parameter in CONFIG.md for specifying the output location of generated Code Connect Swift files for both icons and images.
  • Enhanced ImagePack Model: The ImagePack struct now includes "nodeId" and "fileId" properties to store essential Figma metadata for each asset, enabling the linking functionality.
  • Asset Export Pipeline Update: The iOS asset export commands (iOSIconsExport.swift, iOSImagesExport.swift) and XcodeImagesOutput model were updated to propagate the "codeConnectSwiftURL" parameter, ensuring Code Connect files are generated during the export process.
  • New Code Connect Template: A new Stencil template (CodeConnect.figma.swift.stencil) was added to define the structure of the generated Code Connect Swift files.
  • Comprehensive Testing: New unit tests were added to verify the correct generation of Code Connect files, including scenarios for valid and missing Figma IDs, and proper URL formatting.
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.

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

Copy link
Copy Markdown

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 introduces a valuable feature for generating Figma Code Connect files for iOS, which will significantly improve the design-to-code workflow. The changes are well-structured, touching configuration, data models, loaders, and exporters, and are accompanied by a good set of tests. My review focuses on a few areas to enhance robustness and maintainability, including fixing a potential bug in Swift identifier sanitization, reducing code duplication in the export logic, and suggesting an additional test case to cover an edge case.

Comment on lines +134 to +135
let sanitizedName = name.map { $0.isLetter || $0.isNumber ? $0 : Character("_") }
let structName = "Asset_\(String(sanitizedName))"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

The current sanitization logic for creating structName can produce an invalid Swift identifier. If an asset name starts with a digit (e.g., "24-hour-support"), the sanitized name will also start with a digit (e.g., Asset_24_hour_support), which is not allowed for Swift type names. This will cause a compilation error in the generated file. Please add logic to handle this case, for example by prefixing the name with a string if it starts with a number.

Suggested change
let sanitizedName = name.map { $0.isLetter || $0.isNumber ? $0 : Character("_") }
let structName = "Asset_\(String(sanitizedName))"
let sanitizedName = String(name.map { $0.isLetter || $0.isNumber ? $0 : "_" })
let structName = "Asset_\(sanitizedName.first?.isNumber == true ? "image_\(sanitizedName)" : sanitizedName)"

Comment on lines +34 to +39
// Generate Code Connect file if URL is configured
if let codeConnectURL = output.codeConnectSwiftURL {
if let codeConnectFile = try generateCodeConnect(imagePacks: assets, url: codeConnectURL) {
result.append(codeConnectFile)
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

This block of code for generating the Code Connect file is duplicated in export, exportSwiftExtensions, and exportForHeic. To improve maintainability and follow the DRY (Don't Repeat Yourself) principle, consider extracting this logic into a private helper function within this class.

Comment on lines +120 to +128
let validAssets = imagePacks.filter { pack in
pack.light.nodeId != nil && pack.light.fileId != nil
}
guard !validAssets.isEmpty else { return nil }

let assets = validAssets.map { pack -> [String: String] in
let name = pack.light.name
let nodeId = pack.light.nodeId ?? ""
let fileId = pack.light.fileId ?? ""

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The current implementation first filters imagePacks and then maps over the result, using the nil-coalescing operator (??) to handle optionals that are already guaranteed to be non-nil by the filter. This can be simplified by using a single compactMap operation. This would unwrap the optionals safely and make the intent clearer.

Example:

let assets = imagePacks.compactMap { pack -> [String: String]? in
    guard let nodeId = pack.light.nodeId, let fileId = pack.light.fileId else {
        return nil
    }
    let name = pack.light.name
    // ... rest of mapping logic using non-optional nodeId and fileId
}
guard !assets.isEmpty else { return nil }


/// Tests that Code Connect file is generated when codeConnectSwiftURL is configured
/// and icons have nodeId/fileId set.
func testExportWithCodeConnect_generatesCodeConnectFile() throws {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

These tests for Code Connect generation are great! To make them even more robust, consider adding a test case for an asset name that would generate an invalid Swift identifier without proper sanitization. For example, a name starting with a digit like "12-icon". This would ensure the sanitization logic correctly handles such cases and prevents compilation errors in the generated code.


/// Tests that Code Connect file is generated when codeConnectSwiftURL is configured
/// and images have nodeId/fileId set.
func testExportWithCodeConnect_generatesCodeConnectFile() throws {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

These tests for Code Connect generation are great! To make them even more robust, consider adding a test case for an asset name that would generate an invalid Swift identifier without proper sanitization. For example, a name starting with a digit like "12-image". This would ensure the sanitization logic correctly handles such cases and prevents compilation errors in the generated code.

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