Aus zwei mach eins - oder: In Schönheit sterben...

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Aus zwei mach eins - oder: In Schönheit sterben...

    Hallo zusammen!

    Wie versprochen möchte ich hier ein paar Worte über mein gerade abgeschlossenes Projekt verlieren. Der geneigte Leser wird bei dem ein oder anderen Thema an Fragen / Beiträge von mir denken müssen: Dies ist kein Zufall, sondern liegt in der Natur der Sache: Ich entwickle nur zum Spaß und um neue Dinge auszuprobieren ... dazu noch als "Einzelkämpfer", da regiert manchmal auch Unverständnis und ich suche Hilfe (und Seelsorge) in unserem Forum. Aber der Reihe nach:

    Die Ausgangslage:
    Die Ursprünge liegen 10 Jahre zurück, aber seitdem programmiere ich an Apps zum Editieren von (Maschinen-) Stickmustern. Zunächst unter macOS - inzwischen mit diversen Plugins - kam irgendwann die Idee, ob man dies nicht auch auf iOS umsetzen kann. Man kann und so entstand eine reine iPad-App, "StitchBuddy HD". Diese kostet einen Obolus, und daher wollte ich ihr eine Demo zur Seite stellen. Von IAP hatte ich keine Ahnung (und viel Respekt) und ausserdem könnte ein reduzierter Funktionsumfang (nur Betrachten) auch auf dem iPhone laufen. Schon entstand eine zweite (Universal-) App "StitchBuddy View", die kostenlos war. Und so blieb es die letzten Jahre.

    Der Plan:
    Vor gut einem Jahr ging die macOS-App in den MAS und wurde auf IAP umgestellt. Damit entstand die Idee, die beiden iOS-Applikationen endlich zu einer zusammenzuführen, und ebenfalls als Freemium-Applikation anzubieten. Bei der Gelegenheit sollte auch die Oberfläche angepasst werden, zumal das Ursprungs-Konzept (mangels damaligen Wissens) etwas krude war, State Restoration hatte ich mit eigenen Methoden implementiert, ARC wäre auch eine Idee ... also schlicht Renovierungsbedarf:
    • Einsatz des UISplitViewControllers
    • State Restoration á la Apple
    • IAP (frei für Bestandskunden)
    • Code-Review / -Cleaning
    • ARC (nicht in den Backend-Klassen)
    • Performanz-Verbesserungen (Nebenläufigkeit)
    • UISearchController mit Scopes
    Die Umsetzung:
    Meine Programmierprojekte starten üblicherweise im Herbst und enden im Frühling. Zunächst ergänzte ich die macOS-App mit Automator-Aktions. Dann kamen die iOS-Apps an die Reihe, hier ein paar Lessons learned, alle Details würden diesen Beitrag sprengen, fragt bei Interesse bitte nach:
    • Ich habe letztlich auf einem neuen Projekt aufgesetzt (basieren auf dem Master/Detail-View Template) und alle notwendigen Klassen Stück für Stück übernommen und dabei auf ARC umgestellt, optimiert, getestet. So konnte ich sicher sein, keine Altlasten mitzuschleppen, auch wenn der Ansatz erstmal mühseliger erscheint - ich habe ihn nicht bereut.
    • Beim UISplitViewController habe ich recht viel probiert, um seine "Magic" zu verstehen, insbesondere bei den Anzeige-Modi: So sollte z. B. die DetailView bei mir immer maximierbar sein, standardmäßig aber parallel zur MasterView angezeigt werden. Eine Kombination aus UISplitViewControllerDisplayModeAllVisible und dem displayModeButtonItem der SplitViewController machten es möglich.
    • State Restoration finde ich cool. Allerdings haben sich die Fälle gehäuft, in denen eine Eigenschaft zum Zeitpunkt ihres Restores noch gar nicht verwendet werden kann, weil z. B. eine entsprechende View noch nicht geladen ist. Letztlich habe ich - einem Apple-Beisipiel folgend - in diesen Fällen die Eigenschaft in einem Property zwischengespeichert und dann beispielsweise erst im viewDidLoad benutzt.
    • UISearchController hat zwar seine Eigenarten, aber die längste Fehlersuche war eigentlich ein generisches dismissViewControllerAnimated:, dass ich beim Wechsel in den Hintergrund ausführte ... welches dann auch den SearchController "zerstörte". Im späteren habe ich dann ViewController nur noch explizit verschwinden lassen.
    • Für IAP kann ich nur Receigen empfehlen ... eine von zwei Stellen, an der ich auf fremden Code zurückgreife. Die Einbindung in den Build-Prozess inkl. dynamischer Versionsnummern ist einfach nur cool. Hier noch einmal Danke für die Tipps! Leider ist die Behandlung von Bestandskunden nicht 100% testbar, funktioniert aber (scheinbar).
    • Der zweite "fremde" Code ist Fingertips. Damit konnte ich Demo-Videos in Quicktime aufnehmen, auf denen erkennbar ist, an welche Stellen ich touche. Sehr cool, leicht zu implementieren und ich aktiviere es über eine Option im Settings-Bundle (damit beim Benutzer möglichst wenig fremder Code läuft).
    • PopoverPresentationController fand ich schon vorher gut, um Views auf iPhone und iPad mit gleichem Code zu präsentieren. Allerdings hatte ich früher den auf iPhone notwendigen "Cancel"-Button per Abfrage des Devices gesetzt. Blöde Idee, wenn jemand (inzwischen) auf dem iPad Split View oder Slide Over nutzt und diesen Button braucht. presentationController:viewControllerForAdaptivePresentationStyle: ist als Delegate-Methode Dein Freund.
    • Apple tut sich etwas schwer damit, solch ein Migrationskonzept von zwei Apps in eine zu verstehen. Hier tut man gut daran, dieses beim Review genau zu beschreiben.
    So, ich höre auf bevor der Artikel noch länger wird ... so weit hat wohl eh keiner gelesen. Wenn doch, seid Ihr herzlich eingeladen, die App hier kostenlos zu laden und Euer Feedback im Forum zu geben. Speichern geht bei Mustern mit max. 1000 Stichen, aber zum Probieren sollte das reichen.

    Ciao, Mattes

    P.S.: Wer sich jetzt fragt, woher der Titel dieses Artikels kommt: Aus Benutzersicht hat sich mit diesem Update vergleichsweise wenig getan und ich habe mich manchmal schon gefragt, warum ich es mache. Man kann eben auch in Schönheit sterben. Aber für mich war bei (oder trotz?) aller Probleme auch viel Spass und wieder eine steile Lernkurve. Trotzdem freue ich mich jetzt über eine Sommerpause... :D
    Diese Seite bleibt aus technischen Gründen unbedruckt.
  • Vielen Dank für Deinen ausführlichen Bericht! Schön, wenn jetzt alles so klappt, wie Du Dir das vorgestellt hast. \o/

    Darf ich fragen, wie groß Dein Projekt ist? Files, LOC. Nur so aus purer Neugierde heraus.
    Das iPhone sagt: "Zum Antworten streichen". Wie? Echt Jetzt? Muß ich erst die Wohnung streichen!?
  • torquato schrieb:

    Darf ich fragen, wie groß Dein Projekt ist? Files, LOC. Nur so aus purer Neugierde heraus.
    Ohne mir jetzt extra ein Tool zu installieren, sondern per find . -name "*.m" -print0 | xargs -0 wc -l:
    • neue iOS-App: 10k Zeilen
    • alte iOS-Apps (zwei Targets): 10k Zeilen
    • macOS-App: 6.4k Zeilen
    • Core-Classes: 7.5k Zeilen
    Das heisst, das neue iOS-Projekt kommt so etwa auf 17.500 Zeilen, wobei ich recht viele Kommentar- und Leerzeilen verwende oder auch Klammern in eigene Zeilen setze. Ich schätze mal 8.000 "echte" Code-Zeilen.

    Insgesamt sind es für das iOS-Projekt etwa 40 Klassen.

    Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.
  • Danke. Das klingt nachvollziehbar. Ich finde, als einzelner 'Hobbyprogrammierer' ist das schon ein Wort, und für ein 'Code Cleanup' da alles nochmal durchzugehen macht natürlich schon einiges an Arbeit. Respekt. ;)
    Das iPhone sagt: "Zum Antworten streichen". Wie? Echt Jetzt? Muß ich erst die Wohnung streichen!?
  • Naja, das ist eben über die Jahre gewachsen und da es eine ziemliche Nische adressiert, blieb die Motivation auch (meistens) hoch.

    Interessant finde ich die Vielfältigkeit: Neben Coden eben auch Analyse der Datei-Formate, Icon-Design, Benutzer-Support, Website und überhaupt Maschinensticken als solches (in der Theorie, die Praxis macht meine Frau). Und beim Programmieren die vielen Themen, die mir bisher begegnet sind, z. B.
    • Dokumenten-basierte macOS-Apps
    • Undo-Manager
    • Apple Hilfe
    • Quick Look Plugin
    • Spotlight Plugin
    • Automator Actions
    • iCloud Drive (zwischenzeitlich mal Dropbox API)
    • Core Data
    • NSOperationQueue
    • IAP unter macOS und iOS
    • Settings Bundle
    • UIActions
    Und viel, viel mehr ... Meine Todo-Liste wächst immer schneller als ich umsetzen kann (und will): Es ist eben ein Hobby, und nicht mein einziges. Daher auch die (gewachsene) Entscheidung mit der „Sommerpause“, in der ich meine Freizeit weniger vor‘m Rechner verbringen will.

    Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.