From 7b4cb13afe244e1ec4f115ff056046e90557003d Mon Sep 17 00:00:00 2001 From: Till Date: Thu, 14 May 2026 21:00:24 +0200 Subject: [PATCH] =?UTF-8?q?fix(icon):=20TestFlight-Validation=20gr=C3=BCn?= =?UTF-8?q?=20=E2=80=94=20Icon=20+=20CFBundleIconName?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) --- .../AppIcon.appiconset/AppIcon-1024.png | Bin 0 -> 34353 bytes .../AppIcon.appiconset/Contents.json | 25 +++++ Sources/Resources/Localizable.xcstrings | 100 +++++++++++++----- project.yml | 4 + scripts/make-appicon.swift | 89 ++++++++++++++++ 5 files changed, 194 insertions(+), 24 deletions(-) create mode 100644 Sources/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon-1024.png create mode 100644 scripts/make-appicon.swift diff --git a/Sources/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon-1024.png b/Sources/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon-1024.png new file mode 100644 index 0000000000000000000000000000000000000000..ca1f689185a1fffc24171911a20bf1cecbed80bd GIT binary patch literal 34353 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 G-v0w(rh>!( literal 0 HcmV?d00001 diff --git a/Sources/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json b/Sources/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json index 13613e3..59e99f9 100644 --- a/Sources/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/Sources/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -1,6 +1,31 @@ { "images" : [ { + "filename" : "AppIcon-1024.png", + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "AppIcon-1024.png", + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "tinted" + } + ], + "filename" : "AppIcon-1024.png", "idiom" : "universal", "platform" : "ios", "size" : "1024x1024" diff --git a/Sources/Resources/Localizable.xcstrings b/Sources/Resources/Localizable.xcstrings index 68b3793..eb735e4 100644 --- a/Sources/Resources/Localizable.xcstrings +++ b/Sources/Resources/Localizable.xcstrings @@ -1,6 +1,79 @@ { "sourceLanguage" : "de", "strings" : { + "Einstellungen — ζ-5 TODO" : { + + }, + "Erkunden" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Erkunden" + } + }, + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Explore" + } + } + } + }, + "Konto" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Konto" + } + }, + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Account" + } + } + } + }, + "Lesen" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Lesen" + } + }, + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Read" + } + } + } + }, + "Öffentlicher Zitat-Korpus von mana e.V." : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Öffentlicher Zitat-Korpus von mana e.V." + } + }, + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Public quote corpus by mana e.V." + } + } + } + }, + "Phase ζ-0 — Setup" : { + + }, + "Quote vorschlagen" : { + + }, "Zitare" : { "comment" : "App name", "extractionState" : "manual", @@ -19,30 +92,9 @@ } } }, - "Lesen" : { - "localizations" : { - "de" : { "stringUnit" : { "state" : "translated", "value" : "Lesen" } }, - "en" : { "stringUnit" : { "state" : "translated", "value" : "Read" } } - } - }, - "Erkunden" : { - "localizations" : { - "de" : { "stringUnit" : { "state" : "translated", "value" : "Erkunden" } }, - "en" : { "stringUnit" : { "state" : "translated", "value" : "Explore" } } - } - }, - "Konto" : { - "localizations" : { - "de" : { "stringUnit" : { "state" : "translated", "value" : "Konto" } }, - "en" : { "stringUnit" : { "state" : "translated", "value" : "Account" } } - } - }, - "Öffentlicher Zitat-Korpus von mana e.V." : { - "localizations" : { - "de" : { "stringUnit" : { "state" : "translated", "value" : "Öffentlicher Zitat-Korpus von mana e.V." } }, - "en" : { "stringUnit" : { "state" : "translated", "value" : "Public quote corpus by mana e.V." } } - } + "ζ-3 — TODO: SwiftUI-Form + ManaAuthGate" : { + } }, "version" : "1.0" -} +} \ No newline at end of file diff --git a/project.yml b/project.yml index 06e8b0d..4e533b1 100644 --- a/project.yml +++ b/project.yml @@ -61,6 +61,10 @@ targets: CFBundleVersion: "1" CFBundleDevelopmentRegion: de CFBundleDisplayName: Zitare + # Pflicht-Key für iOS 11+ mit Asset-Catalog-Icons. Xcode setzt + # ihn nur automatisch wenn GENERATE_INFOPLIST_FILE=YES; bei uns + # ist die Info.plist XcodeGen-getrieben, also explizit hier. + CFBundleIconName: AppIcon LSApplicationCategoryType: "public.app-category.reference" UILaunchScreen: {} UISupportedInterfaceOrientations: diff --git a/scripts/make-appicon.swift b/scripts/make-appicon.swift new file mode 100644 index 0000000..64002c3 --- /dev/null +++ b/scripts/make-appicon.swift @@ -0,0 +1,89 @@ +#!/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)")