import Foundation /// Alles, was den Namen der App trägt — an einer Stelle. /// /// Der Name steht noch nicht fest. Damit ein späterer Wechsel nicht zur Suche /// quer durch den Quelltext wird, greift die App nirgends auf ein hart /// geschriebenes „Flixy" zu, sondern immer hierauf. Zu ändern sind dann genau /// zwei Dinge: diese Datei und `project.yml` (Produktname, Bundle-Kennung, /// Anzeigename). /// /// Die Typen aus FlixyKit behalten ihre Namen — sie sind Bauteile, keine Marke. enum Branding { /// Wie die App sich selbst nennt. static let appName = "Flixy" /// Unter welchem Namen die App in der Geräteliste des Plex-Kontos steht. /// /// Wandert in die Kopfzeile `X-Plex-Product`. Eine Änderung hier legt beim /// nächsten Anmelden einen neuen Eintrag an — der alte bleibt als Karteileiche /// stehen, bis er von Hand entfernt wird. static let plexProduct = appName /// Unter welchem Namen die Tokens im Schlüsselbund liegen. /// /// An die Bundle-Kennung gebunden statt an den Anzeigenamen: eine spätere /// Umbenennung der App soll niemanden abmelden. static var keychainService: String { Bundle.main.bundleIdentifier ?? "com.scarriffleservices.flixy" } /// Das eigene URL-Schema, über das Plex nach der Anmeldung zurückschickt. /// /// Die Bundle-Kennung statt eines kurzen Wortes wie „flixy": sie ist /// garantiert eindeutig. Bei einem kurzen Schema könnte eine andere App /// denselben Namen beanspruchen und die Anmeldung abfangen. static var urlScheme: String { Bundle.main.bundleIdentifier ?? "com.scarriffleservices.flixy" } /// Wohin Plex nach der Anmeldung zurückschickt. static var authCallbackURL: URL { URL(string: "\(urlScheme)://auth")! } /// Wann dieser Build entstanden ist. /// /// Gelesen als Änderungsdatum der eigenen Binärdatei — kein Build-Skript, /// keine erzeugte Datei, und immer richtig: die Binärdatei entsteht genau /// dann, wenn gebaut wird. /// /// Steht in den Einstellungen. Ohne diese Angabe lässt sich nicht /// unterscheiden, ob ein Fehler noch besteht oder ob nur ein alter Build /// auf dem Gerät liegt — und das kostet jedes Mal eine Rückfrage. static var buildStamp: String { guard let url = Bundle.main.executableURL, let date = try? url.resourceValues(forKeys: [.contentModificationDateKey]) .contentModificationDate else { return "—" } return date.formatted(date: .abbreviated, time: .shortened) } /// Die Version aus dem Bundle, für die Kopfzeile `X-Plex-Version`. static var version: String { Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String ?? "0" } }