Nachrichten getagged: myFirstApp

Meine erste iPhone App – Folge 12

Von , 26. September 2011

WupperTourActionSheetEs freut mich, dass iOS5 so langsam für den Otto-Normal-Verbraucher in Sicht kommt. Einhergehen sollte der Release nämlich mit Xcode 4.2, welches ich (in der beta Version) für diese App Entwicklung genommen habe. Damals unwissend, dass Apple es verbietet Apps in den App Store zu stellen, die mit einer beta Version der Entwicklungsumgebung entwickelt wurden. Meine Planung ist, spätestens im November mit der App im Store zu sein und ich fände es äusserst deprimierend, eine fertige App nicht veröffentlichen zu dürfen. Aber was habe ich eigentlich gemacht in den letzten Tagen seit dem letzten Update? Es gibt nun einen “locate me” Button in der Karten Ansicht, nach dessen Betätigung Google Maps einem die aktuelle Position anzeigt und dort hinein zoomt. Zusätzlich gibt es einen weiteren Button um per “ActionSheet” (siehe Bild) den Karten-Typ zu wechseln. Zum Beispiel kann eine Karte ohne Satellitenansicht manchmal übersichtlicher sein, wenn man bestimmte Strassen sucht. Ebenfalls fertig ist das Overlay der eigentlichen Route. Also eine durchgezogene Linie anhand derer man erkennen kann, wo man lang laufen muss um von POI zu POI zu kommen. Das wird zwar erst mit iOS4 wirklich gut unterstützt, allerdings sehe ich das zur Orientierung als absolut notwendig an. Wer mit erscheinen von iOS5 nächsten Monat nicht mal auf der 4er Version ist, dem ist ohnehin nicht mehr zu helfen. Leider sind diese Overlays nicht wirklich trivial, aber ich habe in den weiten des Internet ein gutes und vorallem übersichtliches Beispiel gefunden, das mich zur korrekten Lösung geführt hat. Der Muster Code von Apple scheint mir da doch arg überfrachtet und aufgeblasen zu sein! Zu guter letzt habe ich nochmal am Audio Management gefeilt. Es wird nun auch der “Play” Button aktualisiert, wenn die Abspielung des Audio Files beendet ist und eingehende Anrufe sorgen für die automatische Unterbrechung und nahtlose Wiedergabe nach dem Beenden des Anrufes.

Meine erste iPhone App – Folge 11

Von , 14. September 2011

pinViewIm Vergleich zum holprigen Start geht es derzeit Schlag auf  Schlag und ich kann fast wöchentlich ein Update zum Fortschritt abliefern, was mir eine persönliche Freude ist. Nichts ist motivierender als sichtbarer Erfolg! Diese sichtbaren Erfolge sind im heutigen Fall auch hörbare, da ich das Audio Management fertig gestellt habe. Es lassen sich nun in allen Ansichten die entsprechenden Tonausgaben abspielen (derzeit Test Aufnahmen). Ein Etapenziel dabei war, dass der Ton auch beim Wechsel der Ansicht weiter spielt, bis er zuende ist oder eine andere Audiodatei ausgewählt wird. Lobet die Objektorientierte Programmierung! Entgegen meiner bisherigen Planung, komme ich glücklichweise ohne eine aufwändige Audio-Bedienleiste aus, was der Übersichtlichkeit der GUI zugute kommt. Quasi “Ein-Knopf-Betrieb”, der meiner Meinung nach genügen sollte. Die beta Tester werden es dann später merken, ob das langt. ;)

Ein weiterer Meilenstein ist die Finalisierung der POI Stationen. Nach dem Testrundgang (siehe letzter Artikel) hatte sich noch Änderungsbedarf herausgestellt, der nun umgesetzt worden ist. Ich konnte daher die POI Liste einbauen und vor allem die entsprechenden Bilder verlinken. Auf jeder Detailansicht tauchen nun die zugehörigen Bilder in der Reihenfolge auf, in der man beim Ablaufen der Stadtführung die Umgebung erlebt. Ich hoffe das wird als Orientierungshilfe ausreichend dienen können. Weiter in Arbeit befinden sich die eigentlichen Texte der POI’s, welche hoffentlich in den nächsten Wochen fertig gestellt werden. Erst dann können für die oben genannte Audio Infrastruktur die Aufnahmen im Tonstudio gemacht werden.

Last but not least habe ich das Grundgerüst fertig, damit die POI’s als kleine Stecknadeln auf der Kartenansicht dargestellt werden. Was noch fehlt ist die Möglichkeit, diese auswählen zu können und direkt zur Detailansicht zu gelangen. Ausserdem sind im Datenmodel derzeit bis auf 3 Testeinträge noch keine Positionsangaben hinterlegt. Hier muss ich mir mithilfe von Google Maps noch die genauen Koordinaten (Längen- und Breitengrade) zu jedem POI heraussuchen und in der XML Datei hinterlegen.

Meine erste iPhone App – Folge 10

Von , 29. August 2011

Screenshot_WupperTour_110829So langsam nimmt die App tatsächlich Form an und es war an der Zeit, den Stadtrundgang zu validieren. So sind wir also etwa 5h bei schönstem Wetter durch Wuppertal gelaufen und haben haufenweise Notizen gemacht, an dem Rundgang gefeilt und zu jedem POI mehrere Bilder geschossen. Insgesamt sind es 270 Stück geworden, die nun aussortiert werden wollen, da 1-3 Bilder pro POI reichen sollten. Dann ist mir bewusst geworden, dass die POI’s Luftlinie teilweise recht nah beieinander liegen, weswegen wir einige zusammenfassen mussten. Sobald die letzte Programmieraufgabe – die eigentliche Führung per GPS – umgesetzt ist und zumindest beta Stadium erreicht hat, werden wir den Rundgang erneut gehen. Da wird sich dann herausstellen, ob das so funktioniert wie geplant. Die Dauer der Stadtführung sollte (bequem gegangen) bei etwa zwei Stunden liegen und ist meiner Meinung nach sehr schön und zeigt “alle” Facetten die Wuppertal ausmachen. Sobald die Stationen nach unseren Änderungen sauber definiert und ausformuliert sind, werde ich die Datenübernahme vornehmen und die Bilder auswählen und hinzufügen. Das technische Grundgerüst der POI Detail Anzeige für die Texte und Bilder ist auch bereits fertig und gefällt mir eigentlich sehr gut. Ich mag GUI‘s, die schlicht und schlank sind, besonder wenn ich mit meiner mangelnden kreativen Ader eine entwicklen soll. Ein Designer würde also sicher alles ganz anders machen, aber so ist es nun mal. Budget ist nicht vorhanden, um jemanden dafür zu bezahlen. Sollte sich natürlich jemand berufen fühlen, etwas gutes für Wuppertal und den Erfolg der App zu tun, gerne bitte bei mir melden! :)

Davon ab, habe ich mich zur Feier des 10. Artikels über meine erste iPhone App dazu entschieden, in Zukunft aus den Berichten die technischen Aspekte wie Quellcodes usw. rauszuhalten. Leider ohne großartiges Feedback von euch erhalten zu haben, ist es vermutlich so, dass es eine nennenswerte Gruppe Leser dieser Reihe gibt, die eben nicht Objective-C Programmierer sind und nur am Fortgang der App aus Projektsicht interessiert sind und weniger an der technischen Umsetzung. Das wird also ab sofort in separate Artikel verpackt werden.

Meine erste iPhone App – Folge 9

Von , 17. August 2011

WupperTour_Stationen_110816Wieder ist erfolgreich ein wenig Freizeit vernichtet und meine erste iPhone App ein Stückchen weiter. Nachdem ich beim letzten mal ja davon berichtet habe, dass es gar nicht so einfach war, meinem TabBarController einen TableViewController zu verpasssen, wollte ich nun den dritten Aktivist in Form eines NavigationControllers ins Spiel bringen, damit der Anwender nach Auswahl einer bestimmten Station auch die entsprechenden Details eingeblendet bekommt. Leider führte mich erst einmal ein Denkfehler in die Irre. Ich ging davon aus, dass der NavigationController quasi dem TabelViewController hinzugefügt werden muss; es ist aber genau anders herum. Wie beruhigend, dass das ein typischer Anfängerfehler ist, wie mir meine Google Suche bestätigte. Tatsächlich muss also dem TabBarController der NavigationController zugewiesen werden, der dann wiederrum den TabelViewController bekommt. Wechselt der Anwender dann zur Detail Ansicht eines POI’s, wird die entsprechende View auf den Stack des Navigation Controllers gepusht und die TableView ausgeblendet. Auf die richtige Lösung brachte mich eines der vielen schönen Tutorials eines amerikanischen Blogs, unterstützt durch das zugehörige YouTube Video. In dem Tutorial wird das Konstrukt über den InterfaceBuilder angelegt. Ich selbst habe das Grundgerüst allerdings ohne MainWindow.xib aufgebaut, daher folgend die programmatische Ausführung des ganzen in abgesteckter Form als Auszug aus dem AppDelegate:

UIViewController *viewController1, *viewController2;
UINavigationController* navController;
viewController1 = [[FirstViewController alloc] initWithNibName:@"FirstViewController" bundle:nil];
viewController2 = [[SecondViewController alloc] initWithNibName:@"SecondViewController" bundle:nil];
navController = [[UINavigationController alloc] initWithRootViewController:viewController2];
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = [NSArray arrayWithObjects:viewController1, viewController2, nil];
self.window.rootViewController = self.tabBarController;

In meinem Fall ist dann die TableView im XIB File des SecondViewController definiert und wird über die Zuweisung in Zeile 5 reingezogen. Was dann noch fehlt ist der Push des Detail XIB, der im SecondViewController nach der Auswahl eines Tabelleneintrages per didSelectRowAtIndexPath Protokoll-Methode gemacht wird:

detailController = [[DetailViewController alloc] initWithNibName:@"DetailViewController" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:detailController animated:YES];

Bezüglich der Lokalisierung der POI’s gibt es noch zu berichten, dass ich nun die XML Datei mit den POI’s meinem Projekt auch für die englische Sprache hinzugefügt habe. Verwirrend war dann aber leider erstmal, dass die App auch in Englisch sprachiger Umgebung nur die deutschen Texte zeigte. Aber auch das ist ein allgemein bekanntes Problem. Xcode cacht hier diverse Dateien und erkannte erst nach der Projekt Bereinigung über das Menü “Build -> Clean” die neue sprachenabhängige Datei. Manchmal ist sogar das Löschen der App im Simulator bzw. auf dem iPhone notwendig.

Um mal von der fiesen Technik etwas weg zu gehen: wie man am Screenshot sehen kann, fehlen der POI Liste noch die diversen Informationen. Hier muss ich noch die XML Datei entsprechend ausfüllen, was eine Fleissaufgabe ist. Des weiteren werde ich kommenden Samstag die Route erstmalig selbst ablaufen und zu jeder Station ein Foto machen, welches in der Übersicht sichtbar sein wird und natürlich in größer in der Detailansicht. Im gleichen Gang hoffe ich, dass wir auch die eigentlichen Texte der Führung validieren können, damit die Übersetzung ins Englische starten kann.

Eine kleine Anmerkung in persönlicher Sache: Mit jedem Artikel, speziell zum Thema dieser App, steigt mein Besucherzähler sprunghaft. Feedback habe ich aber leider bisher in keinster weise erhalten. Würde mich also sehr freuen, wenn ihr ein paar Tastendrücke in einen Kommentar investieren würdet – gerne auch Kritik, sofern sie konstruktiv ist. ;)

Meine erste iPhone App – Folge 8

Von , 4. August 2011

POIs_XML_ScreenshotNach etwas Themen Abstinenz gibt es wieder über Fortschritte bezogen auf meine erste iPhone App zu berichten. Vorweg sei gesagt, XML Dateien auf dem iPhone zu parsen is a pain in the ass! Und ein TableView Controller in einem TabBarController ebenfalls, wenn man ein Brett vor dem Kopf hat und übersieht, dass man im InterfaceBuilder vergessen hat, die Klasse der TableView richtig zu setzen! Kostet beides dann schnell mal 2 komplette Abende Freizeit-Opferung. Aber ohne Hobel keine Späne (oder so ähnlich ;)) und so bin ich nun froh, endlich die Liste der POI‘s aus einer XML Datei parsen zu können und sie auch auf dem Tab für die Übersicht der Stadtführungs-Stationen darstellen zu können; natürlich mit kleinem Bildchen und Sub-Title präsentiert. Allerdings muss ich nochmal los ziehen und für jeden Streckenpunkt ein vernünftiges Bild machen.

Wie zuletzt angekündigt, habe ich mit der App unter Xcode4.2 (beta) komplett neu angefangen. Ich denke nun erst recht, dass das die richtige Entscheidung war. Die angedachten Features für das erste Release (Mehrsprachigkeit und iPad Unterstützung) sind nach anfänglichen Schwierigkeiten ebenfalls im Griff. In Büchern und Videos sieht es halt immer sehr klar und einfach aus, aber in der Kombination mit verschiedenen Ansprüchen und in konkreten Details offenbaren sich dann doch oft Hürden die zu meistern sind.

Folgend möchte ich kurz noch die einfachste Möglichkeit darlegen, wie man eine XML Datei parsen kann. Ja, ich weiß, einen separaten Delegate für den XML Parser und das ganze verpackt in einer eigenen Klasse wäre schöner und objektorientierter gewesen, überstieg aber leider meinen derzeitigen Wissensstand und mehr als einen ganzen Abend war ich einfach nicht bereit für diesen Baustein an Zeit zu opfern. Wie man mit mehreren Delegates arbeitet, werde ich mir bei Gelegenheit dann nochmal ansehen.

Im AppDelegate Header File:

// Variablen setzen
NSMutableArray *pois;                   // POI array
PointOfInterest *aPOI;                  // one POI for XML parsing
NSMutableString *currentElementValue;   // string for XML parsing

 
Im AppDelegate Implementation File:

// XML parsen
- (void)parser:(NSXMLParser *)parser
  didStartElement:(NSString *)elementName
  namespaceURI:(NSString *)namespaceURI
  qualifiedName:(NSString *)qualifiedName
  attributes:(NSDictionary *)attributeDict
{
  if([elementName isEqualToString:@"POIs"])
  {
    if (!pois)
    {
      // Initialize the POIs array
      pois = [[NSMutableArray alloc] init];
      NSLog(@"XML File POIs found");
    }
  }
  else if([elementName isEqualToString:@"POI"])
  {
    if (!aPOI)
    {
      // Initialize the POI
      aPOI = [[PointOfInterest alloc] init];
    }
    // Extract the ID attribute here
    aPOI.poiID = [[attributeDict objectForKey:@"id"] integerValue];
    NSLog(@"XML Reading POI: %i", aPOI.poiID);
  }
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
  if(!currentElementValue)
  {
    // Initialize String for collecting Data
    currentElementValue = [[NSMutableString alloc] initWithString:string];
  }
  else
  {
    // Collect Data
    [currentElementValue appendString:string];
  }
}

- (void)parser:(NSXMLParser *)parser
  didEndElement:(NSString *)elementName
  namespaceURI:(NSString *)namespaceURI
  qualifiedName:(NSString *)qName
{
  if([elementName isEqualToString:@"POIs"])
  {
    // There is nothing to do if we encounter the end of POIs XML File
    return;
  }
  // If we encounter the end of POI element, we add the POI to the array
  if([elementName isEqualToString:@"POI"])
  {
    [pois addObject:aPOI];
    aPOI = nil;
  }
  else
  {
    // eleminating useless whitespace
    NSString *trimmedString = [currentElementValue
     stringByTrimmingCharactersInSet:[NSCharacterSet
     whitespaceAndNewlineCharacterSet]];
    [aPOI setValue:trimmedString forKey:elementName];
    trimmedString = nil;
  }
  currentElementValue = nil;
}

 
Für das TabelView dann in der “cellForRowAtIndexPath” Methode folgende Hilfsmethode um auf das Array aus dem App Delegate zugreifen zu können:

// get Pointer to the POI Array out of the AppDelegate
- (NSMutableArray *)thePOIs
{
  NSMutableArray *thePOIs = nil;
  id appDelegate = [UIApplication sharedApplication].delegate;
  if ([appDelegate respondsToSelector:@selector(pois)])
  {
    thePOIs = [appDelegate pois];
  }
  return thePOIs;
}

 
Dann kann man zum Beispiel hiermit die Dateien abgreifen:

cell.textLabel.text = [[self.thePOIs objectAtIndex:indexPath.row] title];

 
Wer sich jetzt wundert, warum ich soviele Informationen preisgebe, dem sei folgendes gesagt: Meine App ist im Prinzip nur eine Hülle, also ein Grundgerüst für die eigentliche Stadtführung und vermutlich von einem erfahrenen Programmierer in einer Woche programmierbar. Die eigentliche Arbeit und das KnowHow, um das es geht, steckt in der Stadtführung selbst. Also den Texten und Tonaufnahmen die später enthalten sein werden. Ausserdem ist es mir nur durch die Offenheit des Netzes und die vielen kleinen Hilfen in Foren, Blogs und Webseiten mit Tutorials überhaupt möglich, so einer App zu erstellen. Daher gebe ich gerne Wissen weiter an andere Anfänger die vor ähnlichen Fragestellungen stehen. Das meiste hier steht sowieso in der Apple Doku oder lässt sich woanders nachschlagen – von daher: Nothing special!

Meine erste iPhone App – Folge 7

Von , 20. Juni 2011

Logo Wuppertal AppEin Ende mit Schrecken ist besser, als ein Schrecken ohne Ende. Treu nach diesem Motto hab ich mich nun entschieden, unter Xcode4.2 (beta) mein Projekt neu zu beginnen, da ich die hier angesprochenen Schwierigkeiten nicht in akzeptabler Zeit in den Griff bekommen konnte. Manchmal ist es eben sinnvoll, seine Grenzen zu erkennen und entsprechend konsequent zu handeln. Schuld an der ganzen Misere bin ein Stück ich selbst, aber sowohl Xcode als auch die Macher von route-me tragen ihren Teil dazu bei. Im Falle von route-me ist es allerdings so, dass ich das Projekt ja eigentlich missbraucht habe für eine nicht unterstützte Offline Variante. Ich werde die bereits investierte Zeit unter der Rubrik “Erfahrungen gesammelt” abhaken und beim Neuanfang der App erstmal auf die Standard Online Map Variante von Google zurück greifen. Wenn die App dann endlich im App Store ist, kann ich die Offline Variante, bei der keine Roaming Kosten für ausländische Besucher anfallen, per Update nachreichen. Dann ist hoffentlich auch zum einen Xcode, aber auch das route-me Projekt bezüglich iOS5 soweit, dass das ohne große Komplikationen funktioniert.

Um es mir aber nicht zu leicht zu machen, habe ich mich nun dazu entschieden, Features die für später geplant waren, vorzuziehen. Die erste Version soll also nun direkt eine Universal App sein und somit auch auf dem iPad nativ laufen. Ausserdem werde ich von Anfang an vernünftig auf “Lokalisation” achten und von vorne herein Englisch und Deutsch mit einbauen. Weitere Sprachen sind dann durch die Benutzung der von Apple empfohlenen Techniken schnell implementierbar.

Last but no least habe ich das App Icon fest gelegt und präsentiere es euch mit diesem Artikel oben links. Letztendlich spricht nichts mehr für Wuppertal, als unsere geliebte Schwebebahn! Ich hoffe es gefällt euch! Ob der Apple Glossy Effekt bleibt, habe ich allerdings noch nicht final entschieden. Zum Thema iOS App Icons kann ich übrigens diesen Artikel empfehlen, der übersichtlich die diversen Icon Größen auflistet und erklärt.

Meine erste iPhone App – Folge 6

Von , 14. Juni 2011

Derzeit habe ich Urlaub und wollte die Zeit sinnvoll nutzen und mal wieder an meiner ersten iPhone App basteln. Leider habe ich mir selbst ein paar Steine in den Weg geworfen und letztens auf mein iPhone die iOS5 beta aufgespielt. Einher ging das mit einem Update von Xcode3.2 auf Xcode 4.2 beta! Mein Projekt wieder lauffähig zu bekommen, hat mich nun einen halben Tag gekostet. Ergebnis: Es läuft derzeit nur auf dem iPhone Simulator bis Version 4.0. Darüber erhalte ich eine Fehlermeldung, die man laut Google nur durch komplettes Löschen und neu Importieren seines Projektes weg zu bekommen scheint:

Detected an attempt to call a symbol in system libraries that is not present on the iPhone:strtod$UNIX2003 called from function proj_strtod in image MyAppProject.

Zusätzlich hat sich heraus gestellt, dass das route-me Paket für Offline Maps noch nicht wirklich mit dem iOS5 zusammen arbeiten will. Auch hier erhalte ich beim Öffnen der SQLite Datenbank mit den Tiles einen Fehler 23 – “Authorization denied”

Trying to Open db map source /var/mobile/Applications/blabla/MyAppProject.app/map.db

error opening!: 23

Error opening db map source map.db

Eigentlich habe ich gedacht, naiv wie ich bin, endlich mal mit dem App Inhalt weiter zu kommen, aber nun schlage ich mich mit der Infrastruktur rum! Wer nicht in eine solche Situation laufen will, beachte bitte folgendes: “Never change a running system!” ;-)

Meine erste iPhone App – Folge 5

Von , 16. April 2011

Huch, schon wieder 3 Wochen seit dem letzten Update rum. Macht aber nix, da aufgrund von persönlicher Auslastung eh kaum Zeit da war, an diesem Projekt weiter zu arbeiten. Ein bißchen was gibt es aber doch: Mein Arbeitgeber hat den Nebenerwerb offiziell genehmigt, was ja Grundvorraussetzung war, ein Gewerbe anzumelden um auch Geld mit der hart erarbeiteten App verdienen zu können. Das ist schon mal sehr gut für die weitere Motivation. ;-)

Ebenfalls positiv war ein Meeting mit der Wuppertal Marketing GmbH. Ich habe den derzeitigen Stand der App präsentiert und den von mir erdachten Endzustand skiziert. Dabei kamen von der Geschäftsführung auch prompt noch ein paar gute Ideen, die ich gerne umsetzen werde.

Für diesen Termin musste natürlich die Möglichkeit her, die App im pre-Alpha Stadium auch auf einem iPhone vorzeigen zu können. Dazu ist man erst berechtigt, wenn man nicht nur offizieller Apple Developer (kostenlos) ist, sondern auch am entsprechenden Developer Program, in dem Fall das für iOS, teilnimmt. Diese Mitgliedschaft wärt ein Jahr und endet automatisch, wenn man die regelmäßig anfallenden 79 Euro Gebühr nicht berappt. Als Gegenleistung erhält man kostenlosen Zugang zum aktuellsten Release von Xcode, darf eigene Apps auf iOS Geräten ausführen und beliebig viele (und beliebig oft) Apps für den App Store einstellen. Die Gebühr gilt somit also auch für die Nutzung der App-Store Infrastruktur und der Dienstleistung der Überprüfung der eingereichten Apps.

Eine weitere Tatsache die meinen Wissensstand letztens bereichert hat ist, dass die von Apple einbehaltenen 30% von jeder verkauften App bereits die MwSt. enthalten. Wenn ich also richtig verstanden habe, sind tatsächlich 70% des Erlöses in die nackte Tasche, bei Nutzung der Kleinunternehmerregelung! Dazu werde ich meinen Urlaub in 2 Wochen nutzen und den Gewerbeschein holen und dann hoffentlich auch mal wieder ein wenig programmieren!

Meine erste iPhone App – Folge 4

Von , 21. März 2011

DefaultAppIconEs tut mir leid, dass hier in letzter Zeit fast nur über meine erste iPhone App zu lesen ist und ich damit vielleicht einige Leute langweile, aber zumindest die Besucherzahlen geben mir recht. Die sind nämlich nach oben geschnellt in letzter Zeit und es scheint doch viele Leute zu interessieren, wie der Fortgang der App und dem drum herum sich so gestaltet. Obwohl ich die letzten Tage relativ wenig zum eigentlichen Programmieren gekommen bin, gibt es dennoch einige Neuigkeiten von den “Nebenkriegsschauplätzen”. Das App Design und der Funktionsumfang für den Stadtrundgang ist nun festgelegt. Daraus ergibt sich auch die Gestaltung des GUI, die ich nun forciert umsetzen kann. Ausserdem ist die eigentliche Route des Stadtrundganges definiert und die Arbeit an den ersten Texten hat begonnen. Offen und zugleich spannend ist die Frage nach dem richtigen App Namen und einem geeigneten Icon!

Weiter gibt es zu berichten, dass ich bei meinem Arbeitgeber nun einen Antrag zur Genehmigung eines Nebenerwerbs eingereicht habe. Schliesslich vermacht man seine komplette Arbeitsleistung per Arbeitsvertrag dem Arbeitgeber und ist nur mit separater Genehmigung auf der legalen Seite, ein Gewerbe anzumelden. Ein Gewerbeschein ist nämlich nötig, da es sich um eine regelmäßige Einnahme mit Gewinnabsicht handelt. Was ich noch klären muss und wo sich viele Internet Geister scheiden, welche Form des Gewerbes für einen kleinen App Entwickler wie mich die richtige Wahl ist. Im Moment tendiere ich zur Kleinunternehmerregelung, aber dazu werde ich hier noch separat posten. Sollte mein Arbeitgeber mir nämlich meinen Wunsch verweigern, fällt das Geld verdienen sowieso erstmal ins Wasser und ich muss zusehen, wie ich damit umgehen kann.

Bezüglich der Programmierung gab es wie gesagt nur kleine Fortschritte. Ich hab einige Zeit mit einem Problem bei dem TableView vergeudet, das ich auf dem Reiter “Einstellungen” verwenden möchte. Die App stürzte beim Wechsel auf die Setup View immer sang und klanglos ab. Das ist nun im Griff und ich habe darüber hinaus gelernt, wie man auf eine Tabellen Zelle Buttons und dergleichen legen kann. Stark geholfen hat mir hier ein Blog Eintrag vom iPhone SDK Dev Blog. Vielen dank dafür! Abschliessen werde ich diesen Tab für die Einstellungen hoffentlich (bis Ende dieser Woche), sobald ich mich mit der Speicherung dieser Userdaten (NSUserDefaults) angefreundet habe.

Meine erste iPhone App – Folge 3

Von , 6. März 2011

Screenshot_myFirstAppDie Einbindung der Offline Karten des OpenStreetMap Projektes hat erfolgreich funktioniert. Ich hatte etwas Probleme mit der Erstellung der SQL Datenbank, aus der die einzelnen Tiles geladen werden, aber nachdem ich den Zoomfaktor der per Perl Skript runtergeladenen Tiles auf 1 bis 16 gesetzt habe und im Testmodul als Startkoordinaten die präzisen Breiten- und Längengraden angegeben habe, klappt’s nun auch endlich. :-D Allerdings bläht das Kartenmaterial die App auch ganz schön auf. Alleine die Karten sind schon knapp 40MB groß, dabei habe ich mich auf die gerade noch sinnvolle maximale Detailstufe von 16 beschränkt. Eine Stufe höher (17) wäre mir noch lieber gewesen, aber dann wäre das Kartenmaterial ca. 100MB groß geworden. Vielleicht etwas für ein späteres Update, je nachdem wie die Resonanz dazu aussehen wird. Eine Möglichkeit wäre noch, es dem Anwender zu überlassen, ob er alternativ die Google (online) Maps nutzen möchte. Für die deutsche Nutzerschaft wäre das zumindest eine gute Sache, die ich eventuell noch umsetzen werde bei einem weiteren Update. Im Screenshot zu diesem Artikel seht ihr dann nun auch einen ersten Entwurf der eigentlichen Oberfläche meiner ersten iPhone App. Bei dieser Gelegenheit sei erwähnt, dass so ein TabBarController zickig sein kann! ;-) Viel mehr gekämpft habe ich aber (und nun wird es etwas technisch), mit der Begrenzung der Karte. Da es sich wie gesagt um lokal gespeicherte Offline Karten von Wuppertal handelt, gelangt man beim Verschieben der Karte abseits von Wuppertal in graues Niemandsland. Im Standard ist die route-me Library zwar in der Lage, den User auf eine bestimmte Zoom Stufe zu begrenzen, aber leider nicht das Bewegen auf der Karte einzuschränken. Im Entwickler Wiki habe ich Aussagen gefunden, dass die Macher von route-me das schon einmal umgesetzt haben, es aber nicht in Produktion übernommen haben, da es zuviele Probleme damit gab. Also habe ich mich selbst ans Patchen der Library gemacht und einen zwar nicht gerade super schönen, aber funktionalen Weg gefunden, um zu verhindern, dass der Nutzer der App den Kartenbereich verlässt. Dazu habe ich im route-me Framework die Datei MapView/Map/RMMapContents.m gepatcht und die Methode moveBy wie folgt um “Bounds” erweitert:

- (void)moveBy: (CGSize) delta
{
  [mercatorToScreenProjection moveScreenBy:delta];
  [imagesOnScreen moveBy:delta];
  [tileLoader moveBy:delta];
  [overlay moveBy:delta];
  [overlay correctPositionOfAllSublayers];
  [renderer setNeedsDisplay];

  //AZe: Grenzen setzen für Map Scrolling (Wuppertal)
  const float AZeMinLat = 51.2;
  const float AZeMaxLat = 51.298;
  const float AZeMinLon = 7.05;
  const float AZeMaxLon = 7.31;


  CLLocationCoordinate2D AZeCoordinate;
  AZeCoordinate.latitude = self.mapCenter.latitude;
  AZeCoordinate.longitude = self.mapCenter.longitude;
  if ( AZeCoordinate.latitude > AZeMaxLat ||
    AZeCoordinate.latitude < AZeMinLat ||
    AZeCoordinate.longitude > AZeMaxLon ||
    AZeCoordinate.longitude < AZeMinLon )
  {
    if ( AZeCoordinate.latitude > AZeMaxLat ) {
      AZeCoordinate.latitude = AZeMaxLat;
    }
    if ( AZeCoordinate.latitude < AZeMinLat ) {
      AZeCoordinate.latitude = AZeMinLat;
    }
    if ( AZeCoordinate.longitude > AZeMaxLon ) {
      AZeCoordinate.longitude = AZeMaxLon;
    }
    if ( AZeCoordinate.longitude < AZeMinLon ) {
      AZeCoordinate.longitude = AZeMinLon;
    }
    [self setMapCenter:AZeCoordinate];
  }

}

Der Effekt dieses Patches ist, dass der Anwender zwar die Map weiterziehen kann, sie aber auf die Grenzen zurückspringt. Die Koordinaten beziehen sich auf die Mitte der Map, wodurch sich bei unterschiedlichen Zoom Tiefen auch leicht unterschiedliche Grenzen ergeben. Wie gesagt, nicht schön, aber funktionell und dadurch dass die Map ohnehin nur für Wuppertal Interessierte gedacht und großzügig bemessen ist, dürften die meisten Anwender das nie bemerken.

Panorama Theme by Themocracy