zitare-native/scripts/make-appicon.swift
Till 7b4cb13afe fix(icon): TestFlight-Validation grün — Icon + CFBundleIconName
Apple Validator hatte drei Fehler geworfen:
  - Missing 120x120 (iPhone) und 152x152 (iPad)
  - Missing Info.plist key CFBundleIconName

Root-Cause: AppIcon.appiconset hatte keinen filename gesetzt → keine
PNG-Variants im Bundle. Plus: bei GENERATE_INFOPLIST_FILE=NO injiziert
Xcode CFBundleIconName nicht automatisch, das muss explizit in die
plist.

Fixes:
- scripts/make-appicon.swift erzeugt 1024×1024-PNG-Platzhalter in
  paper-Theme-Farben (Sienna-Background, dunkles Z, zwei
  Anführungszeichen-Akzente) analog cards-native
- Sources/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json
  verlinkt AppIcon-1024.png für light / dark / tinted (3 Appearances)
- project.yml setzt CFBundleIconName: AppIcon im Info.plist-Root

Archive-Verifikation:
  $ /usr/libexec/PlistBuddy -c "Print :CFBundleIconName" Info.plist
  → AppIcon
  $ ls ZitareNative.app | grep AppIcon
  → AppIcon, AppIcon60x60@2x.png (=120×120), AppIcon76x76@2x~ipad.png
    (=152×152)

Platzhalter — vor produktivem App-Store-Launch durch designtes Icon
ersetzen.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 21:00:24 +02:00

89 lines
3.1 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env swift
// Generiert ein 1024×1024-AppIcon-PNG als Platzhalter für Zitare.
//
// Design (paper-Variant aus @mana/themes):
// - Background: warm Sienna (paper-primary, HSL 18 50% 38%)
// - Zwei stilisierte typografische Anführungszeichen oben in
// gebrochenem Weiß (paper-background)
// - Großes serifenbetontes Z" zentriert in dunklem Sepia
//
// Aufruf:
// swift scripts/make-appicon.swift
//
// Schreibt nach: Sources/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon-1024.png
//
// Dies ist ein Platzhalter vor App-Store-Submission durch ein
// designter Icon ersetzen.
import AppKit
import CoreGraphics
let size = 1024
let cs = CGColorSpaceCreateDeviceRGB()
guard let ctx = CGContext(
data: nil,
width: size, height: size,
bitsPerComponent: 8, bytesPerRow: 0,
space: cs,
bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue
) else {
print("CGContext creation failed")
exit(1)
}
// HSL(18, 50%, 38%) paper-primary, warm Sienna
let background = CGColor(red: 0.57, green: 0.30, blue: 0.19, alpha: 1)
ctx.setFillColor(background)
ctx.fill(CGRect(x: 0, y: 0, width: size, height: size))
// Zwei Anführungs"-Akzente oben gebrochenes Weiß (paper-bg-light)
let accent = CGColor(red: 0.95, green: 0.93, blue: 0.88, alpha: 0.92)
let quoteFont = NSFont(name: "Georgia-Bold", size: 360)
?? NSFont.boldSystemFont(ofSize: 360)
let quoteAttrs: [NSAttributedString.Key: Any] = [
.font: quoteFont,
.foregroundColor: NSColor(cgColor: accent) ?? .white,
]
// Anführungszeichen links ()
let leftQuote = NSAttributedString(string: "\u{201E}", attributes: quoteAttrs)
let leftLine = CTLineCreateWithAttributedString(leftQuote)
ctx.textPosition = CGPoint(x: 160, y: 520)
CTLineDraw(leftLine, ctx)
// Anführungszeichen rechts (")
let rightQuote = NSAttributedString(string: "\u{201C}", attributes: quoteAttrs)
let rightLine = CTLineCreateWithAttributedString(rightQuote)
ctx.textPosition = CGPoint(x: 620, y: 520)
CTLineDraw(rightLine, ctx)
// Großes Z" mittig dunkles Sepia, serif
let zFont = NSFont(name: "Georgia-Bold", size: 640)
?? NSFont.boldSystemFont(ofSize: 640)
let darkSepia = CGColor(red: 0.22, green: 0.16, blue: 0.12, alpha: 1)
let zAttrs: [NSAttributedString.Key: Any] = [
.font: zFont,
.foregroundColor: NSColor(cgColor: darkSepia) ?? .black,
]
let zStr = NSAttributedString(string: "Z", attributes: zAttrs)
let zLine = CTLineCreateWithAttributedString(zStr)
let zBounds = CTLineGetImageBounds(zLine, ctx)
let tx = (CGFloat(size) - zBounds.width) / 2 - zBounds.origin.x
let ty = (CGFloat(size) - zBounds.height) / 2 - zBounds.origin.y - 40
ctx.textPosition = CGPoint(x: tx, y: ty)
CTLineDraw(zLine, ctx)
// PNG schreiben
guard let cgImage = ctx.makeImage() else {
print("makeImage failed")
exit(1)
}
let bitmap = NSBitmapImageRep(cgImage: cgImage)
guard let data = bitmap.representation(using: .png, properties: [:]) else {
print("PNG encoding failed")
exit(1)
}
let target = URL(fileURLWithPath: "Sources/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon-1024.png")
try data.write(to: target)
print("Wrote \(target.path) (\(data.count) bytes)")