NSTableView mittels NSSortDescriptor aber ohne NSMutableArray sortieren

Wie schon im letzen Post gesagt versuche ich mich gerade in einer kleinen Mac App. Ein Desktop-Programm bringt ganz andere UI-Konzepte mit als eine mobile App auf dem Smartphone. Beispielsweise können natürlich auf dem Desktop Tabellen mehrere Spalten haben – dies ist auf iOS und co. ja eher unüblich.

Irgendwie war es für mich ein bisschen irritierend eine Lösung zu finden wie ich den Inhalt einer NSTableView ohne die Benutzung eines NSMutableArrays aber mit NSSortDescriptor sortieren kann. Ich will so gut wie möglich den NS-Namespace in modernen Swift Anwendungen vermeiden. Sprich: Array statt NSArray, String statt NSString, etc.

Dank dem NSHipster habe ich eine fast schöne Lösung gefunden. Fast schön da diese etliche Forced-Casts enthält die man ja eigentlich immer versucht zu vermeiden. Falls also jemand eine bessere Idee hat, nur her damit!

Schlussendlich musste ich nur folgende paar dinge tun und schon sortiert sich mache NSTableView als hätte sie noch nie was anderes getan.

  1. Jeder sortierbaren Spalte einen SortDescriptor Key geben. Entweder über Quelltext oder (wie ich) über den Attributes Inspector in Xcode
    Attribute Inspector
  2. Im NSTableViewController die folgende NSTableViewDelegate-Methode hinzufügen:
    // MARK: - NSTableViewDelegate -
    extension ParserViewController: NSTableViewDelegate
    {
        func tableView(tableView: NSTableView, sortDescriptorsDidChange oldDescriptors: [NSSortDescriptor])
        {
            myList = (myList as NSArray).sortedArrayUsingDescriptors(tableView.sortDescriptors) as! Array
            tableView.reloadData()
        }
    }

Et viola, schon klappt es auch mit der Sortierung.

Eigene (Meta-) Daten im Swipe-Down-Menü in tvOS anzeigen

Man sollte sich immer neuen Dingen offen gegenüber zeigen. Aus diesem Grund habe ich vor wenigen Tagen mir fest vorgenommen in meiner Freizeit an einer kleinen App für den neuen AppleTV mit tvOS zu arbeiten. Um alles möglichst simpel zuhalten ist diese im Grunde nur eine auf zwei Views basierende Anwendung zum Aussuchen und Betrachten von Videos.

Gerade bei so kleinen “Ausprobiert”-Projekten stolpert man immer mal wieder über kleine Features die man hätte die sich in der Realisierung dann doch in die länge ziehen. Macht ja nix, ist ja Freizeit.

Swipe down Apple TV

Einer der beiden Views ist, wie sollte es auch anders sein, ein Video Player im Vollbild. Genauer gesagt ein AVPlayer (Referenz) samt hierzu passenden AVPlayerViewController (Referenz).

Auf der letztjährigen WWDC wurde das Feature des “zusätzliche Informationen”-Menüs des Apple TVs gezeigt. Hierzu wischt man, meist im Vollbild eines Videos, auf der Fernsteuerung von oben nach unten. In der gleichen Bewegung erscheint hierbei eine halb transparentes, graue Fläche mit fest definierten Werten. Im Standardfall sind dies “Info” und “Audio”. Diese Bereiche werden aus den Metadaten des Videos gespeist.

An dieser Stelle eines vorne weg: Große Kudos an den Stackoverflow Post Jeff Bowen zur Aufarbeitung dieses Themas! Falls ihr noch nach simplen Code für dieses Problem sucht folgt dem Link zu Stackoverflow.

Nun gibt es Fälle wo das Video diese Metadaten nicht besitzt oder mann diese gern Ändern möchte. Um dies zu tun muss man dem AVPlayerItem (Referenz) des aktiven AVPlayers eine Liste von AVMutableMetadataItem (Referenz) mitgeben.

Ein solches AVMutableMetadataItem benötigt zwingend vier Werte ohne dieses es zwar fehlerfrei baut und deployed jedoch nicht dargestellt wird. So ist neben der Locale auch der keySpace (Übersicht) und der key für das entsprechend Metadatenschlüsselwort (Übersicht) nötig. Als viertes wird in String-Form noch der eigentliche Wert benötigt.

Schlussendlich stopft man also die Metadaten in ein PlayerItem, dieses in einen AVPlayer und dieser steckt in seinem AVPlayerViewController. Apple könnte hier ruhig einmal an ihrer Dokumentation arbeiten.

Dank der tollen Sprachfeatures von Swift kann man jedoch vieles von diesem Boilerplate-Code in eine schöne Extension packen. Somit wart man die Übersichtlichkeit.

Aus all diesem ergibt sich nun bei mir der folgende Code

Extension

extension AVMutableMetadataItem
{
    /// Creates a meta data item for the swipe-down-menu of tvOS's information view
    ///
    /// - parameter avMetadataCommonKey: AVMetadataCommonKey identifier string
    /// - parameter value: String value for the key
    /// - return: Created and defined AVMutableMetadataItem object
    class func createItemWith(AVMetadataCommonKey avMetadataCommonKey: String, value: String) -> AVMutableMetadataItem
    {
        let item        = AVMutableMetadataItem()
        item.locale     = NSLocale.currentLocale()
        item.keySpace   = AVMetadataKeySpaceCommon
        item.key        = avMetadataCommonKey
        item.value      = value

        return item
    }
}

Benutzung

        let playerItem  = AVPlayerItem(URL: videoUrl)
        let titleItem   = AVMutableMetadataItem.createItemWith(AVMetadataCommonKey: AVMetadataCommonKeyTitle, value: videoTitle)

        playerItem.externalMetadata.append(titleItem)
        let playerViewController = AVPlayerViewController()
        playerViewController.player = AVPlayer(playerItem: playerItem)

Immer schön alle Kombinationen abtesten – auch bei einem Badge Generator

Bilder sagen mehr aus tausend Worte. Wie wahr. Fies wird es wenn Bilder Worte anzeigen sollen. Fieser wird es wenn diese Worte in dutzenden verschiedenen Sprachen auf dem gleichen Bild zu sehen sein sollen.

Microsoft App Store Badge

Ein solcher kleiner Fauxpas ist eventuell Microsoft mit ihrem App Store Bade Generator passiert. In den meisten Sprachen mit kürzeren Worten passt der Slogan “” ohne Probleme herein. Nur eben im ausschweifenden Deutsch fehlt der letzte Buchstabe. Alles jedoch nicht weiter schlimm so lange man nicht auf den Microsoft Store angewiesen ist räusper.

Ich habe heute via Twitter diesen Umstand dem offiziellen deutschen Microsoft Developer Account gemeldet. Mal sehen ob auf dieses Feedback reagiert wird.

Begriffe der Amazon Web Services einfach erklärt

Große Firmen neigen dazu ihre Produkte aufzuspalten, dutzende Namen zu vergeben welche jedoch nicht immer auf den ersten Schlag erkennen lassen um was es eigentlich geht.

AWS in plain english

Amazon ist hier mit dem Angebot an AWS-Produkten keine Ausnahme. Ein hilfreicher Beitrag auf expeditedssl.com versucht dies für die englische Sprache zu lösen. Mir zu mindestens hat es sehr geholfen wenn meine Twitter timeline einmal wieder sich über Outages oder neue Features eines bestimmten Amazon Dienstes ausließ.

Hey, have you heard of the new AWS services: ContainerCache, ElastiCast and QR72? Of course not, I just made those up.

But with 50 plus opaquely named services, we decided that enough was enough and that some plain english descriptions were needed.

Nach etwas stöbern dürfte somit zu mindestens manche Begriffe wie EC2, IAM, WAF und SNS etwas klarer sein.

Die “Bayer und der Würschtlmann” – App ist nun verfügbar

Öfters brauchen Wochenendprojekte gern einmal länger als was man am Anfang dachte. Genau so verlief es auch mit der dbudwm App für iOS. Vor allem wenn man zwischenzeitlich die Entwicklung von Applikationen für Apples mobiles Betriebsystem hauptberuflich ausübt ist man nie zufrieden – schließlich lernt man ja jeden Tag dazu und will dies auch in der eigenen App verwirklichen.

Screen Shot 2016-01-16 at 22.13.31

Nunmal ist jedoch auch jedes Hobbyprojekt an einem Punkt angelangt wo man sagen kann “jo, passt jetzt schon – irgendwie”. Genau an diesem Punkt bin ich jetzt die Wochen gekommen. Ja, man kann noch soviel verbessern, einbauen, optimieren aber wie es jetzt ist, ist es auch vorerst okay.

Für mich ist genau dies wichtig zu erleben. Dass etwas ‘fertig’ wird. Man alle Stufen inklusive der Veröffentlichung im Store einmal durchspielt hat ohne vorzeitig das Handtuch zu werfen. Durch kleinere Verbesserung weiß ich nun mittlerweile auch wie das mit dem Einreichen von Aktualisierungen und Co. im Store abläuft – man lernt eben nie aus.

Funktionsumfang

Wie auf den Bildern zu erkennen ist es hauptsächlich ein RSS Reader der etwas mehr als nur die Überschrift der Artikel anzeigen kann. Mit einer Wischgeste auf dem jeweiligen Post kann man diesen favorisieren oder teilen. Die anderen beiden Views sind neben der Favoritenansicht auch ein Verwaltungsfenster um Einstellungen zurückzusetzen oder Informationen zu App abzurufen.

Was (noch) nicht geht sind Offline-Cache, Pushes, und was einem sonst noch so an Features einfallen würde.

iphone-6-list

Fairerweise muss ich hier aber zugeben, dass manche Funktionalität wie die Anzeige des Artikelbildes sehr mit der heißen Nadel gestrickt wurde und eventuell in Zukunft leicht brechen kann.

Bezug

Die App steht in Apples iTunes App Store natürlich kostenfrei für das iPhone 4 bis iPhone 6s Plus zum Herunterladen bereit.

Download_on_the_App_Store_Badge_DE_Source_135x40

Hinweis

Aus all den oben beschriebenen Gründen seht diese App bitte als “Real Life Playground” meinerseits an. Dieser muss nicht zwingend immer funktionieren, hoch optimiert sein oder meine Fähigkeiten komplett repräsentieren. In der Freizeit soll man, meiner Meinung nach, auch mal was nur zum Spaß machen dürfen.

“Zurück-Tasten-Druck” innerhalb einer Windows 10 mobile App unterstützen

Etwas wirr aber scheinbar dennoch gewollt. Bestätigt man innerhalb einer Windows 10 mobile App den Hardware “Zurück”-Button so kommt man zurück auf den Home-Screen – genau das Verhalten des mitten “Windows”-Buttons. Um das Feature “Gehe-eine-Navigationsebene-zurück” zu ermöglichen, muss in der jeweiligen Code-Behind-Datei der entsprechenden XAML-Page zwei, drei Zeilen Quelltext hinzugefügt werden.

Back Button

1. Im Konstruktor auf das System Event hören

public InfoPage()
{
    InitializeComponent();
    SystemNavigationManager.GetForCurrentView().BackRequested += OnAppBackRequested;
}


2. Den in 1. angehängten Event-Handler mit Leben füllen

Hierbei prüft man einfach ob ob der Request valide ist. Fall er dies ist wird das Event als abegehandled angesehen und ein Frame zurück gesprungen.

private void OnAppBackRequested(object sender, BackRequestedEventArgs e)
{
    Frame frame = Window.Current.Content as Frame;
    if (frame == null || !frame.CanGoBack || e.Handled) return;

    e.Handled = true;
    frame.GoBack();
}

So etwas kann man auch ideal in eine eigene Subklasse der Page-Klasse packen. Eventuell benötigt man in Zukunft öfters solche kleinen Helferlein im Umfeld der Microsoft Universal Platform Entwicklung.

Kurzer Einblick in iOS9 Storyboards mit Xamarin

Ja ich gebe zu, das verlinkte Video auf Channel 9 ist weder lang noch aussagekräftig noch sehr tiefgreifend. Jedoch zeigt es für mich zum ersten mal auf einfachste Weiße wie man eigentlich in Xamarin mit iOS 9 Storyboards umgeht / umgehen muss.

Capture

Als Xcode Benutz wirkt alles verständlich und fast identisch. Da in meinem Verständnis Xamarin sich die Aufgabe gestellt hat plattformübergreifende Entwicklung für mobile Systeme zu ermöglichen frage ich mich, wie ein Java Android Enwtickler hiermit zu Recht kommen würde. Eventuell verstehe ich es aber auch nur falsch. Mal sehen ob in Zukubft vermehrt mit dieser Technologie zusammebstoßen werde.

Wer sich ebenfalls weiter umschauen will der kann sich auch andere Videos auf Channel 9 von diesem MVP zu genau diesem Thema ansehen.