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>
This commit is contained in:
parent
c0260fa55f
commit
7b4cb13afe
5 changed files with 194 additions and 24 deletions
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
@ -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:
|
||||
|
|
|
|||
89
scripts/make-appicon.swift
Normal file
89
scripts/make-appicon.swift
Normal file
|
|
@ -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)")
|
||||
Loading…
Add table
Add a link
Reference in a new issue