Translation by Jonas Pencke (@jonaspencke)

iOS-Framework: Einführung in MKNetworkKit

Wie genial wäre es, wenn sich ein Networking-Framework automatisch ums Cachen der Antworten kümmern würde?
Wie genial wäre es, wenn sich ein Networking-Framework automatisch alle noch auszuführenden Operationen merken würde, wenn der Client offline geht?
Im Offline-Zustand könnten somit Tweets favorisiert oder Feeds als gelesen markiert werden und das Networking-Framework würde sich um die Aufnahme aller Operationen kümmern, sobald das Gerät wieder online ist. Und dies alles ohne zusätzlichen Programmieraufwand? Herzlich Willkommen bei MKNetworkKit.

Was ist MKNetworkKit?

MKNetworkKit ist ein in Objective-C geschriebenes Networking-Framework, welches sich nahtlos integriert, Blocks verwendet, ARC ready ist und sich einfach verwenden lässt. Inspiriert wurde MKNetworkKit von zwei anderen bekannten Networking-Frameworks, namens ASIHTTPRequest und AFNetworking. Der Funktionsumfang beider wurde zusammengeführt und mit neuen zusätzlichen Funktionen erweitert. Im Vergleich mit anderen Frameworks schreibt man beim Verwenden von MKNetworkKit ein wenig mehr Code, was jedoch zu klarerem bzw. besser lesbarem Code führt. Mit MKNetworkKit ist es schwierig, unschönen Networking-Code zu schreiben.

Funktionen

Extremes Leichtgewicht
Das komplette Framework besteht im Wesentlichen aus 2 Hauptklassen und ein paar Kategorien. Aus diesem Grund sollte das Anpassen von MKNetworkKit ziemlich einfach von der Hand gehen.

Die gesamte Applikation benutzt eine einzige globale Queue
Apps die sehr stark von einer Internet-Verbindung abhängen, müssen sich um die Optimierung bei der Anzahl der gleichzeitig genutzten Netzwerk-Operationen kümmern. Bisher gibt es leider kein einziges Networking-Framework, was dies von Haus aus korrekt erledigt. Nachfolgend gebe ich euch ein Beispiel für Probleme, die auftreten können, wenn die Anzahl der gleichzeitig ablaufenden Netzwerk-Operationen in einer App nicht kontrolliert bzw. optimiert wird.
Angenommen wir möchten einige Fotos auf einen Server (z.B. Color oder Batch) laden. Die meisten mobilen Netzwerke (3G) sind dabei auf maximal 2 gleichzeitige HTTP-Verbindungen von der gleichen IP-Adresse beschränkt. Das bedeutet, dass von einem Gerät gleichzeitig nicht mehr als 2 HTTP-Verbindungen in einem 3G Netzwerk geöffnet werden können. Bei EDGE ist es oft sogar noch schlimmer bzw. sind weniger Verbindungen erlaubt. In den meisten Fällen verfügt man dort nur über eine einzige Verbindung. Das Limit von 6 in einem gewöhnlichen Breitbandnetz (Wifi) wirkt demgegenüber relativ hoch. Da die Verbindung von einem iDevice mit einem Wifi-Netzwerk jedoch nicht immer gesichert ist, sollte man auch auf eingeschränktere Netzwerk-Verbindung vorbereitet sein. Im Normalfall sollte das iDevice jedoch mit einem 3G-Netzwerk verbunden sein. Demzufolge ist es möglich 2 Fotos gleichzeitig hoch zu laden. Dabei ist die langsame Upload-Geschwindigkeit nicht das größte Problem. Das eigentliche Problem tritt auf, wenn z.B. ein View geöffnet wird, der mehrere Thumbnails (sagen wir auf einem anderen View) lädt, während im Hintergrund die anderen Upload-Operationen noch laufen. Wenn nun die Queue-Größe über die App hinweg nicht ordnungsgemäß gehandhabt wird, können die Download-Operationen der Thumbnails mit einem Timeout abbrechen, was nicht wirklich sinnvoll ist. Besser wäre es die Download-Operation der Thumbnails zu priorisieren oder solange zu warten, bis der Upload der Fotos fertig gestellt ist, um danach das Laden der Thumbnails zu beginnen. Damit das funktioniert, braucht man eine (einzige) globale Queue für die gesamte App. MKNetworkKit stellt genau dieses Prinzip automatisch sicher, indem es für jede Instanz eine globale Queue anlegt und verwendet. MKNetworkKit ist selbst kein Singleton, aber die globale Queue schon.

Netzwerk-Aktivitätsanzeige korrekt darstellen
Während viele Klassen und Bibliotheken von Drittanbietern ein einfaches In- bzw. Dekrementieren der Anzahl der Netzwerk-Anfragen verwenden, um den Aktivitätsindikator anzuzeigen, basiert die MKNetworkKit Aktivitätsanzeige auf dem Prinzip der global geteilten Queue. Durch das Observieren (KVO) der “operationCount” Property, wird die Aktivitätsanzeige immer dargestellt, solange noch eine Operation in der gemeinsamen Queue abgearbeitet wird. Für den Entwickler entfällt damit das manuelle Verwalten der Netzwerk-Aktivitätsanzeige.

Automatisches Testen der Queue-Größe
Vorhin wurde erwähnt, dass die meisten mobilen Netzwerke gleichzeitig nicht mehr als 2 Verbindungen erlauben. Aus diesem Grund sollte bei einer 3G Netzwerkverbindung die Queue-Größe auf 2 gesetzt werden. Dies wird automatisch von MKNetworkKit erledigt. Verschlechtert sich die Verbindung von Wifi zu 3G/EDGE/GPRS, dann passt MKNetworkKit für dich die Anzahl der erlaubten gleichzeitigen Verbindungen an – in diesem Fall auf 2. Selbstverständlich wird die Queue-Größe wieder zurück auf 6 gesetzt, sobald dem Gerät erneut ein Wifi Netzwerk zur Verfügung steht. Dieser Ansatzes bringt eine erhebliche Performance-Verbesserung beim Laden von Thumbnails (oder mehreren ähnlichen kleinen Anfragen) für eine Foto-Galerie von einem Remote-Server über 3G.

Automatisches Caching
MKNetworkKit kann automatisch alle “GET”-Anfragen cachen. Wird die gleiche Anfrage ein weiteres Mal ausgeführt, so ruft MKNetworkKit den “CompletionHandler” mit der gecachten Version der Antwort (wenn diese vorliegt) direkt auf. Wenn die Daten vom Server erfolgreich geladen wurden, wird der “CompletionHandler” ein weiteres Mal mit der neuen Antwort aufgerufen. Das bedeutet, dass das Cache-Handling nicht manuell gemacht werden muss. Alles was dafür notwendig ist, ist das Aufrufen der folgenden Methode.

In von MKNetworkEngine abgeleiteten Klassen können bei Bedarf Methoden überschrieben werden, um den Cache-Ordner und die “in-memory” Cache-Kosten einzustellen.

Freezen (einfrieren) von Operationen
MKNetworkKit bietet die Möglichkeit Netzwerk-Operationen einzufrieren. Wenn eine Operation eingefroren wird, z.B. beim Verlust der Netzwerkverbindung, werden die Operation automatisch serialisiert und wieder ausgeführt, sobald das Gerät wieder online kommt. Dies ist vergleichbar mit “Drafts” in einem Twitter- oder Email-Client.
Wenn ein Tweet gepostest wird, kann der Netzwerk-Aufruf als “freezable” markiert werden und MKNetworkKit übernimmt automatisch das Einfrieren und Wiederherstellen der Anfragen. Das heißt, dass fast kein extra Code geschrieben werden muss, um die Tweets später abzuschicken. Dies kann auch für andere Operationen, wie dem Favorisieren eines Tweets oder Sharen eines Posts von einem Google Reader Client, Hinzufügen eines Links zu Instapaper oder ähnlichen Operationen genutzt werden.

Führt exakt eine Operation für gleiche Anfragen aus
Beim Laden von Thumbnails (von einem Twitter Stream), wird oft für jedes einzelne Avatar Bild eine neue Anfrage erzeugt. In der Realität sollte jedoch die Anzahl der Anfragen gleich der einzigartigen URLs sein. MKNetworkKit führt jede GET Anfrage die in die Queue kommt nur exakt einmal aus. HTTP POST-Anfragen werden logischerweise nicht von MKNetworkKit gecacht.

Image Caching
MKNetworkKit kann einfach zum Cachen von Thumbnails genutzt werden. Durch das Überschreiben einiger weniger Methoden kann die Anzahl der Bilder, die im in-Memory-Cache gehalten werden sollen und der Speicherort im Cache-Directory eingestellt werden. Das Überschreiben dieser Methoden ist aber komplett optional.

Performance/Leistung
Nur ein einziges Wort: Geschwindigkeit. Das Cachen von MKNetworkKit ist nahtlos (seamless). Es arbeitet wie NSCache, jedoch mit der Ausnahme, dass beim Auftreten einer Speicherwarnung der in-Memory-Cache in den Cache Ordner geschrieben wird.

Volle Unterstützung von Objective-C ARC
Normalerweise wird für ein neues Projekt ein neues Netzwerk-Framework genommen. MKNetworkKit ist eigentlich nicht dafür gedacht existierende Frameworks zu ersetzen (obwohl es möglich ist, ist es meistens ein recht aufwendiger bzw. ermüdender Job). Neue Projekte sollten eigentlich immer ARC verwenden. Als dieser Artikel geschrieben wurde, war MKNetworkKit das einzige Networking-Framework, das komplett ARC fertig ist. ARC basierte Speicherverwaltung ist generell um eine Größenordnung schneller als die Speicherverwaltung ohne ARC.

Wie wird es benutzt
Ok genug des Eigenlobes. Lasst uns schauen, wie das Framework benutzt werden kann.

Hinzufügen des MKNetworkKits

1. Ziehe den MKNetworkKit Ordner in dein Projekt.
2. Füge das CFNetwork.Framework, SystemConfiguration.Framework und Security.Framework hinzu.
3. Inkludiere MKNetworkKit.h zu deiner PCH Datei
4. Lösche die NSAlert+MKNetworkKitAdditions.h Datei falls es ein iOS Projekt ist.
5. Lösche die UIAlerView+MKNetworkKitAdditions.h Datei falls es ein Mac Projekt ist.

Das war’s. Mit nur 5 Core Dateien verfügst du über ein mächtiges Networking-Kit.

Klassen in MKNetworkKit

1. MKNetworkOperation
2. MKNetworkEngine
3. Verschiedene Helferklassen (Apple’s Verfügbarkeits-Klasse (Reachability)) und Kategorien

Ich glaube an Einfachheit und Apple hat den schweren Job beim Schreiben des richtigen Networking-Codes bereits erledigt. Was ein Drittanbieter Netzwerk-Framework ermöglichen sollte, ist ein elegantes Queue basiertes Networking mit optionalem Caching. Ich glaube daran, dass jedes Drittanbieter-Framework weniger als 10 Klassen besitzen sollte (unabhängig davon ob es sich dabei um Networking handelt oder eine UIKit Ersetzung oder irgend etwas anderes). Mehr als das ist zu aufgebläht. Three20 sowie ShareKit sind Beispiele für eine aufgeblähte bzw. überfrachtete Bibliothek. Es kann sein, dass sie an sich gut sind, aber trotzdem bleiben sie riesig und total aufgebläht. ASIHttpRequest oder AFNetworking sind im Vergleich zu RESTKit schlank und somit wirkliche Leichtgewichte. Ebenfalls ist JSONKit ein Leichtgewicht, anders als TouchJSON (oder alle anderen TouchCode Bibliotheken). Es kann natürlich sein, dass nur ich Wert darauf lege, aber in meinem Source-Code soll nicht jede dritte Zeile von einer Drittanbieter-Bibliothek stammen.

Die Schwierigkeit bei einem großen und unüberschaubarem Framework ist, das Verständnis für die interne Funktionsweise und die Möglichkeit das Framework an die eigenen Bedürfnisse anzupassen (falls nötig). Meine Frameworks (wie MKStoreKit, das In-App-Verkäufe zu deiner App hinzufügt) konnten immer super einfach verwendet werden und ich glaube, dass dies auch für MKNetworkKit gilt. Um MKNetworkKit zu benutzen, musst du nur die öffentlichen Methoden der beiden Klassen MKNetworkOperation und MKNetworkEngine kennen. MKNetworkOperation ist der ASIHttpRequest Klasse recht ähnlich. Es ist eine Unterklasse von NSOperation und bilder einen Wrapper um deine Request- und Response-Klassen. In einer Applikation wird dann für jede benötigte Netzwerkoperation eine neue MKNetworkOperation erzeugt.

MKNetworkEngine ist eine Pseudo-Singleton Klasse, die die Netzwerk-Queue der Applikation verwaltet. Es ist in dem Sinne ein Pseudo-Singleton, da für einfache Anfragen die MKNetworkEngine Methoden direkt genutzt werden können. Für größere Anpassungen sollte jedoch eine von MKNetworkEngine ableitende Klasse erzeugt werden. Jede von MKNetworkEngine ableitende Klasse besitzt von Haus aus ihr eigenes Reachability Objekt, das sie über Server-Verfügbarkeitsänderungen notifiziert. Für jeden einzelnen REST-Server, den du verwendest, sollte eine eigene abgeleitete Klasse von MKNetworkEngine erzeugt werden. Es ist in diesem Sinne Pseudo-Singleton, da jede einzelne Anfrage, in egal welcher Subklasse, durch die eine globale Queue geht.

Instanzen deiner MKNetworkEngines können wie die CoreDataManagedObjectContext Klasse im “ApplicationDelegate” gespeichert werden. Beim Verwenden von MKNetworkKit werden Unterklassen von KNetworkEngine erzeugt, um die Netzwerk-Anfragen logisch zu gruppieren. Das bedeutet, dass alle Yahoo-relevanten Methoden in einer gemeinsamen Klasse und alle zu Facebook gehörenden Methoden in einer anderen Klasse liegen. Im Folgenden schauen wir uns drei Beispiele für die mögliche Verwendung des Frameworks an.

Beispiel 1

Lasst uns nun eine “YahooEngine” erzeugen, die aktuelle Wechselkurse von “Yahoo finance“ lädt.

Schritt 1:

Erzeuge einer “YahooEngine”-Klasse als abgeleitete Klasse von MKNetworkEngine. Die init-Methode der MKNetworkEngine bekommt als Parameter einen Host-Namen und bei Bedarf einen benutzerdefinierten Header. Die benutzerdefinierten Header sind optional und können “nil” sein. Wenn ein eigener REST Server geschrieben werden soll (anders als in diesem Fall), könnte dort die Client-App-Version und andere sonstige Daten, wie ein Client-Identifier hinzugefügt werden.

Settings headers

Dabei ist zu beachten, dass yahoo einen eigentlich nicht zwingt einen “x-client-identifier” im Header mitzuschicken. Zum Zeigen des Features wurde es aber im obigen Code-Beispiel hinzugefügt.

Da der komplette Code ARC verwendet, ist es die Aufgabe des Entwicklers eine Engine Instanz zu speichern (starke Referenz).

Wenn eine abgeleitete Klasse von MKNetworkEngine erzeugt wird, wird dazu automatisch die Reachability-Implementierung hinzugefügt. Das bedeutet, wenn der Server nicht mehr zu erreichen ist oder irgendwelche unvorhersehbaren Umstände eintreten, z.B. dass der Host nicht erreichbar ist, werden die Anfragen automatisch eingefroren. Für weitere Informationen bezüglich des Einfrieren von Operationen, schaut in der Sektion “Freezing Operations” etwas weiter unten nach.

Schritt 2:

Design der Engine Klasse (Trennung der Zuständigkeiten)
Nun kümmern wir uns um das Schreiben der “YahooEngine”-Methoden, welche die Wechselkurse abfragen. Die Engine-Methoden werden aus dem ViewController heraus aufgerufen. Eine gute Design-Angewohnheit ist, sicherzustellen, dass die Engine-Klasse die URL/HTTP-Headers nicht an die aufrufende Klasse weitergibt bzw. offenlegt. Der View braucht keine Informationen über die URL-Endpunkte oder andere Parameter. Das bedeutet, dass Parameter in Methoden der “YahooEngine” die Währungen und die Anzahl der Währungseinheiten sein sollten. Der Rückgabewert dieser Methode könnte ein double sein, der den Wechselrate-Faktor beschreibt und eventuell den Zeitstempel, wann es abgefragt wurde. Da die Operationen nicht synchron ausgeführt werden, sollten die Werte

Code snippet 1

mit Hilfe von Blocks zurückgegeben werden. Ein Beispiel hierfür wäre das folgende:

Blocks

Die Basisklasse MKNetworkEngine definiert drei Typen von Block-Methoden, siehe unten:
In unserer “YahooEngine” nutzen wir eine neue Art von Block, “CurrencyResponseBlock”

Code block 2

der die Wechselrate zurück liefert. Die Definition sieht wie folgt aus:
In jeder normalen Applikation sollten eigene Block-Methoden – ähnlich wie der “CurrencyResponseBlock” – zum Zurücksenden von Daten zum View Controller definiert und genutzt werden.

Schritt 3:

Verarbeitung der Daten
Die Datenverarbeitung, die die vom Server geholten Daten – unabhängig ob es JSON, XML oder “Binary Plists” sind – umwandelt, sollte in der Engine durchgeführt werden. Noch einmal, die Controller sollten von dieser Aufgabe befreit werden. Die Engine sollte die Daten in passenden Model-Objekten oder Arrays von Model-Objekten (im Falle von Listen) zurück liefern. JSON/XML sollte deshalb in den Engines zu Modellen umgewandelt werden. Nochmals, um die richtige Aufteilung der Zuständigkeiten sicherzustellen, sollte der ViewController nicht über die Schlüssel (Keys) verfügen, um auf einzelne Elemente im JSON zugreifen zu können.

Dies fordert das Design der Engine bzw. lässt sich daraus schließen. Die meisten Networking Frameworks zwingen einen nicht, diesem Paradigma des “Separation of Concerns” zu folgen. Wir machen das, weil wir uns um euch kümmern :)

Schritt 4:

Methoden Implementierung
Wir werden nun die Implementierungsdetails der Methode diskutieren, die die Währungsumrechnungen durchführt.

Das Abgreifen der Währungsinformationen von Yahoo ist so einfach wie eine normale GET-Anfrage. Hierfür habe ich ein Makro geschrieben, welches die URL für ein zu

Defines

übergebendes Währungsformat formatiert.
Die Methoden, die in dieser Engine Klasse geschrieben werden, sollten die folgenden Sachen in ebendieser Reihenfolge tun.

1. Die URL aus den Parametern zusammenstellen.
2. Für die Anfrage ein MKNetworkOperation Objekt erzeugen.
3. Die Parameter der Methode setzen.
4. “Completion” und “ErrorHandler” zu der Operation hinzufügen (Der “CompletionHandler” ist dabei der richtige Platz, um die zurückgelieferten Antworten zu verarbeiten und in entsprechende Modelle zu konvertieren.)
5. Optional können “ProgressHandler” zur Operation hinzugefügt werden. (Oder aber im View Controller)
6. Falls die Operation ein Datei-Download ist, muss ein Download-Stream (im Normalfall eine Datei) gesetzt werden. Dies ist wiederum optional.
7. Wenn die Operation fertig ist, muss das Resultat weitergereicht und die Block-Methode aufgerufen werden, um die Daten zur aufrufenden Methode zurückzugeben.

Code block currency

Das ist im Folgenden dargestellt
Der obige Code formatiert die URL und legt eine MKNetworkOperation an. Nachdem die “Completion” und “ErrorHandler” definiert wurden, wird die Operation durch das Aufrufen der Superklassenmethode “enqueueOperation” in die Queue aufgenommen und liefert eine Referenz davon zurück. Der “ViewController” sollte diese Operation speichern und sie abbrechen, wenn der View aus der View-Hierarchie herausgeschmissen wird. Deshalb sollte, wenn die Engine Methode sagen wir in “viewDidAppear” aufgerufen wird, die Abbruch Operation in “viewWillDisappear” aufrufen. Das Abbrechen der Operation ermöglicht der Queue, andere Operationen des nächsten Views durchzuführen (Denkt dran, dass in einem mobilen Netzwerk nur zwei Operationen gleichzeitig verarbeitet werden können. Deshalb ist das Abbrechen von Operationen, wenn sie nicht mehr benötigt werden, eine Grundvoraussetzung, um Performance und Geschwindigkeit der App sicherzustellen).

Der View Controller kann zusätzlich (bei Bedarf) einen “ProgressHandler” hinzufügen und darüber das User Interface aktualisieren. Dies ist nachfolgend dargestellt.

Progress block

Die MKNetworkEngine besitzt zudem Standardmethoden, um eine Operation nur aus einer URL zu erzeugen. Aus diesem Grund könnte die erste Zeile des Codes auch wie folgt

Create op

geschrieben werden
Beachten muss man, dass die bei der Initialisierung der Engine Klasse angegebenen Hostnamen automatisch vor die Request-URLs gesetzt werden.

Das Erzeugen einer POST, DELETE oder PUT Methode ist so einfach wie das Ändern eines Parameters einer http Methode. Die MKNetworkEngine besitzt noch mehr Standardmethoden wie diese. Mehr Informationen findet ihr in den header Dateien.

Beispiel 2

Hochladen eines Bildes zu einem Server (zum Beispiel zu TwitPic).
Lasst uns nun durch ein Beispiel schauen, in welchem ein Bild zu einem Server geschickt wird. Beim Hochladen eines Bildes muss die Operation offensichtlich als “multi-part form data” encodiert werden. Dabei folgt MKNetworkKit einem ähnlichen Pattern wie ASIHttpRequest. Durch den Aufruf der Methode “addFile:forKey:” in der MKNetworkOperation wird der Anfrage eine Datei als “multi-part form data” “hinzugefügt”. Es ist wirklich so einfach.
MKNetworkOperation hat zudem eine Standardmethode, um ein Bild von einem “NSData” Pointer hinzuzufügen. Das heißt, dass die Methode “addData:forKey:” direkt von einem “NSData” Pointer aufgerufen werden kann, um ein Bild zu einem Server zu schicken. (Interessant ist dies zum Beispiel beim direkten Hochladen eines gerade mit der Kamera geschossenen Bildes.)

Beispiel 3

Herunterladen von Dateien in einen lokalen Ordner (Caching).
MKNetworkKit ermöglicht das einfache Laden einer Datei von einem Remote-Server sowie das Speichern in einer Lokation auf dem iPhone des Benutzers.
Dafür muss nur der “outputStream” der MKNetworkOperation gesetzt werden und man ist

Stream

fertig.
Es können mehrere “Output Streams” zu einer einzelnen Operation hinzugefügt werden, um die gleiche Datei an mehreren Stellen zu speichern (zum Beispiel im Cache Ordner sowie im “Working” Ordner)

Beispiel 4

Thumbnail-Caching
Beim Herunterladen von Bildern muss eher eine absolute URL als ein Pfad angegeben werden. DIE MKNetworkEngine hat dafür eine Standard-Methode. Verwende einfach die Methode “operationWithURLString:params:httpMethod:” um eine Netzwerk-Operation mit einer absoluten URL zu erzeugen.
Die MKNetworkEngine ist intelligent, da sie mehrere GET-Anfragen zur gleichen URL zu einer einzigen zusammenführt und alle Blocks, wenn die eine Operation fertig ist, notifiziert. Dies verbessert drastisch die Geschwindigkeit beim Abgreifen von Bild-URLs für bekannte Thumbnails.

Leite die MKNetworkEngine ab und überschreibe den Bild Cache Ordner und die Cache-Kosten. Wenn diese beiden Einstellungen nicht individuell angepasst werden sollen, können auch direkt die MKNetworkEngine-Methoden zum Download von Bildern genutzt werden. Dies ist sogar empfehlenswert.

Caching Operationen
MKNetworkKit speichert standardmäßig alle Anfragen zwischen. Alles was dafür getan werden muss, ist das Cachen für die Engine anzuschalten. Wenn eine GET-Anfrage ausgeführt wird und die Antwort vorher bereits zwischengespeichert wurde, dann wird der “CompletionHandler” sofort mit der gecachten Antwort aufgerufen. Um zu wissen, ob die Antwort eine zwischengespeicherte ist oder nicht, kann die Methode “isCachedResponse”

Cache

genutzt werden. Dies ist im Folgenden illustriert:

Freezing-Operationen
Eines der wahrscheinlich interessantesten Features von MKNetworkKit ist die integrierte Möglichkeit, Operationen einfrieren zu können. Alles was dafür benötigt wird, ist die Operation als “freezable” zu markieren. Dies erfordert quasi keinen Aufwand.
Eingefrorene Operationen werden automatisch serialisiert, wenn die Netzwerk-Verbindung abbricht, und wieder aufgenommen, wenn eine neue Netzwerk-Verbindung besteht. Denkt über die sich bietenden Möglichkeiten nach, z.B. kann ein Tweet als Favorit markiert werden während man offline ist und die Operation wird später, wenn man wieder online ist, automatisch ausgeführt.
Eingefrorene Operationen werden ebenfalls auf der Festplatte persistiert, wenn die App in den Hintergrund tritt und auch automatisch fortgeführt, wenn die App wieder in den Vordergrund kommt.

Standardmethoden der MKNetworkOperation
Die Klasse MKNetworkOperation bietet folgende Standardmethoden, um das Daten-Format der Antwort zu bestimmen:

1. responseData
2. responseString
3. responseJSON (only on iOS 5)
4. responseImage
5. responseXML
6. error

Diese Methoden sind relativ praktisch beim Zugreifen auf die Antwort nach einer beendeten Netzwerk-Operation. Wenn das Format falsch ist, liefern die Methoden “nil” zurück. Wenn zum Beispiel versucht wird auf “responseImage” zuzugreifen, obwohl die aktuelle Antwort eine HTML Antwort ist, wird “nil” zurückgeliefert. Die einzige Methode, die garantiert das richtige und erwartete Resultat zurück liefert, ist “responseData”. Die anderen Methoden sollten benutzt werden, wenn der Typ der Antwort bekannt ist.

Sinnvolle Makros
Die Makros, “DLog” und “ALog” sind frecherweise von Stackoverflow geklaut und leider kann ich die Quelle nicht mehr finden. Falls du diese Makros geschrieben haben solltest, lass es mich wissen.

Eine Bemerkung zu GCD
Ich habe absichtlich GCD nicht verwendet, da Netzwerk Operationen bei Bedarf gestoppt und priorisiert werden müssen. GCD kann dies, obwohl es effektiver als NSOperationQueue ist, nicht. Ich empfehle GCD-basierte Queues nicht für Netzwerk-Operationen zu verwenden.

Dokumentation
Die Header-Files sind dokumentiert und ich probiere gerade das “headerdoc” von Apple aus. Währenddessen kannst du ein wenig mit dem Code herumspielen bzw. ihn verwenden (read: Fork).

Source Code
Der Source Code für das MKNetworkKit ist zusammen mit einer Demo-Applikation auf Github verfügbar.
MKNetworkKit bei Github

Anfragen für neue Funktionen
Bitte schickt mir keine Email für Funktionen, die ihr gerne in der Zukunft hättet. Der beste Weg ist ein Issue auf Github zu erzeugen.

Lizenz
MKNetworkKit ist unter der MIT Lizenz lizensiert.

Der gesamte Source Code kann unentgeltlich in deiner App genutzt werden, wenn ein Copyright Hinweis in der App angezeigt wird. Eine kleine Erwähnung in den tiefsten Winkeln deiner “About”-Seiten reicht aus.

Eine Attribution freie Lizenz kann auf Nachfrage stattgegeben werden. Kontaktiert mich unter mknetworkkit@mk.sg

Follow me on Twitter