Skip navigation

Hallihallo!

Im Laufe der letzten Woche habe ich eine kleine Implementierung des Simplex-Algorithmus in Matlab gestartet. Zwar besitzt Matlab schon die Funktion linprog(…), die lineare Probleme zu lösen vermag, jedoch spuckt diese Funktion nur das Ergebnis aus und gerade, wenn man ab und zu mal einen Simplex von Hand rechnen muss und am Ende nicht das richtige Ergebnis herauskommt, hat man keine Lust, mühsam nach dem Fehler zu suchen. Deshalb gibt meine Implementierung in jedem Iterationsschritt die entsprechenden Zwischenergebnisse an.
Ein Nachteil ist bisher, dass der Algorithmus sich nicht eigenständig eine geeignete Menge an Basisindizes sucht und loslegt, die müsst ihr zu Beginn selbst definieren und mitgeben. Die Übergabe des LP erfolgt wie gewohnt in Standardform.
Das vollständige Programm kann hier heruntergeladen werden: Download (via Dropbox, ca. 5KB)
Den Code dürft ihr nach Belieben bearbeiten und weiterverwenden. Viel Spaß damit!

Gruß,
Tobi

Hallöchen!

 

Die richtig coolen Webseiten haben etwas magisches an sich: Oftmals werden Dinge, die normal per Reload/Formular-Submit erfolgen, völlig instant gemacht, ohne Neuladen der Seite! Also dynamisches und effizientes Laden/Ändern von Daten. Das ist mittels AJAX möglich. Schöne Weboberflächen entstehen meist eben mit JavaScript, AJAX und natürlich jQuery!

Ich habe diese Thematik mal ein wenig runtergebrochen auf ein sehr einfaches Niveau: ein simples Login, ohne Datenbankkommunikation, einfach nur ein Dummy. Wer das Ganze später produktiv nutzen möchte, muss da noch eine Datenbankabfrage für Benutzerdaten einbauen und ganz wichtig: Inputvalidation! Auch muss natürlich am Ende dafür gesorgt werden, dass auf allen Seiten sich das Login ‘gemerkt’ wurde und so weiter!

Fangen wir mit dem Beispiel an, es kann mit allen Quellen hier heruntergeladen werden! Ihr dürft damit anstellen, was ihr wollt! Der Quellcode ist dokumentiert! :)

 

Übersicht über die benötigten Dateien:

  • index.php <- Das Login UI kommt hier rein
  • login.php <- Benutzerdatenüberprüfung wird hier gemacht
  • login.js  <- Kommunikation zwischen UI und Benutzerdatenüberprüfung
  • style.css <- Einfach nur hübsche UI gestalten
  • images/   <- In den Ordner kommen hübsche Bilder für UI

 

Also fangen wir mit der index.php an:

Unser Doctype Kram:


<!DOCTYPE html> <html lang="en">

Unser Head, mit allem, was wir brauchen:

<head>  <meta charset="utf-8">  <title>Login</title>    <link rel="stylesheet" href="style.css">    <!--[if lt IE 9]> <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script> <![endif]-->   <!-- jQuery einbinden, weil awesome -->  <script src="http://code.jquery.com/jquery-1.7.2.min.js" type="text/javascript"></script>  <!-- Ein Script einbinden, mit dem wir per 'enter' das Login starten --> <script src="http://www.openjs.com/scripts/events/keyboard_shortcuts/shortcut.js" type="text/javascript"></script>  <!-- Ein Plugin für jQuery einbinden, um die Login Falsch Funktion zu animieren --> <script src="http://gsgd.co.uk/sandbox/jquery/easing/jquery.easing.1.3.js" type="text/javascript"></script> <!-- Unser eigenes Login-Script einbinden --><script src="login.js" type="text/javascript"></script>   </head> 

Fangen wir mit dem Body an:

Hier muss die login.php eingebunden werden! Der Rest zählt nur zu hübsch.

<body>    <div id="centered">    <div id="loginArea">    <h2 style="margin-top: 12px;">Login</h2> <hr> <!-- Die login.php einbinden --> <?php require_once('login.php'); ?>

Hier folgt der Table mit den Login Feldern und dem Login Button, ein Formular ist NICHT nötig! Das funktioniert über die login() JavaScript Funktion im Login-Button.

<!-- Es folgt der LoginTable -->  <table id="login">    <tr> <td height="45"> <span style="font-size: 20px;">Username: </span> </td> <td> <input type="text" name="username" id="username" value="" /> </td> </tr> <tr> <td height="45"> <span style="font-size: 20px;">Password: </span> </td> <td> <input type="password" name="password" id="password" value="" /> </td>    </tr> <tr> <td>    </td>    <td> <input type="button" name="loginSubmit" value="Login" style="margin-left: 134px;" onclick="login()"/ </td> </tr> </table> 

 Und hier schließen wir den Login-Bereich ab und legen schon mal ein LEERES Div für den Members Only Content an:

</div>    <div id="secretDiv"> <!-- Hier wird der Inhalt NICHT direkt hineingeschrieben, sondern der Inhalt für die Members wird von der login.php zurückgegeben und per JavaScript hier eingefügt! --> </div> </div> </body> </html> 

 Weiter folgt die login.php, die wir ja schon in der index.php eingebunden haben:

Wichtig ist, es sollte nur eine Rückgabe erfolgen, wenn wirklich ein Login angestoßen wurde, da sonst die Ausgabe in der index.php erscheint, da sie ja schon eingebunden wird, ohne, dass erst ein Login erfolgte! Weiterhin wird hier die Dummy-Loginfunktion gestartet. Also, es werden die Benutzerdaten geprüft und es wird ein Output erzeugt, der entweder sagt, dass das Login fehlgeschlagen ist oder erfolgreich war.

<?php    /* Durch das require_once in der index.php, wird die Datei schon ohne Login aufgerufen. Ein Loginversuch soll aber erst versucht werden, wenn Benutzerdaten per POST übergeben wurden. */   if (isset($_POST['username']) && isset($_POST['password'])){ // Hier müsste noch Input-Valdidation durchgeführt werden $user = $_POST['username']; $password = $_POST['password'];    // Das hier ist nur Dummy, eigentlich kommte hier wahrscheinlich eine Datenbankabfrage if ($user == "tutorial" && $password == "123456"){ echo getLoginOKReturnString(); }else{ echo getLoginFailReturnString();  } }   

 Hier kommen die Funktionen, die die Rückgabe für den jeweiligen Status erzeugen:

/* Beim Zurückgeben hier muss folgendes beachtet werden: Die JavaScript Funktion und der HTML Inhalt, der Members only ist, darf NICHT schon in der index.php oder der login.js stehen, da man sonst auch ohne Zugangsdaten mit der Seite arbeiten kann. Darum müssen alle Daten, die ein Login benötigen, nur aus einer Datei zurückgegeben werden, die ein Login durchführt bzw. überprüft, ob eine Session für den Benutzer existiert. Bitte auch nicht den Inhalt für die Member Area in eine andere JS/HTML Datei schreiben, da diese auch ohne Login angezeigt werden können! */    // Das Javascript und HTML zurückgeben, das dem User sagt, dass das Login erfolgreich war und zeigt ihm das Hidden-Feature  function getLoginOKReturnString(){ return "<center><h1 class=\"shadow\">Here's your secret: <br><br><p style=\"font-size: 84px\" class=\"shadow\">42</p></h1></center>";    }    // Das Javascript und HTML zurückgeben, das dem User sagt, dass seine Daten nicht korrekt waren  function getLoginFailReturnString(){ return "0";   } ?>

Die login.js, die Datei, die für die Kommunikanten zwischen index.php und login.php zuständig ist.

Hier wird direkt nach dem Laden ein wenig Code ausgeführt:

Das Hauptdiv wird vertikal zentriert, weil’s hübsch sein soll. Auch für den Loginbutton brauchen wir einen Enter-Button-Trigger, den binden wir mit einem 3rd Party JavaScript ein. Das meiste JavaScript hier ist jQuery, weil’s einfach awesome ist.

// Wird beim Abschließen des Ladens der Seite aufgerufen  $(document).ready(function() { // Vertikal das Haupt-Center-DIV zentrieren var x = $(document).height(); x = (x-240)/2; $("#centered").css('margin-top',x); // Fügt der Enter-Taste der Tastatur einen Observer hinzu, der beim Drücken der Taste unsere Login Funktion aufruft  shortcut.add("enter", function() {  login();  }); }); 

 Hier ist die eigentliche, wichtige, Funktion für die Kommunikanten: Die Loginfunktion macht einen POST Request an unsere login.php und verarbeitet dessen Rückgabe:

// Die Login Funktion, um die Benutzerdaten zu prüfenfunction login(){ // Die Benutzerdaten aus der HTML auslesen und in einer Variable zwischenspeichern var username = $("#username").val(); var password = $("#password").val(); /* Einen Ajax-POST Request an unsere login.php senden mit unseren Benutzerdaten. Wenn der Request erfolgreich war, wird dessen Rückgabe (alles, was 'ausgegeben' wurde (also per echo z.B.)), an eine anonyme Funktion als Wert 'requestData' übergeben. Innerhalb der anonymen Funktion können diese Daten jetzt verarbeitet werden, um zu prüfen, ob der Login erfolgreich war.   */ $.post("./login.php", { username: username, password: password }, function(requestData){ // Wir geben von der login.php '0' zurück, wenn die Benutzer/Passwort-Kombination falsch war if (requestData == "0") { /* Also die Funktion aufrufen, die dem Benutzer zurückgibt, dass seine Daten nicht korrekt waren. Wenn die Daten richtig waren, geben wir ja das anzuzeigende HTML/JavaScript zurück. */ wrongPassword(); }else{ /* Statt 'else' sollte man hier natürlich noch eine eindeutige Validation machen! Es könnte auch 'else' aufgerufen werden, wenn ein PHP Fehler aufgetreten ist! */   // Anzeigen des secretDiv $('#loginArea').fadeOut('slow', function() {   // Setzen wir also jetzt die Rückgabe der login.php als Inhalt des secretDivs $('#secretDiv').html(requestData); $('#secretDiv').fadeIn(); });   }   }); }

 

Hier kommt eine Funktion, die ausgeführt wird, sobald die Benutzerdaten nicht richtig sind:

Es wird dabei das Login-Div 'geschüttelt', wie unter OS X. Für die Bewegung benutzen wir ein jQuery 'Easing' Plugin. 

// Eine Funktion, die aufgerufen wird, wenn das Passwort/Benutzer nicht richtig waren. Sie lässt das Login-Div sich 'schütteln'. function wrongPassword(){   $("#centered").animate( { marginLeft: "+=25px" }, { duration: '20', easing: 'easeOutBounce' }) .animate( { marginLeft: "-=50px" }, { duration: '20', easing: 'easeOutBounce' }) .animate( { marginLeft: "+=25px" }, {   duration: '20', easing: 'swing' });   } 

 Der Style Kram ist unwichtig, den könnt ihr euch beim Runterladen anschauen! :)

 So jetzt viel Spaß damit und bei Fragen dürft ihr die gern stellen! :)

 

Q

Hallöchen,

hier mal für alle, die so etwas suchen, ein PHP Script, das eure gesamten Tables einer Datenbank sichert. Es ist auch eine Wiederherstellungsfunktion vorhanden, das Ganze kann per HTTP-GET bedient werden und komprimiert mit gzip die Backups.

Auf GitHub: https://gist.github.com/2930377

Viel Spaß damit, Jan

Mit diesem Artikel möchte ich noch einmal das Thema bzg. Synchronisieren von Push Notifications unter iOS kurz vor der WWDC12 abhandeln.

Was man schon öfter mal gelesen hat ist ein Problem, das ich auch kenne:

Man besitzt mehrere Apple Geräte, bekommt eine Twitter-Reply und liest diese auf dem iPhone. Geht man nun an sein iPad, ist die Reply immer noch im Notification Center, obwohl man sie gelesen hat.

Was Leute dazu sagen:

Warum lässt sich das nicht synchronisieren?

 

Also schauen wir einmal, was Push-Notifacations überhaupt sind:

Push-Notifications sind Benachrichtigungen, die einem Prinzip folgen: Push statt Pull. Man verlagert dabei den Prozess des Informationen-Suchens auf stärkere Geräte, die Server und informiert den Client dann via Push Notification über die neuen Informationen. Es wäre für den Client sehr von Nachteil, wenn er das Informationen-Suchen übernehmen müsste, denn dann müsste er quasi sekündlich (eher öfter) prüfen, ob es neue Informationen gibt.

 

Push, or server push, describes a style of Internet-based communication where the request for a given transaction is initiated by the publisher or central server. It is contrasted with pull, where the request for the transmission of information is initiated by the receiver or client.

(http://en.wikipedia.org/wiki/Push_technology)

Push Notifications sind also Benachrichtigungen über neue Informationen (Daten) von einem Server, der nach Informationen (Daten) sucht. Eigentlich ein zentrales System, der Server verwaltet es. Nicht der Client! (Nur mal so angemerkt: Das ist für mich der Hauptgrund, warum eine Synchronisation der Clients eigentlich ungünstig ist, denn nicht der Client sollte diese Arbeit verrichten, sondern, wenn überhaupt, der Server!)

Was viele Benutzer denken, was Push-Notifications sind:

Eine Benachrichtigung im Notification Center, die ich drücken kann und damit interagieren kann oder löschen kann. Dabei wird eben oftmals gedacht, dass man in jedem Fall mitbekommt, wenn eine solche Benachrichtigung eintrifft, denn man sieht sie ja im Notification Center oder an der Zahl der App (Badge).

Auch das ist wiederum falsch, denn Push-Notifications benötigen kein visuelles Feedback! Auch während eine App geöffnet ist, kann sie Push Notifications empfangen! Nur der User bekommt es nicht so mit, sondern denkt eher „Ah ok, die App hat die Daten neu geladen”. Stimmt eben nicht, diese Daten hätten auch via Push kommen können!

Also noch mal: Der Sinn von Push-Notifications ist es, Daten an den Client zu übergeben, damit der nicht so viel Arbeit hat!

Was man auch beachten sollte: Oft sind Push Notifications nicht nur Information sondern auch REaktion. Der Client soll oftmals mit diesen Daten auch eine AKTION ausführen.

Wenn jetzt jemand hingehen würde und Push Notifications synchronisieren wollte, könnte es gut sein, dass ein flüssiges Streaming von zum Beispiel Tweets nicht mehr flüssig ist, weil er gerade seinen Twitter Client auf zwei Geräte offen hat. Viel schlimmer: Beim Synchronisieren von Push Notifications gehen Daten verloren, die ein Server für den Client für wichtig hielt! Ein doofes Beispiel für sowas wäre ein pushbased Messenger: Auf dem iPad hat man die Nachricht gelesen, geht man nun ans iPhone und schaut in den Verlauf, fehlt da vielleicht (auch nur für einen kurzen Moment, bis die App die Daten dann wirklich per Pull neu lädt) die aufs iPad gepushte Nachricht. Dieses Verhalten ist mir bei iMessage schon des Öfteren aufgefallen (iMessage synchronisiert bereits die Benachrichtigungen), gepushte Nachrichten waren auf dem iPad, gehe ich ans iPhone sind dort die aufs iPad gepushten (und somit synchronisierten) Nachrichten noch nicht. Erst nach kurzer Ladezeit, wurden diese reingeladen.

Wer also Push Notifications synchronisieren will, enthält den Apps ihre Daten vor. Diese machen dann *mimmimi* und der Benutzer regt sich auf, weil er ständig warten muss, bis gepullt wurde.

Resultat: Ganz großes *mimimimii das ist total scheiße*  und wenig Nutzen.

 

 

Fazit:

Die Idee ist gar nicht mal so doof, aber ohne große strukturelle Umordnung nicht realisierbar. Selbst wenn Apple das anbietet mit iOS6, wird am Ende hoffentlich der Programmierer entscheiden, ob diese Daten synchronisiert werden dürfen oder nicht. Weil alles Andere gäbe Chaos im großen Stil. Des Weiteren wäre es wünschenswert, wenn jetzt nicht alle Entwickler ihre alten Push Dienste umbauen müssten deswegen. Es wird mir zwar nicht jeder glauben, aber es ist eine menge Arbeit Server- und Clientkommunikation noch einmal umzubauen.

 

Wer sich schon jetzt *mimimimi* ansehen möchte, warum das denn alles nicht ‘gut’ ist, darf mal freundlich hier vorbei klicken:
„iOS Notifications sind komisch”
 

 

Q

Warum ich finde, dass das iOS Homescreenkonzept fehlerhaft ist und überholt werden muss:

1. Der iOS Homescreen ist nie für das iPad konzipiert worden
Man sortiert seine Apps auf dem iPad nach eigenen Konzepten, richtig? Klar, jeder macht das! Es macht ja auch Sinn, die eigene Ordnung auf dem Homescreen zu nutzen, um sich selbst effizienter zu recht zu finden– so ist das am iPhone auch vorgesehen gewesen und funktioniert genan so. Aber was macht das iPad damit? Genau, das iPad sortiert sich selbst, wenn man den Orientation-Modus ändert. Die Reihen verändern sich. Gern hat man beispielsweise immer links die ersten drei wichtigsten Apps zum Thema „soziale Netze“ und an vierter Stelle von links einen Ordner mit weiteren Apps zu diesem Thema. Sortiert man so und rotiert das iPad vom Portrait in den Landscape-Mode, sortiert das iPad um und eine Reihe hat nicht mehr vier Apps sondern fünf. Schon verrutscht alles. So sollte das garantiert im Konzept nicht sein, daraus kann man folgern, dass das Konzept eben nie für das iPad entworfen wurde, sondern einfach nur übertragen.

20120415-120706.jpg

20120415-120714.jpg

2. „Multitasking“ ist im iOS Homescreenkonzept nie vorgesehen gewesen
2.1 Dass das „Multistasking“ kein Wirkliches ist, wissen wir wohl alle. Wenn man sich jetzt mal ein bisschen näher mit der Implementierung des „Multitasking“ beschäftig, fällt auf, dass hier ein schwerer Designfehler präsentiert wird. Und zwar kennt man aus quasi jedem Betriebssystem ein “X” als einen Schließenbutton für ein Fenster. Wofür wird er in iOS auf dem Homescreen verwendet? Richtig: um eine App zu löschen. Es würde ohne das Multitasking ja nicht mal auffallen. Aber was wird im Homescreenkonzept verwendet, um eine App. zu schließen (also aus der Multitaskingbar zu ntfernen)? Genau. Ein rotes “-”. Ein Minus steht für mich für ein Löschen einer App. Warum ist das alles so? Sehr wahrscheinlich, weil Apple das auffiel mit der Implementierung des „Multitasking“ zwar auffiel aber es auch sehr unangemessen wäre das jetzt im Nachhinein nach mehreren Jahren noch zu ändern. Es müsste eben genau umgekehrt sein. Ein rotes Minus als Löschenbutton und ein schwarzes “X” als Schließenbutton. Man sieht also hier, dass Apple „Multitasking“ nie im Konzept des Homescreens vorsah.

20120415-124434.jpg

20120415-124448.jpg

2.2 Die Multitaskingbar ist unnötig. Ja natürlich, weil sie, zumindest bei mir, einfach nur alle Apps enthält, die ich auch auf dem Homescreen habe. Nur eben anders sortiert, nach letzter Verwendung. Als Ersatz dafür hat man am iPad die vier/fünf-Fingergesten. Nun, hier kann man noch einen Sinn in dieser Bar sehen. Aber insgesamt ist sie überflüssig, weil diese Bar eben nur die Apps anzeigt, die auch auf dem Homescreen sind. Weil ganz ehrlich, schließen muss man diese Apps ja nicht. Die meisten arbeiten ja gar nicht im Hintergrund, das sind die Wenigsten. Die meisten liegen einfach im RAM und warten darauf, wieder geöffnet zu werden. Sie verbrauchen also keine reale Leistung bzw. Akku, da sie einfach nur im Arbeitsspeicher liegen. Tja, also wozu noch schließen? RAM haben die iOS-Geräte heute genug. Das iPad 3rd Generation sogar einen ganzen Gigabyte. Es ist also aus meiner Sicht sinnfrei, dass es diese Bar gibt. Auch, weil Apple unter Lion die Politik vertritt, es soll dem Anwender doch egal sein, wieviele Apps laufen, deshalb entfernte Apple die kleinen Punkte im Dock unter dem laufenden Programm im Desktopbetriebssystem. Also, warum nicht auch unter iOS? Klar ist es ein mobiles Gerät bzw Smartphone, aber eben mit Leistung um das zu ermöglichen.
Natürlich hat die Multitaskingbar als zweites Feature die Lautstärkereglung und die Helligkeiterglung bzw Wiedergabeeinstellungen, aber was war der Hauptzweck der Multitaskingbar? Wohl doch eher die Apps, die laufen. Stellt sich also heraus, diese Bar ist mehr oder weniger überflüssig.

20120415-125727.jpg

Insgesamt sind das nur drei kleine Dinge die mir auffielen, auch das Dock verliert meiner Meinung nach durch die Folder seine Bedeutung. Ich glaube, dass Apple mit dem neuen iOS 6th Generation vieles ändert. Unter Anderem erwarte ich:
- Apple entfernt die Multitaskingbar
- Apple fördert Exposé unter iOS
- Apple fügt mindestens am iPad Benutzerverwaltung hinzu
- Apple ändert sehr wahrscheinlich den Löschenbutton nicht.
- Apple könnte das Dock entfernen, aber doch eher unwahrscheinlich, weil es auch in OS X fundamentaler Bestandteil des Desktops ist

Q

Huhu!

Ich wurde gebeten hier mal etwas über die Kommunikation in Cocoa mit MySQL zu berichten.
Fangen wir also gleich an! (Hier konkret beschrieben als iOS-App)

Was brauchen wir?
- Eine SQL Datenbank
- Einen Table den wir in einem UITableView darstellen wollen
- Daten im Table, der Table muss einen autoincrement id Tag haben
- Einen PHP Wrapper
- Einen SQL2JSON Wrapper
- Ein bisschen Geduld!

Hier einmal den Source zur PHP API unserer App:

require_once("db.php");

$id = $_GET["id"];

$sql = "SELECT * FROM ourTable WHERE id = '$id'";
$string = sql2json($sql);

echo $string;

// Diese Wrapper-Funktion ist nicht von mir, allerdings finde ich den Link nicht mehr, wo ich sie gefunden habe!

//Function will take an SQL query as an argument and format the resulting data as a
// json(JavaScript Object Notation) string and return it.
function sql2json($query) {
$data_sql = mysql_query($query) or die("'';//" . mysql_error());// If an error has occurred,
// make the error a js comment so that a javascript error will NOT be invoked
$json_str = ""; //Init the JSON string.

if($total = mysql_num_rows($data_sql)) { //See if there is anything in the query
$json_str .= "[\n";

$row_count = 0;
while($data = mysql_fetch_assoc($data_sql)) {
if(count($data) > 1) $json_str .= "{\n";

$count = 0;
foreach($data as $key => $value) {
//If it is an associative array we want it in the format of "key":"value"
if(count($data) > 1) $json_str .= "\"$key\":\"$value\"";
else $json_str .= "\"$value\"";

//Make sure that the last item don't have a ',' (comma)
$count++;
if($count < count($data)) $json_str .= ",\n";
}
$row_count++;
if(count($data) > 1) $json_str .= "}\n";

//Make sure that the last item don't have a ',' (comma)
if($row_count < $total) $json_str .= ",\n";
}

$json_str .= "]\n";
}

//Replace the '\n's - make it faster - but at the price of bad redability.
$json_str = str_replace("\n","",$json_str); //Comment this out when you are debugging the script

//Finally, output the data
return $json_str;
}

In der db.php im gleichen Verzeichnis muss die SQL Verbindung hergestellt werden:
$dbname="our_dbname";
$dbhost="our_dbhost";
$dbuser="our_dbuser";
$dbpass="our_dbuserpassword";

mysql_connect($dbhost,$dbuser,$dbpass);
mysql_select_db($dbname);
?><\code>

Wichtig um die gesamt Anzahl an Einträgen zu bekommen benötigen wir noch eine PHP Datei im gleichen Verzeichnis:

require_once("db.php");

$sql = "SELECT * FROM ourTable";
$result = mysql_query($sql) OR die("

\n".$sql."

\n".mysql_error());

$num_rows = mysql_num_rows($result);

echo $num_rows;

?>

Mit diesem Code können wir für eine ID den Inhalt der Datenbank als JSON darstellen. Der ID Tag muss per GET übergeben werden.

Hinweis! Es ist wichtig, dass ihr die Datensätze nacheinander (id für id) und nicht alle auf einmal ausgebt, da das am Ende in JSON oft langsam wird bzw. die maximale Größe des Datensatzes überschreitet!

Hinweis! Es scheint Probleme mit bestimmten Sonderzeichen beim Einlesen des JSON Codes zu geben.

In unserem Xcode Project benötigen wir einen UITableViewController und eine Klasse, die sich um die Kommunikation kümmert.
Das Gute an Objective-C ist in diesem Fall, dass das NSDictionary quasi mit JSON arbeiten kann. Ab 10.7 und iOS5 gibt es eine NSJSONSerilisation, die aus dem gefetchten NSData einer NSURLConnection ein NSDictionary macht. Man kann dann also mit [myJSONDict objectForKey:@"xy"]; aus dem JSON Dictionary den Wert Auslesen. Der Key ist der Name der Spalte aus der Datenbank und das Object die hinterlegte Information.
Man könnte also zB. jetzt den Wert 'id' wie folgt auslesen:
int id = [[myJSONDict objectForKey:@"id"] intValue];

Was wir jetzt also machen:
Den UITableViewController laden und von diesem aus in der viewDidLoad Methode anfangen die Daten zu laden. Und zwar so, dass jedes geladene Item aus der Datenbank direkt in den TableView geladen wird.
Wir ermitteln also erst die Anzahl der Datensätze und wenn wir diese haben, gehen wir durch eine Schleife mit Countbedingung.
In der Schleife können wir dann mit der aktuellen Schleifencountvariable eine NSURLConnection an die API mit der aktuellen id (eben die Schleifenvariable) stellen. Da ich empfehle GCD zu nutzen, wird eine synchrone Verbindung aufgebaut, die ein NSDate ausgibt mit dem JSON Code. Dieses NSData wird in ein NSDictionary umgewandelt und dann per NSNotification als UserInfo mitgesendet. Der UITableViewController observiert diese Nachricht und fügt das NSDictionary dem dataArray des UITableViewController hinzu und lässt dann den TableView neuladen.
So werden Schrittweise alle Daten geladen und angezeigt.
Durch den id Tag ist es auch möglich nur die 15 neusten Item der Datenbank zu laden.

Der SampleCode für das Xcode Project folgt in Kürze!

Viel Spaß damit,
Q

Hey Leute!

Apple möchte für die Apps im MacAppStore seit geraumer Zeit (!) das AppSandboxing per Pflicht einführen, zur Sicherheit des Users.
Nun, dass AppSandboxing funktionieren kann, zeigt iOS. Dort rennt jede App in einem Sandkasten, erfolgreich.
Aber unter OS X gestaltet es sich auch für Apple scheinbar schwieriger, da man es nachträglich integriert.
Beispielsweise würde damit die Wahrscheinlichkeit, dass eine App das Adressbuch auf die eigenen Server lädt verringert, da der Entwickler bestimmte Zugriffe »beantragen« muss. Wenn also eine Dateisynchronisations-App um Adressbuchzugriff bittet, wird im MAS Review auffallen, dass die App das Adressbuch gar nicht ‘braucht’ und somit wird der Antrag abgelehnt und die App rejected.

Nun zu dem Zeitablauf der Geschichte:
Apple versuchte bereits die Deadline bis zum November 2011 einzuhalten, da dies sich immer noch schwierig gestaltete wurde der Termin auf den ersten März 2012 verschoben.
Heute gab Apple bekannt, dass die Deadline auf den 1. Juni 2012 aufgeschoben wurde.
Interessant oder? Eine Firma wie Apple, die tatsächlich die ganzen Bugs im Sandboxing zum wiederholten Male nicht pünktlich fixen kann?
Nun, ich kann nur bestätigen, dass das Sandboxing noch sehr fehlerhaft ist. Probleme bereiten mir das Pathobserving und der Auto-Start beim Login.

Hoffen wir mal, dass Apple das bald in den Griff bekommt und sich nicht weiter blamiert.

Q.

Eine kurze Anmerkung meiner Seits zu 10.8.

Apple wird in die Sicherheitseinstellung ‘GateKeeper’ integrieren. Dieses Feature sorgt dafür, dass der User einstellen kann, welche Arten von Programm installiert werden dürfen.
Man kann wählen zwischen ‘MAS Apps’, ‘von verifizierten Entwicklern’ (Mac Dev Programm wird benötigt) und ‘anywhere’.

Unterschwellig wird hier dem User suggeriert nur MAS Apps zu installieren und den offenen Markt von Programmvertrieb von OS X Programmen zu meiden.

Damit entwickelt sich aus meiner Sicht ein iOS im OS X. Ein geschlossenes System, in das keiner reinkommt. Hier eben die unterschwellige Manipulation des Users.

Ich finde es echt nicht schön. 10.6.6 hat byteproject es schon erwähnt, es wird ein geschlossenes System. OpenSource wird für OS X abgeschafft.

Danke, Apple.

Q.

Huhu!

Da ich momentan selbst auch oft mit dem kleinen Problem kämpfe, dass viele custom Frameworks/Classes, die man benutzen möchte, kein ARC supporten hier ein kleines Workaround, wenn man trotzdem weiterhin ARC in seinem Projekt benutzen möchte.

Man gehe in Xcode/Project/Build Phases/Compile Sources.
Dort wählt man die Sources an, die man von ARC ausschließen möchte und fügt rechts bei den Compiler flags folgendes ein:

-fno-objc-arc

Das war’s und sollte auch so funktionieren! :)

Q

Tag!

Im Zuge des Xcode3 PPC-Buildings wollte ich mir ein Test-Run vereinfachen.
Und zwar müsste ich für einen Test-Run die App immer manuell auf den PPC Ziel Rechner übertragen. Das ist natürlich extrem aufwendig, daher hab ich mir da was ausgedacht, was (vielleicht auch für Euch) praktisch sein kann.

Plan: Xcode bei einem Build sagen, dass es nach dem Build die App auf den Remote Rechner kopiert und dort ausführt.

Umsetzung:
1. Xcode: Rechtsklick auf »Targets/Add/New Build Phase/New Run Script Build Phase/«.
2. Wenn sich kein Fenster öffnet: Targets aufklappen, AppName aufklappen, Doppelklick auf »Run Script«.
3. In besagtem Fenster können alle Voreinstellungen übernommen werden.
4. Anpassen dieses Scripts: Gist für Eure Laufzeitumgebungen. Und in das Script Fenster einfügen. Ein spezielles Speichern des Scripts ist nicht nötig, das Fenster kann einfach geschlossen werden. Warnungen und Fehler werden in der Log ausgegeben.

Viel Spaß damit und bei Fragen, kommentieren.

Q