Tutorials Search / Native Mac IDE / Create an iOS or Mac app icon
📝 Written ● Beginner Updated 2026-05-17

Create an iOS or Mac app icon

App icons used to mean exporting fifteen PNGs at every device-pixel size. Modern Xcode wants one — a 1024×1024 PNG — and generates the rest. This tutorial covers what makes that one image App-Store-shippable, the asset-catalog flow, and the one mistake that gets builds silently rejected at upload.

You can let the agent do this for you in three sentences ("add an app icon, use the image at ~/Desktop/icon.png as the source") and it'll generally land it on the first try. The reason this tutorial exists is for when something goes wrong — usually a rejected upload — and you need to know what the asset catalog actually expects. Once you understand the shape of the problem, the agent's edits stop being magic.

What you'll learn

Step 1: The mental model

1

Asset catalogs are folders pretending to be files

When you see Assets.xcassets in the Xcode project navigator, that's not a single file — it's a directory on disk. Inside, every "image" you've added is its own subdirectory containing the actual PNGs and a small Contents.json that tells the build system which file goes with which size, scale, and idiom (iPhone, iPad, Mac, etc.).

For an app icon specifically, the directory is named AppIcon.appiconset. In the old flow it would contain ~15 PNGs at every required device-pixel size. The modern flow, since Xcode 14, supports a "Single Size" mode: drop in one 1024×1024 PNG, and the toolchain generates every smaller variant at build time. You don't ever ship 15 files — you ship one.

This is the entire reason a "use this image as my app icon" prompt to the agent works so reliably. There's exactly one file to write and one Contents.json to edit.

Step 2: Prepare the source image

2

Three rules, one of which gets builds rejected

Your 1024×1024 source PNG needs to satisfy three constraints:

  • Exactly 1024×1024 pixels, square. Not 1023×1024, not 2048×2048 downscaled. Xcode will warn but ship; App Store Connect will reject if it's not exactly square at upload time.
  • sRGB color space. If you exported from Figma or Sketch, you're almost certainly already in sRGB. If you exported from a print tool, you might be in Display P3 or Adobe RGB — convert before importing or colors shift on device.
  • No alpha channel. This is the silent killer. App Store Connect rejects any iOS icon with transparency — and it does so at the very end of upload, after the long wait. Flatten the image against a solid color (usually white or your brand color) before saving.

Also: don't pre-round the corners. iOS and macOS apply their own corner masks (different radii per platform, different per device family). If you ship a pre-rounded square, you get a double-rounded blob that looks wrong everywhere. Ship a perfect square; the OS does the rest.

The alpha-channel rejection is the most common ship blocker. Symptoms: you upload to App Store Connect, wait 10 minutes, and get an email that reads "Invalid Asset — The app icon … can't contain alpha channels or transparencies." Fix it by flattening: open in Preview → Export → uncheck "Alpha" → save → reimport. Or in the terminal: sips -s format png --setProperty hasAlpha no icon.png --out icon-flat.png.

Step 3: The fast path — App Icon Generator (with built-in AI)

3

Mobile menu → App Icon Generator… → prompt or paste → Generate

LingCode ships a dedicated sheet that does the whole pipeline — generate the source image, resize it to every required dimension, write the asset catalog — in one window. From the menu bar choose Mobile → App Icon Generator….

You have two ways to provide the source:

  • Type a prompt: there's a text field that takes natural language ("minimalist purple lightning bolt, flat design, white background") and calls LingCode's hosted image-generation backend to produce a 1024×1024 PNG. A quota badge above the field shows how many generations you have left this month — free/Pro/Max-Pro tiers have different ceilings.
  • Drop a master image: if you already have a 1024×1024 PNG from Figma, Midjourney, the chat's generate_image tool, or anywhere else, click the master-image slot and pick the file.

Then pick your target directories — the iOS slot points at your project's Assets.xcassets/AppIcon.appiconset/, the Android slot at app/src/main/res/ (toggle off whichever platform you're not shipping). Click Generate. The sheet lists every file it wrote so you can verify the output landed in the right folders.

The sheet uses LingCode's bundled AppIconGeneratorService under the hood — pure Core Graphics, no external tools. The iOS pass produces a complete AppIcon.appiconset with all required sizes; the Android pass writes ic_launcher, ic_launcher_round, and the adaptive ic_launcher_foreground at every density bucket (covered in the Android adaptive icon tutorial).

Step 4: Or do it via chat

4

If you'd rather stay in the agent loop

Open a Claude chat in your project and ask:

Add an app icon to this project. Use ~/Desktop/icon.png as the source image.
Use the modern single-size asset catalog flow (one 1024×1024 image).

The agent will copy the file into YourApp/Assets.xcassets/AppIcon.appiconset/icon.png and rewrite Contents.json to declare a single 1024×1024 universal entry. Both edits show up in the diff view, easy to revert.

Don't have a source image yet? The chat has its own image-generation tool wired to Gemini's image model. Ask "generate a 1024×1024 app icon: a calm geometric sun in gold on a deep-navy background, flat design" and the agent saves the result to <project>/assets/<slug>.png, then references it back inline so you can iterate. Needs your own Gemini API key (Settings → API Keys → Gemini). Once you like the result, ask the agent to wire it into the asset catalog — or open the App Icon Generator sheet and point it at the generated file.

Verify by opening Assets.xcassets in Xcode (or LingCode's asset browser) and clicking AppIcon. You should see your image in a single large slot, not split across a grid of device-specific slots. That confirms single-size mode is on.

iOS and Mac in the same project? The single 1024×1024 image works for both — the build system synthesizes the per-platform variants. If you want platform-specific art (a different look on Mac than iPhone), the agent can switch the asset catalog back into multi-platform mode and add separate source images per idiom. Mention "I want different artwork on macOS" in your prompt.

Step 5: Add it manually (the path everything else is automating)

5

If you ever need to do this by hand

Same flow, click by click. Useful when something has drifted and the diff isn't obvious.

  1. Open Assets.xcassets in Xcode. Select the AppIcon entry in the left sidebar.
  2. In the right inspector (Attributes), set Devices to iOS, iPadOS, macOS as appropriate.
  3. Toggle Single Size on (or "iOS Marketing" — same thing, depending on Xcode version).
  4. Drag your 1024×1024 PNG into the single slot that appears.
  5. Build and run. Confirm the icon appears in the Dock (Mac) or Home Screen (iOS Simulator).

If the slot complains "Image dimensions don't match expected size," the source isn't exactly 1024 square. If it complains about alpha, see Step 2's warn box.

Step 6: Diagnose a failure

6

Two failure modes, each with one symptom

If the icon doesn't appear or won't ship, it's almost always one of these:

SymptomCauseFix
Builds and installs, but the launcher shows the generic gray app icon The asset catalog has the image but the project's build settings don't reference AppIcon as the icon source. Project target → Build Settings → search "ASSETCATALOG_COMPILER_APPICON_NAME". It should be AppIcon. If empty, set it.
App Store Connect upload rejected with "alpha channels or transparencies" The 1024×1024 source PNG has an alpha channel — even if it looks fully opaque, the channel itself is the problem. See Step 2's warn box: flatten with sips or Preview's "uncheck Alpha" export, replace the file, archive and re-upload.

Both diagnoses take 30 seconds with the agent: paste the rejection email or the launcher symptom into chat, and it'll inspect Contents.json and the build settings for you.

What's next