Apps
Umstieg auf die Dateien-App
08. September 2019
Im heutigen Blog greife ich das Thema auf, wie ich unter iOS am besten lokale Dateien speichere und verarbeite. Noch spezifischer, wenn die Anforderung ist, dass der User die Datei mit einer externen App teilen kann, sie bearbeitet und wieder in die ursprüngliche App ladet.
Problembeschreibung
Bevor iOS 11 hatte ich zwei Möglichkeiten für Dateispeicherung – entweder mittels Realm oder einem App spezifischen „document directory“ – abhängig vom Use-Case. Damit man die Datei mit einer externen App teilen kann, verwendete ich einen „UIActivityViewController“. Und um die Dateien wieder zur originalen App zurück zu bekommen, ist diese nach außen hin öffentlich gemacht und mittels der „share extension“ angezeigt. Das hat alles ganz gut geklappt, allerdings war es nicht ganz einfach die Ein- und Ausgänge im Blick zu behalten, da diese Anhänge Teil eines viel größeren Realm-Objekts waren.
Die Dateien-App als Lösung
Nachdem wir bei uns iOS 10 nicht mehr unterstützen, habe ich mich dazu entschlossen die Dateien-App zu benutzen. Welche alle oben genannten Punkte ersetzt. Es war ein geeigneter Moment, da wir die App in Zukunft noch viel mehr benutzen. Momentan ist die Sektion „On my iPhone“ in der Dateien-App noch immer für Dateien reserviert. Sobald iOS 13 erscheint, werden User die Möglichkeit haben, dort selbst Ordner für sich zu erstellen. Außerdem sollen USB-Sticks und SD-Karten unterstützt werden. Allerdings gibt es einen Punkt, der ganz wichtig für die App-Entwicklung ist: Das berühmte „document directory“ ist zugänglich über die Dateien-App. Dieser Ordner war niemals sichtbar für einen User, allerdings nutzten ihn Entwickler um Dateien intern zu speichern und abzurufen. Das ändert sich nun indem man einfach zwei Keys in „Info.plist“ ändert:
<key>UIFileSharingEnabled </key>
<true/>
<key>LSSupportsOpeningDocumentsInPlace</key>
<true/>
Fertig. Jetzt hat die eigene App einen Ordner in der Dateien-App und die komplette Dateien-Struktur ist nun für den User und andere Apps zugänglich. Falls man Dateien doch vor dem User versteckt Speichern mag, gibt’s noch immer einige vordefinierte Ordner von Apple.
Dieser Code zeigt, wie die Ordner-Struktur erstellt ist. Die „root“-Verzeichnis des Realm-Objekts speichert die „BaseURL“, welches auch andere angehängte Objekte enthält.
<strong>let</strong> basePath = ElectricCars/Tesla/Roadster/
let baseURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!.appendingPathComponent(basePath)if !FileManager.default.fileExists(atPath: baseURL.absoluteString) {
do {
try FileManager.default.createDirectory(atPath: baseURL.path, withIntermediateDirectories: true, attributes: nil)
} catch {
print(error)
}
}
Wenn wir die Ordner-Struktur haben, gehen wir dazu über, die tatsächliche Datei in den Ordner zu speichern. „attachment data“ ist ein Teil des Realm-Objekts, welches die Daten als Entwurf speichert bis der User den „Speichern“-Button drückt. Wenn man diesen drückt, speichert man eine Datei in den „documents folder“ der Dateien-App. Der Realm-Objekt speichert den Pfad zur Datei. Die Daten selbst entfernen sich aus dem Realm-Objekt. Da wir ab jetzt den Pfad zur Datei benutzen um an die Daten zu kommen.
<strong>do</strong> {
try attachment.data!.write(to: baseURL.appendingPathComponent(attachment.name)) // name contains file extensiontry realm.write {
attachment.path = attachment.name
attachment.data = nil
}
} catch {
print(error)}
Feinarbeit:
Um alles etwas flüssiger zu machen, verwenden wir „UIWebKit“. Damit das Dokument für eine Vorschau oder für das Teilen innerhalb der App bereit zu stellen. Ohne dem, alle Bearbeitungen in der Dateien-App würden auf die Dateien, welche in unserer App gespeichert sind, angewandt werden, welche eventuell an den Server geschickt werden.
*Bemerkung:
Falls man eine große App programmieren möchte, wo es hauptsächlich um Dokumente geht, sollte man sich eher die Integration der Dateien-App in die eigene ansehen, nicht andersherum (https://www.appcoda.com/files-app-integration/)