What we’ve done
In the past 6 months
- I’ve tried things with GeoJSON data and mapping on iOS. I like the fact that it’s a standard, but I had a hard time creating the map functionalities I wanted. I did good things, which I will possibly reuse one day. It was mainly a Proof Of Concept, for a future feature. It’s not the case yet, but we will support GeoJSON in the Monki Map API later.
- I improved https://docs.monkiprojects.com, with some terminology and a description of features.
- The old Monki Map app icon was never intended to be used in production. It had too many details, and was a raster graphic, which meant it didn’t look great in small sizes, and looked very bad in large sizes. That’s why I redesigned it, using a vector graphics tool. I will post it here someday.
- As explained in the docs, places have IDs starting with
place_
. Unfortunately, this means place IDs are nowString
s, and notUUID
s. This makes working with them harder, so I wrote swift-prefixed-type, a library providing a type-safe,Codable
data structure for prefixed types. - Another Proof Of Concept I wrote is reading an image’s EXIF data at images import,
to create places at the location of the picture,
as described in the docs.
When making the code cleaner, I wrote and published swiftui-photos-picker,
PHPickerViewController
for SwiftUI. - I started writing a Swift iplementation of biscuit, an authentication and authorization token we’ve been working on a lot at Clever Cloud. It’s the authorization token all of Monki Projects' apps will use, and this implementation is required in order for Monki Map to allow user log in. As always, biscuit-swift is open-source on GitHub.
This month
Core Data
I rewrote the app data store to use Core Data the right way. We were using some custom setup, like a local API, but this meant a lot of boilerplate code and a very bad integration with UIKit and SwiftUI. This was mainly done thanks to Donny Wals very complete book “Practical Core Data”. It’s a real goldmine, I learned the key Core Data concepts I was missing, it’s the click I needed.
Search parser
In the version presented on this website, we show a working search bar. The problem with it is that the code backing it was very ugly, and not reusable at all. Also, it was prone to performance issues as the app would grow, which will soon be fixed with the use of Core Data.
To fix those issues, I wrote a reusable search parser (https://github.com/MonkiProjects/monki-map-search-parser). It uses parser combinators and a Parsing Expression Grammar (PEG) to make the code more performant, more robust and good-looking (really, I’m surprised how readable it is).
I wrote tests, described the grammar for users and setup workflows to ensure the parser works correctly on both Linux and macOS. Making it cross-platform was necessary, because I will use the same parser in the API that will serve all other platforms.
Website fixes
As you had probably noticed browsing this website, there were a few (enormous) bugs which occurred from time to time. I fixed them all, yay 🎉
- For some reason, clicking a link to a cached page (even with HTTPS link) would switch to an unsecure version of the website (HTTP).
I don’t really know why this happened,
but I added a trailing slash (
/
) to menu links and it fixed the issue 🤷🏻♂️ - The most problematic issue was that if you opened a cached page, it would load without the CSS style sheet 🤭
Surprise, this was also a cache problem 🤪 I had put an
integrity
field to the HTML tag loading the CSS file. Unfortunately, when the file was cached, it would resolve as a-1
size file, and the integrity check would fail. For security reasons, the browser would not load the cached file. I just removed it. - The third one was quite weird too. Because of it, the website font (Nunito) would not load. I had seen the problem months ago,
but I had no idea where it came from. I thought about different things:
- Font URL changed: The font is not stored locally in the website’s files, it’s loaded from a website. If this URL changed for some reason, which is not supposed to happen, it would break the link. Obviously, this was not the reason.
- CORS: Because of CORS, the server delivering the font could block my website from accessing this font. As the font comes from Google Fonts, it’s not subject to CORS restrictions. Another dead end.
- Quotas / subscriptions: When I chose the font, it was free. However, things could have changed, and after a quick check, it did not. That’s good because I can keep it, but bad because I had to dig deeper.
- PostCSS bug: Next I thought “maybe I used a wrong PostCSS tag to load the font”,
but
@import url();
is a regular CSS tag… which means it should be read correctly. - No more idea, let’s try things: The problem only happened in the production website, not locally on my computer (i.e. when developing). I opened this website and inspected the CSS style sheet. To my surprise, there was a Tailwind warning written in plain text (not a comment) on the first line which is… the line that imports the font! Hurray, I have something 🎉
- When I improved this website a few months ago,
I switched from Bootstrap to Tailwind. Now I knew the bug came from here.
The warning said “warn - As of Tailwind CSS v2.2, `lightBlue` has been renamed to `sky`. warn - Please update your color palette to eliminate this warning.".
I checked my code, and
lightBlue
was never used 🤔 I tried manually upgrading Tailwind from v2.1 to v2.2, but this did nothing. I still didn’t have the problem locally, and it stayed in production. - I figured out the problematic line was
…colors
. It imported all of Tailwind’s colors, no matter if I used it or not. I chose to do this to keep all colors available, not just my custom colors, but for Tailwind this meant I was using it. What solved my problem is camiant’s comment in an issue on Tailwind’s repository. I added the temporary fix until Tailwind removes the color from its default palette and it solved the issue. - Who would have thought the missing font came from a Tailwind warning in my CSS file, due to something I wasn’t using, put on the first line due to minification,
and which would prevent browsers from reading the
@import
statement? 🤯
- While fixing those 3 issues, I realized I could improve something else: the color of the browser’s bar and page background (see Meta Theme Color and Trickery on css-tricks.com) to avoid white straps at the top of the page (and bottom when scrolling). I used the same color as the header and footer so now it should look gorgeous 🙂
What we’re doing
Switching back to UIKit
You may already know I spent hundreds of hours (yeah… this much) rewriting the Monki Map using different architectures to find the right fit. Well, after a long talk during a training session with traceurs from Nantes, I realized the version I was working on for nearly a year didn’t have the features it had in July 2020, and this was the most important.
It really clicked me that the most important is having a working app, something everyone can touch and feel. That’s why I made the hard choice to revert the app as it was back then. That’s the magic of git, a tool developers use everyday for its versioning capabilities.
This time, I didn’t start again from scratch, I just took the working year-old app to progressively include the new things I’ve been working on since then. If you’re familiar with iOS development, I switched back to a UIKit-based app, while I was working on a SwiftUI-focused one for almost a year.
I’m progressively transforming what was complex code from a year ago to new code using Core Data correctly and using more reusable structures (like the search parser).
Where we are
Well, it’s always hard to say, but to give you a very simple TODO list, here’s what’s done and remaining:
- Buttons to create places: working but bad code
- Place creation (on-device storage): working
- Global map: broken, waiting for search bar to repair
- Search bar
- “Parsing” (understanding text queries): working, clean and reusable code
- Query builder screen (a handy screen to filter places easily): almost done
- Map places filtering: broken, waiting for above tasks to repair
- Place selection: working
- Map markers clustering: working
- Place edition: screen broken, waiting for fixed map to repair