Dev Diary: Risiken und Nebenwirkungen von setHidesBarsOnSwipe

Viele kennen es von der Facebook- und anderen Apps, dass die Navigationbar in Apps sich langsam ausblendet, wenn der Nutzer nach unten scrollt. Beim Zurückscrollen taucht sie dann rasch wieder auf, so dass die Bedienelemente stets schnell erreichbar sind.

Seit iOS 8 existiert eine einfache und komfortable Möglichkeit, den Bildschirm auf diese Weise in Apps effizienter auszunutzen:

[self.navigationController setHidesBarsOnSwipe:YES];

Die Sache hat nur einen Haken. Bislang hatte ich in meiner App eine Funktion implementiert, die Wischgesten nach rechts in eine Art Zurück-Funktion übersetzt:

UISwipeGestureRecognizer *recognizer;
recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(pageTurnLeft:)];
[recognizer setDirection:(UISwipeGestureRecognizerDirectionRight)];
[[self view] addGestureRecognizer:recognizer];

Die Funktion löst seit dem Aktivieren von setHidesBarOnSwipe nicht mehr aus. Wie sich herausstellte, zieht die Funktion alle Gesten auf sich. Es ist aber durchaus möglich, sich dem GestureRecognizer anzuschließen:

[self.navigationController.barHideOnSwipeGestureRecognizer addTarget:self action:@selector(swipeGesture:)];

Ein GestureRecognizer für alles – das klingt zu schön, um wahr zu sein. Und das ist es auch. Denn bislang konnte ich dem Recognizer gleich die gewünschte Swipe-Richtung mit auf den Weg geben (setDirection), was hier nicht geht. Mehr noch: Wir haben es bei der ausgelösten Funktion auch nicht mit einem Übergabewert des Typs UISwipeGestureRecognizer zu tun, dessen Direction wir einfach auslesen könnten, sondern mit einem anderen Vertreter:

- (void)swipeGesture:(UIPanGestureRecognizer*)gesture

Der UIPanGestureRecognizer ist leider kein so freundlicher Typ. Das Bestimmen der Richtung gestaltet sich weitaus aufwendiger. Und bislang habe ich noch keine zufriedenstellende Lösung gefunden, neue und alte Funktion in Einklang zu bringen.

Dev Diary: iOS 9 und App Transport Security

Im Dev Diary, meinem kleinen Entwicklertagebuch, berichte ich über Entdeckungen, Tipps und Hinweise, auf die im Zuge der App-Entwicklung stoße.

Der Herbst naht so langsam und damit die Veröffentlichung von iOS 9. Alle Appentwickler sind gut beraten, sich schon einmal mit den Betaversionen und Xcode 7 beta vertraut zu machen, um später nicht unter Zeitdruck unliebsame Überraschungen zu erleben.

Und eine böse Überraschung setzte heute beim Ausprobieren der WZ App unter iOS 9 gleich beim ersten Aufruf ein. Wie beim Roulette hieß es: Nichts geht mehr. Die Daten vom Server wurden nicht geladen. In der Konsole gab es dazu die Begründung:

The resource could not be loaded because the App Transport Security policy requires the use of a secure connection.

App Transport Security? Tatsächlich soll diese API im SDK Gutes bewirken, nämlich abgesicherte Verbindungen zwischen App und Server. Dies macht bei vielen Anwendungen Sinn, bei denen persönliche Daten oder Logins übertragen werden. Und damit sich das schnell durchsetzt, hat Apple die Funktion per Default aktiviert.

Die Realität sieht aber so aus, dass viele Server weiterhin nur per HTTP erreichbar sind. Vielfach können Entwickler auch gar nicht vorhersehen, ob ihnen nicht doch eine ungesicherte Verbindung unterkommt, etwa bei Links in Tweets oder RSS-Feeds.

Kurzum: Die App Transport Security ist sicher sinnvoll, aber viele Entwickler möchten sie wahrscheinlich abschalten oder zumindest teilweise entschärfen. Bei Neglected Potential gibt es eine gute Zusammenfassung über die verschiedenen Optionen.

Wenn’s schnell gehen muss:

In Xcode die Info.plist der App editieren (nicht als Property List, sondern über Rechtsklick->Open As als Source Code). Dort folgendes einfügen:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

Damit ist die App Transport Security erstmal komplett deaktiviert. Trotzdem lohnt sich ein Blick in die Doku bei Apple und die Überlegung, wie die neue Funktion möglicherweise doch genutzt werden.