@AppStorage mit Swift-Klasse

Der Property-Wrapper @AppStorage speichert Value-Types in den UserDefaults. Will man aber ein Objekt dort speichern, muss man einige Klimmzüge machen. Um anderen das Suchen nach einer Lösung zu erleichtern ist hier meine Lösung:

Ausgangslage:

Ich erstelle eine einfache Klasse wie diese:

class Person: ObservableObject {
  @Published var name: String
  @Published var age: Int

  init() {
    self.name = ""
    self.age = 0
  }
}

Will ich diese nun als @AppStorage in den UserDefaults speichern bzw. von diesen laden:

@main
struct TestApp: App {
  var body: some Scene {
    WindowGroup {
      ContentView()
    }
  }
}

struct ContentView: View {
  @AppStorage("person") var person = Person()

  var body: some View {
    VStack {
      TextField("Name: ", text: $person.name).padding()
      TextField("Age: ", value: $person.age, formatter: NumberFormatter()).padding()
      Spacer()
    }
  }
}

Leider lässt Swift (derzeitige Version: 5.3) das so nicht zu. Klare Ansage: die Variable kann ein Value-Type sein oder muss einen rawValue haben. Als rawValue zulässig sind jedoch nur Double, Int, Bool oder String. Data ist nicht möglich.

Lösung: Die Klasse muss die Protokolle RawRepresentable und Codable verwenden.

class Person: ObservableObject, RawRepresentable, Codable {
  @Published var name: String
  @Published var age: Int

  init() {
    self.name = ""
    self.age = 0
  }

  // CodingKeys: erforderlich, damit rawValue nicht kodiert wird
  enum CodingKeys: String, CodingKey {
    case name = "name"
    case age = "age"
  }

  // init from decoder
  required init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: CodingKeys.self)
    name = try container.decode(String.self, forKey: .name)
    age = try container.decode(Int.self, forKey: .age)
  }

  // init with rawValue
  required init?(rawValue: String) {
    if rawValue.isEmpty {
      print("Initialised with empty rawValue, setting defaults")
      self.name = ""
      self.age = 0
      return
    }
    print("Initialising with rawValue: \(rawValue)")
    guard let data = try? JSONDecoder().decode(Person.self, from: rawValue.data(using: .utf8)!) else {
      self.name = ""
      self.age = 0
      return
    }
    self.name = data.name
    self.age = data.age
  }

  // encode to encoder
  func encode(to encoder: Encoder) throws {
    var container = encoder.container(keyedBy: CodingKeys.self)
    try container.encode(name, forKey: .name)
    try container.encode(age, forKey: .age)
  }

  // raw representable
  var rawValue: String {
    get {
      guard let data = try? JSONEncoder().encode(self) else {
        print("Unable to encode data")
        return ""
      }
      print("Returning raw value: \(data)")
      return String(data: data, encoding: .utf8)!
    }
  }
}

Die Funktion encode(…) ist zwingend erforderlich, da der Wert rawValue (computed property) nicht serialisiert werden darf (erzeugt anderenfalls eine Schleife).

Veröffentlicht unter Allgemein | Schreib einen Kommentar

Chicken (VNC) Catalina

Es scheint so, als wenn die Entwickler von Chicken (of the VNC) kein Interesse mehr an der Fortführung Ihres Programmes haben.

Seit Catalina scheinen alle verfügbaren Binaries nur 32-bittig zu sein und sind dadurch nicht mehr lauffähig unter macOS 10.15.

Das selber Kompilieren mit Hilfe von Xcode ist leider nicht ganz trivial, da viele Sourcen als Assembler Dateien vorliegen und nasm benötigen.

Vielleicht hilft es ja jemandem, anbei eine Binary als DMG-Datei für macOS ab 10.10 und als 64-bittige Version.

Bei mir läuft das auch problemlos auf Catalina.

Veröffentlicht unter Allgemein | Kommentare deaktiviert für Chicken (VNC) Catalina

Apache 2.2 SSL A+ Rating

SSL heisst nicht unbedingt sicher – Heartbleed, Poodle und Co. sei Dank. Auf der Qualys-Website kann man seinen Webserver auf Sicherheitslücken testen lassen.

Es gibt einige Anleitungen, eine A+ Bewertung zu erhalten. Die sind aber teilweise veraltet oder nur für Apache 2.4.

Unter Debian Wheezy habe ich mit folgenden Einstellungen mit Apache 2.2 eine A+ Bewertung erhalten:

ssl.conf:
SSLProtocol all -SSLv3 -TLSv1.1
SSLHonorCipherOrder On
SSLCipherSuite \
  DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA: \
  ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA: \
  ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA:AES128-SHA
SSLCompression Off

default-ssl.conf: (VirtualHost)
SSLOptions +StrictRequire
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"

Für die Header-Direktive im VirtualHost muss natürlich mod_header in Apache aktiviert werden.

a2enmod headers

Ergänzung: Wer keine Java-Clients unterstützen muss, kann die letzten 3 Cipher auch weglassen. Windows XP mit Internet Explorer 6/8 werden nicht unterstützt. Außerdem sollten sämtliche Betriebssystem-Updates installiert sein. Bei mir wurde mit der neuesten openssl-Version erst TLS_FALLBACK_SCSV aktiviert.

Veröffentlicht unter Allgemein | Verschlagwortet mit , , , , , , | Kommentare deaktiviert für Apache 2.2 SSL A+ Rating

iOS 7 – Teil 1

Craig Federighi stellte gestern iOS7 vor, angeblich mit den größten Änderungen seit der Einführung des iPhones.

Wenn er damit die grafische Oberfläche meint, so muss man ihm Recht geben. Das Interface wirkt wie eine Kreuzung aus Windows Phone und Android, vom „alten“ iOS ist kaum noch etwas übrig geblieben abgesehen von der Anordnung der Icons auf dem Springboard.

Lock-Screen

iOS7-02

Fangen wir doch einfach mal von vorne an: als erstes sieht man den Lock-Screen.

Sofort sticht ins Auge, dass die Status-Leiste am oberen Bildschirm-Rand optisch nicht mehr getrennt ist vom Rest des Bildschirms.

Die Empfangsstärke wird mit Hilfe von 5 Punkten dargestellt, das Batterie-Symbol ist breiter geworden und der Schriftzug des Netzbetreibers schmaler (wie eigentlich sämtliche System-Schriften).

Der Slider zum Entsperren wird nur noch durch den Text angedeutet, welcher in Slider-Richtung (von links nach rechts) einen dezenten Glüh-Effekt aufweist.

Kaum zu erkennen sind die beiden kleinen, grauen Dreicke mittig am oberen unteren Bildschirmrand, welche die Nachrichtenzentrale bzw. die Quick-Settings öffnen. Rechts unten befindet sich das Kamera-Symbol, welches den Schnellzugriff auf die Knips-Funktion erlaubt. Es handelt sich aber nicht um einen Button, sondern muss nach oben gewischt werden, was für Einsteiger vermutlich irritierend ist.

Quick-Settings

iOS7-27Die Schnell-Einstellungen können vom Sperr-Bildschirm oder Springboard aufgerufen werden, in dem man vom unteren Bildschirm-Rand mit einem Finger nach oben wischt.

Sämtliche wichtigen Einstellungen wie Flug-Modus, WLan, Bluetooth, Nicht stören und die Rotations-Sperre lassen sich in der oberen Reihe an oder aus schalten. Darunter befindet sich der Helligkeits-Regler sowie die Audio-Steuerung.

Die untere Icon-Reihe gewährt Schnell-Zugriff auf die Taschenlampe (LED-Blitz), Uhr, Taschenrechner und Kamera. Ob diese konfigurierbar sein wird, lässt sich derzeit noch nicht sagen.

Zumindest kann man sich jetzt die Installation einer Taschenlampen-App sparen, denn schneller als über die Quick-Settings kann man kein Licht machen.

Spotlight-Suche

iOS7-32Die Such-Funktion erreichte man bisher auf einem Extra-Bildschirm, der sich links von der ersten Springboard-Seite befand. Dieser Screen existiert nicht mehr. Wo also ist denn nun die Suche?

Man wischt einfach mit einem Finger von der Bildschirm-Mitte nach unten und die Suchleiste erscheint prompt am oberen Bildschirm-Rand.

Die Suche während des Eintippens fühlt sich noch sehr träge an, erste Ergebnisse erscheinen erst nach einigen Sekunden. Hoffentlich wird daran  noch kräftig gearbeitet.

Auffällig ist ansonsten nur, dass bei der Suche die Tastatur in einem dunklen Theme erscheint, so etwas hat man bisher noch nicht gesehen auf einem iPhone.

In Kürze geht es dann weiter mit Teil 2.

 

Veröffentlicht unter Allgemein | Verschlagwortet mit , , , , , , | Kommentare deaktiviert für iOS 7 – Teil 1

WWDC 2013

Gestern war WWDC-Keynote. Für mich eigentlich ziemlich enttäuschend, da für eine Multi-Milliarden-Firma wie Apple die Neuigkeiten sehr überschaubar waren. Kurz zusammengefasst:

  • Neue MacBook Air (ab sofort)
  • Neue Airport Extreme und TimeCapsule (ab sofort)
  • Vorschau auf Mac Pro (irgendwann in diesem Jahr)
  • Vorschau auf iOS7 (Herbst)
  • Vorschau auf OS X 10.9 Mavericks (Herbst?)
  • iRadio (mit iOS7, zunächst nur USA)

Ja, das war’s auch schon.

Allerdings gab es doch ein paar Sachen, die aufgefallen sind. WWDC-Keynote 2013Die Keynote war bei weitem nicht so steif wie die letzte. Stellenweise sogar witzig.

Craig Federighi und Phil Schiller haben ihre Aufgabe hervorragend gemacht; sogar Tim Cook war dieses Mal lockerer und wirkte nicht so gequält und aufgesetzt wie sonst.

Eddie Cue war sehr unauffällig, als wollte er nicht zuviel Aufmerksamkeit auf die Web-Version von iWork lenken. Apple und das Internet… eine lange und schwierige Geschichte.

Für alle, die keine Lust haben, sich die 2 Stunden anzuschauen, kommt in Kürze ein erster Überblick mit Screenshots von iOS7.

Veröffentlicht unter Allgemein | Verschlagwortet mit , , , , , , , , , , , , | Kommentare deaktiviert für WWDC 2013

Lokales TimeMachine Backup verhindern

Auf ohnehin recht knapp bemessenen SSD’s lässt sich unter MacOS X das lokale TimeMachine Backup deaktivieren. So wird der Speicherplatz, der für ältere Versionen von Dokumenten verwendet wird, wieder freigegeben. Allerdings ist es dann auch nicht mehr möglich, mit Hilfe von TimeMachine zwischen den einzelnen (lokal gespeicherten) Versionen die Änderungen sich anzuschauen.

Wenn man aber sowieso ein externes Laufwerk für TimeMachine verwendet, ist das ja nicht schlimm.

Ausschalten der lokalen Backups: sudo tmutil disablelocal

Einschalten der lokalen Backups: sudo tmutil enablelocal

Veröffentlicht unter Allgemein | Verschlagwortet mit , , , , | Kommentare deaktiviert für Lokales TimeMachine Backup verhindern

TextMate 2 auf Remote-Servern nutzen

TextMate 2 ist ein angenehmer Editor ohne großen Schnickschnack. Will man ihn im Terminal-Fenster verwenden, gab es ja schon immer den Befehl „mate“.

TextMate -> Preferences -> Terminal und dort den Shell support  installieren. Ab sofort kann man dann im Terminal z.B. „mate test.txt“ benutzen.

Im unteren Bereich der Einstellungsseite befindet sich aber der Punkt „Accept rmate connections“.

Um Remote-Server mit der Funktion von remote TextMate auszustatten, sollte auf dem Remote-Server zunächst ruby installiert werden. Ein SSH-Server ist natürlich ebenfalls voraussetzung. Dann sollte man das rmate-Script (der blaue Link auf der obigen Einstellungs-Seite) auf den Server kopieren (und natürlich darauf achten, dass es sich im Pfad befindet und ausführbar ist).

Wenn man sich nun mit dem Remote-Server verbindet und statt des normalen ssh-Befehls folgende Version verwendet: „ssh -R 52698:127.0.0.1:52698 example.com“, kann man mit „rmate test.txt“ eine Remote-Datei auf dem lokalen Mac editieren. Dafür muss TextMate nicht einmal vorher geöffnet sein.

Veröffentlicht unter Allgemein | Verschlagwortet mit , , , , , , | Kommentare deaktiviert für TextMate 2 auf Remote-Servern nutzen

Tastenwiederholung in Mac OS X Lion

Ein Mac ist doch kein iPhone… warum soll ich für ein Ö das „O“ lange gedrückt halten, um dann aus einer eingeblendeten Liste das „Ö“ auszuwählen? Stattdessen muss man auf die Tasten-Wiederholung verzichten.

keyboard

Naja, ab ins Terminal und eingeben:

defaults write -g ApplePressAndHoldEnabled -bool false

und alles ist wieder gut!

Veröffentlicht unter Allgemein | Verschlagwortet mit , , , , | Kommentare deaktiviert für Tastenwiederholung in Mac OS X Lion

Cocoa iTunes Podcasts

Liste interessanter Cocoa Podcasts (A=Audio, SD=Video geringe Auflösung, HD=Video hohe Auflösung)

Nicht mehr fortgesetzt werden:

  • Late Night Cocoa (A)
  • MacSoftwareBusiness (MacSB) (A)
  • The MDN Show (A)

Ersatz-Cast ist jetzt

  • iDeveloper (A)

Weiterhin hörens- bzw. sehenswert sind:

  • Macoun (SD)
  • Hot Cocoa (HD)
  • CocoaRadio (A)
  • cocoaFusion (A)
  • CocoaCast (A, HD)
  • XCode von NULL auf Hundert (HD, deutsch)
  • NSBrief (A)
  • Edge Cases (A)
  • Identical Cousins (A)
Veröffentlicht unter Allgemein | Verschlagwortet mit , | Kommentare deaktiviert für Cocoa iTunes Podcasts

Debian Lenny SNMP – No swap line in /proc/stat

Nach der Installation von SNMP füllten sich die Log-Dateien langsam aber sicher mit Meldungen wie

snmpd[pid]: No swap line in /proc/stat
snmpd[pid]: No page line in /proc/stat

Die Einträge kamen alle 5 Sekunden, so dass normale Meldungen kaum noch zu finden waren.

Das Umstellen des Loggings in /etc/init.d/snmpd brachte bei mir keine Abhilfe. Nach ein wenig Suchen fand ich dann unter /etc/default den Eintrag für snmpd.

Dort braucht man nur die Zeile

SNMPDOPTS='-Lsd -Lf /dev/null -u snmp -I -smux -p /var/run/snmpd.pid'

durch

SNMPDOPTS='-Lf /dev/null -u snmp -I -smux -p /var/run/snmpd.pid'

zu ersetzen, und schon herrscht Ruhe.

Veröffentlicht unter Allgemein | Verschlagwortet mit , , , , , | Kommentare deaktiviert für Debian Lenny SNMP – No swap line in /proc/stat