formApps – Digitale Formulare als App

Das Kind bekommt einen Namen – formApps! Worum geht es? Wie der Name schon ahnen läßt, handelt es sich um Formulare, genauer gesagt um elektronische Formulare. Die Idee ist einfach. Wir sind umgeben von Formularen, insbesondere ist es ein beliebtes Werkzeug nach dem gegriffen wird wenn es um Prozesse in einem Unternehmen geht: Abnahmeprotokoll, Inventur-Formulare etc. An dieser Stelle ist formApps eine einfache Möglichkeit ein beinahe beliebiges Formular in eine App umzuwandeln! Gibts es das denn schon nicht? Aber natürlich gibt es das, zahlreiche Anbieter werben mit Online-Formulargeneratoren,  “Apps” die man schnell zusammen klicken kann etc. 

Warum dann formApps? Weil es doch anders ist! formApps vereint Vorteile einer nativen App mit Gestaltungs-Flexibilität eines HTML5-Formulares. Apps, die auf Basis von formApps gebaut sind, sind native Apps, die über App-Store verteilt werden können und die Datenerfassung komplett Offline ermöglichen! Die ermöglichen auch Datenexport komplett ohne Server, z.B. Email-Versand, .csv-Export, PDF-Export etc.  

formApps bietet nach Wunsch natürlich auch eine Server-Komponente an. Die in der App erfassten Daten können auf den Server “verschickt” und dort später ausgewertet werden.

Es gibt inzwischen schon zwei Apps die mit formApps gebaut sind. Es sind unsere “alten” bekannten: LieferscheinApp und Übergabe-App. Die Apps können kostenlos über Appstore installiert und ausprobiert werden!

Shortnotes – latest updates and news

Last two weeks were really meaningful for Shortnotes (former Cheat-sheets). The app has got two additional localizations: Italian and Spanish, Turkish is in progress. In Spanish the app is called “Chuleta” and it means.. how do you think what? Right, it means “Cheatsheet” 🙂 The Italian title is “Bigliettino” with the same meaning. Enjoy Shortnotes in your native language!

Preissenkung für die PolterApp Pro Version!

In letzter Zeit habt ihr sicherlich viel Aktivität bei der PolterApp wahrgenommen: neuer Internetauftritt, Optimierung des User Interfaces, neue Funktionen und vieles mehr. Warum? Ganz einfach, das Ziel der PolterApp war schon immer nützlich und verständlich zu sein. Daran hat sich seit 2016 nichts geändert. Was sich aber heute ändert ist der Preis für PolterApp Pro. Ab heute kann die Pro Version der PolterApp für nur 12,99 Euro erworben werden.

Übergabe-App für Immobilienmakler

Immobilienmakler aufgepasst: heute erblickte die neue App zur Haus- bzw. Wohnungsübergabe die Welt! Die Übergabe-App wiegt 36 Mb, dem Entwickler und dem Baby der App geht es gut 😉

Was macht denn die App so besonderes? Sie ist EINFACH. Intuitiv aufgebaut, keine Anmeldung erforderlich. Die Protokoll-Daten können als PDF direkt per Email verschickt werden.

Was noch? Das Potenzial! Die Übergabe-App ist sehr flexibel gebaut, so dass dem Ausbau und den speziellen Anforderungen nichts im Wege steht! Sprecht uns gerne an, falls irgendwelche Features vermisst werden oder gewünscht sind! Fürs Feedback schon mal Danke im Voraus! 😉

Die LieferscheinApp ist da!

Fröhliche Nachrichten – die LieferscheinApp steht ab sofort für alle iPhone- und iPad-Nutzer zur Verfügung. Es handelt sich dabei um einen Lieferscheinblock für Rundholztransport. Kommt es etwa bekannt vor? Ja natürlich, HISLIS! Die LieferscheinApp ist zwar nicht ganz das gleiche wie die Android Umsetzung, geht aber in die gleiche Richtung. Es umfasst die Möglichkeit, die üblichen Lieferscheinfelder auszufüllen, Holzdaten zu erfassen und Fotos anzuhängen. In der Test-Phase sind auch Pro Features freigeschaltet: PDF-, CSV- und Email-Export. Wir freuen uns auf euer Feedback!

HISLIS bei Google Play

Ab heute steht der digitale Lieferscheinblock HISLIS bei Google Play zur Installation bereit. Etwa 1 Jahr lang hat die Test-Phase bei Bentheimer Holz GmbH gedauert. Nun ist es soweit. Lange Laufzeiten für das manuelle übermitteln der Lieferscheine gehören somit bei Rundholztransport der Vergangenheit an.

Die HISGIS-App beinhaltet insbesondere die Anbindung an Holz-Informationssystem von Bentheimer Holz. Bitte sprecht uns an, wenn die Anbindung an Euer Backendsysteme ebenso gewünscht ist.

PolterApp Version 4.x

Last three weeks of the ongoing development of the PolterApp were dedicated to the implementation of the Feedback from the USA. Especially, it turned out that localization of the PolterApp in English left much to be desired. Thanks to constructive suggestions and notes the dropdown values for species, kind and quality have been reorganized and completed with new entries. The list of wood certifications has been also extended. To make the things easier in the future, it became possible for the user to add his own list values in the App settings! Do not worry, it is still possible to put plain text into corresponding fields.

The localization of the PolterApp into English is now almost finished. Please, let me know if you still find some text that is not correct or should had a better wording. You help is highly appreciated!

SWIFT: Upload a file with multipart/form-data in iOS using uploadTask and URLSession

Let’s see how to upload any file to a web server, using only Apple’s built-in URLSession. Most of the examples in the Internet utilize dataTask and not the uploadTask. Also the examples I found demonstrate only the uploading of the image files. That’s why I decided to share a working code for building up a multipart/form-data request, that can be used in combination with uploadTask.

// generate boundary string using a unique string
let boundary = UUID().uuidString
        
// Set the URLRequest to POST and to the specified URL
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.addValue("Bearer \(yourAuthorizationToken)", forHTTPHeaderField: "Authorization")
        
// Content-Type is multipart/form-data, this is the same as submitting form data with file upload
// in a web browser
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
        
let fileName = fileURL.lastPathComponent
let mimetype = mimeType(for: fileName)
let paramName = "file"
let fileData = try? Data(contentsOf: fileURL)
var data = Data()
// Add the file data to the raw http request data
data.append("\r\n--\(boundary)\r\n".data(using: .utf8)!)
data.append("Content-Disposition: form-data; name=\"\(paramName)\"; filename=\"\(fileName)\"\r\n".data(using: .utf8)!)
data.append("Content-Type: \(mimetype)\r\n\r\n".data(using: .utf8)!)
        data.append(fileData!)
        data.append("\r\n--\(boundary)--\r\n".data(using: .utf8)!)
// do not forget to set the content-length!
request.setValue(String(data.count), forHTTPHeaderField: "Content-Length")

As you can see, it’s pretty straightforward. First we create a request, setting Content-Type to “multipart/form-data” and Authorization token if required. You can set any other values if you web service requires. The second is to create the data that confirms to the multipart/form-data protocol. For we want to upload any kind of files, the mime type is recognized automatically:

private func mimeType(for path: String) -> String {
        let pathExtension = URL(fileURLWithPath: path).pathExtension as NSString
        guard
            let uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, pathExtension, nil)?.takeRetainedValue(),
            let mimetype = UTTypeCopyPreferredTagWithClass(uti, kUTTagClassMIMEType)?.takeRetainedValue()
        else {
            return "application/octet-stream"
        }

        return mimetype as String
    }

So now we have two peaces of puzzle. To bring them together just use the uploadTask(with:data:) function:

session.uploadTask(with: request, from: data)

The webservice should be happy now with your upload file call.

SWIFT: Save NSAttributedString into text file

To save NSAttributedString string into text file we convert first NSAttributedString into Data and afterwards save Data as usual into a text file:

do {
   let rtfData = try attributedText.data(from: .init(location: 0, length: attributedText.length), documentAttributes: [.documentType: NSAttributedString.DocumentType.rtf])
   try rtfData.write(to: fileURL, options: .atomic)
} catch {
   print(error)
}