Il Cittadino Magazine
Since January 2012 I’ve been working for a project called Catflow.
Catflow is a powerful publishing system with an integrated and efficient CMS. It relays on the design principle of separation of layout, style and content. It allows to publish your content on many different channels and devices using the same tools and concepts.
The apps are hybrid, made of a native core written in Objective-C for iOS and Java for Android (I use Swift for experimenting with new features or for T&M projects) responsible for dealing with updates and to the presentation of content, made of HTML pages.
Each page can be written in plain HTML or with the WYSIWYG editor, which translate the page in HTML via our transpilers. We use doT.js for apps and Jinja2 for web pages and PDFs.
I’ve been the sole iOS developer, I contributed to part of the backend in Python and Node, part of the Android framework and to the making of several projects involving Catflow, some of them not related to apps but to websites or PDFs.
Catflow key components
I started working for Catflow in 2012 and the initial idea was to have a system to publish catalogs, so the name Cat Flow (flow to make a catalog). Although the system was meant to be multi channel we started with iOS apps. As we wanted to give our customer the ability to fully customise the presentation layer making an hybrid app was the obvious choice. We didn’t use one of the existing frameworks like Phonegap or Cordova so we developer our own. I wrote the entire iOS part and supervised the implementation of the Android native framework.
We thought iBooks for the iPad was interesting, with the ability to scroll horizontally the pages and have a scrollview with thumbnails at the bottom, so we decided to start with something similar.
Apart from the custom components for the UI, the bigger native part was the communication with Catflow backend.
When publishing an app, Catflow produces a folder with every asset the app needs and a file describing the app’s structure. There data can be exported as a set of JSON files, one for each entity described in the project (products, sections, customers etc.) or a sqlite db file. All the images are in a folder and can be processed by the backend, for example to scale them so the client updates a single image at full resolution and can use it for a PDF while a scaled version is exported for the apps. HTML pages created with the WYSIWYG editor are transpiled so a template based on doT.js is created. The app reads the structure file and builds a hierarchy of contents. A content is the result of binding data (extracted from the JSONs or via an SQL query) and a template.
The main component was the custom scroll view, able to display HTML pages and scroll through them horizontally (although the vertical scroll is supported by my implementation we never used it) in the fastest possible way. The custom scroll view implements a prefetch mechanism so even scrolling really fast translate in a seamless transition between pages.
Below the scroll view we put the stripe, consisting of page previews created by making a screenshot of the actual page, or optionally by taking a single image of the product. The stripe allows for really fast scrolling between products and a tap on an element opens the product page with an animation, mimicking the page expanding from the stripe to the bigger view.
We also implemented other native UI components like the menu, a toolbar with buttons to access the wishlist, notes, and search.
While loading a page, during the prefetch or as a link is followed, the native framework creates the HTML string applying data to the template ending and loading it into a webview.
Each time an update is made in the backend and published, the app sends the current git revision of the folders to the backend which produces a zip containing the differences, so we send the smallest set of data every time an app asks for an update.
The first app we made with Catflow was for Spinmaster. They needed a tool to show marketing material to potential customers and to make orders. The app runs on the iPad and on Android tablets, is landscape only and it distributed via the B2B app store.
All the customer needs to provide are two Excels for products and customers and images and videos for each product. The result is an app divided into sections, with each section containing its products. There is a menu to navigate between sections and to quickly browse products we introduced the Stripe. What the stripe does is taking a screenshot of a page, similar to what iBooks do when browsing HTML based books. Both the stripe and the above part with products can scroll independently. Each time a new section is selected, either via the menu or by manually scrolling, the stripe is positioned to its first product. While scrolling the stripe the above section is left unchanged.
The agent can add a product to the order and remove products either from the page or from the wish list (a native table view), then open the order page, where he can change quantities and remove products if he forgot to do it before opening the order. Eventually the order is sent via email to a catflow address and a cron processes all the orders of the day and makes an Excel file that the customer service can import in SAP.
The project we made for Sanofi Aventis is about a single iOS application, running on the iPad, used by agents visiting pharmacies across Italy.
The apps has two purposes: showing marketing material to promote new products and interfacing with the CRM to collect orders and to sign new contracts.
One of the requirements was to be able to operate offline, so the app is able to synchronise data getting everything it needs from the CRM and sending the manipulated entities back to be stored on the server. I implemented a priority queue, as some entities need to be saved before other ones, i.e. the order entity needs to exist before products can be added to an order.
The app made for Campari is similar to Spinmaster, used by agents to show marketing materials to potential customer. There is the stripe, but instead of making a screenshot of the product page I inserted an image.
Each agent has a login, and can see a part of the catalog based on his role, so sections and products are filtered.
Since the app was needed for iPad and for Windows I made an Electron version of it, extending the component we use on Catflow to preview a tablet app.
Our client wanted to have an app for selling a variety of products related to houses and gardens, like pools, threes, chairs, patios and pavements. The idea was to let the user place each product on a picture, drawing the pavement and rotating 3D object, then send the screenshot, together with the list of products included into the project, to place an order.
The app was available on iOS and Android and the project started before ARKit was introduced, so I opted for Three.js
Il Cittadino Magazine
Catflow was used by a newspaper to publish a monthly periodical. The articles were inserted into Catflow and each month a new issue of the magazine was published to the apps that downloaded it after receiving a push notification or when the user chose to download a specific issue from the home page.
The app was available for iPhone, iPad and Android devices.
With this app it is possibile to pay fines, bills and taxes by manually entering the fields or by scanning a barcode or taking a picture of a bill and letting the app recognise the fields.
At the end of the payment process, if the user doesn’t want to pay immediately the information can be saved into the app’s internal calendar as a reminder or can be sent to of the affiliated agencies. If the payment is sent to an agency the user can pay the bill by showing the cashier the payment id generated by the app, and is be able to access the history of payment made in the past.
I use Google Vision to recognise a set of known templates and fill automatically the form with the amount, the payment ID etc. or we scan the barcode if present.
The navigation between pages is done via links and I implemented a prefetch mechanism to allow a smoother transition.