Opendate is a statup offering live music management platform that automates the event lifecycle. They based in Indianapolis, IN. I was approached by Opendate in the mid of 2021. They needed to build an iOS app to automate music ticketing. I joined a team of developers and designers, and was provided with a well-defined API and great design.
The app is used as a point of sale by a cashier and a door attendant. Along with manual credit card details entry, we used Stripe terminal to accept and process the payments. Unfortunately, Stripe Terminal SDK didn’t support Flutter at that moment, so I built a bridge between native Swift code and Flutter using platform channels. Since I have rich experience in native iOS development, I did not have any difficulties with this task.
Initially, we wanted to implement the order total calculation logic in the app to fully match the logic on the server side. I suggested to move the logic to the server-side to reduce maintenance costs. This saved us at least 2 hours of development time and kept us from releasing another update when we needed to update the logic a few months later.
I worked with Andrey on the development of a mobile app for one of my businesses and he was exceptional. He set clear expectations for the project, his communication was top-notch, and he delivered what he said he would deliver. On time and on budget. I will definitely work with Andrey again.
Leafarise is a gardening app that helps gardeners to track their plants and keep a garden journal.
I solely built both the backend and the client-side. Though I worked alone, I still used GitHub for version control, created pull requests, and so on. When I was working on this project, the Flutter team had released Flutter 2.0, and I migrated the entire project to the new version of Flutter and Dart.
Google Firebase was used for a database, authentication, backend logic, analytics, crash reporting, and static website hosting. Since I have a rich experience with Firebase, it didn’t take much time to integrate these features.
Performance is crucial to the users, so I decided to implement a progressive image loading. I used the same approach in my previous freelance project, and it recommended itself very well.
One of the requirements was public beta testing. I set up both Apple TestFlight public beta testing and Google Play Store open beta track. Beta testers were able to try out the app before release. The company collected helpful feedback from them, getting the opportunity to polish the app for a wider audience.
I also took care of submitting the app to the stores. I generated all the necessary screenshots, uploaded crashlytics symbols for getting crash details, and submitted both builds to AppStore and Google Play. Due to careful preparation, the submission process went flawlessly, without any rejections from the review teams.
Explorial is a mobile app for travelers that lets to explore a city in Switzerland along with playing a fun game with friends.
Explorial GmbH approached me to join their mobile development team in early 2020. They expected to get a solid and well-architected app that they could maintain on their own. The client provided me with clean mockups and a detailed gameplay description.
Our team used Trello for task management. We communicated via Slack. My responsibility was to create a framework: navigation, business logic, data access layer, and main screens.
One of the challenging parts was internationalization: the app initially should be localized on German language only, with the possibility of adding more languages. I used flutter_i18n library for localization, as it recommended itself as a quick and reliable option in my previous projects.
The app extensively uses location services, so we need to ask permission to use them politely. I suggested adding a priming screen explaining why does the app require location access. According to researches, this approach increases conversion rates significantly.
This project took 2.5 months and 70 hours of pure development time. By the time the application was released, they had added new game content (new cities) based on the foundation that I had built.
Professional, reliable, very good code quality -> perfect partnership :) Thanks to you we have a solid app foundation to build on.
Tahlili is an MVP app for health tracking. It simplifies entering and analyzing health variables, such as body temperature, blood pressure, and many others.
I started working on the project in March 2020. The client wanted to have a well-architected app with a good-looking but straightforward UI, and he provided me with well-defined functional specifications, as well as very basic design mock-ups. Based on that, I created a technical specification for each app screen and designed the app architecture and the database schema. My client and I constantly discussed the specification through Upwork messages to ensure that we are on the same page. All the specifications I made were available on the GitLab wiki for any team member.
Based on the specifications, I started to code the app. The backend wasn’t ready, so I stubbed all the API calls to quickly create a proof of concept app that showcases the idea. The data access layer was designed to be easily swapped with real-world backend API in the future.
The application should have several graphs, and I integrated charts_flutter library to add them. Unfortunately, it wasn’t flexible enough for our needs, so I had to implement most of the charts with CustomPainter class. That didn’t take much time, as I already had a good experience with Flutter custom drawing.
The UI should look native on both iOS and Android platforms, which means some elements would look different. Also, the app needs to reuse as much code as possible. I found a good balance between these requirements, not going beyond the bounds of the agreed estimates.
Another requirement was to add Arabic localization with RTL text direction. I chose the flutter_i18n library for localization, as it allows to use YAML localization files, which is very convenient.
I worked with Tahlili again in 2021 to redesign the app and add new charts and screens. They hired another Flutter developer, so I guided him through the project and did code reviews. He focused on the UI part of the app while I was responsible for the entire mobile project and developed the whole business logic.
This is an online furniture shopping app for furniture company from West Africa. It targets Android devices only and is built on Flutter/Dart. It uses Google Firebase as a backend.
I started working on the project in early November 2019. The customer provided me with mockups in PDF format. After that, I started thinking about the database structure and the app architecture, and setting up the environment. I think that it’s important to plan first and then start developing the app.
Next, I built an authentication system. It was SMS-based authentication using Google Firebase Auth, because people in West Africa are used to using phone numbers rather than email addresses for authentication.
In mid-December 2019, the app was completed: right on time, according to the schedule approved by the customer. I implemented product browsing functionality, product details (including product options, such as size and color), cart screen, checkout flow (including choosing an address and payment method), order tracking and other, a total of 14 screens. A discount system has also been added. I believe that fast image loading is important for online shopping app, so I chose the progressive image loading approach used by Medium and other popular services. First, the app downloads a very small blurry image thumbnail and present a product with the thumbnail to the user. After that it starts downloading the full-sized version of the image in background and replaces the thumbnail immediately after downloading it. I had to create a Google Cloud Function trigger to automatically generate a thumbnail every time a new image is uploaded to Google Cloud Strage. sharp npm package was used for that. This approach has improved the browsing experience, especially for people with poor internet connectivity. Also, the app was localized to 2 languages: English and French.
Later, the customer asked me to implement email notifications about new orders. I added another trigger that generates an email based on a special email-optimized HTML template and sends it to a predefined email address. For sending an email I used nodemailer npm package.
We communicated with the customer via a corporate Slack channel. I documented my work using GitLab wiki so that any future developer can easily join the development process. Guys from the company that hired me were tech savvy enough to build the app directly from the repository, so we didn’t spend time for setting up CI/CD for the client app. However, I set up GitLab CI/CD for the server side.
This is the second time my company has hired Andrey for a software development work. As always, he has been to the task, completing the job on time and budget. Andrey systematically documented everything - from product features, to codes, to issues - making it super easy for me and my team to stay current on the project. I will hire Andrey time and time again.
This is a large project I worked on since 2017. RaffleHunter is an iOS app, letting people win cool prizes from companies. I was provided with designs in Sketch format by my employer, PurpleVolt Inc., and, after refining the requirements, started developing the app using Swift. To reach AppStore faster I was also asked to implement a backend using Parse Server hosted on back4app.com for the MVP version of the app. In a few months PurpleVolt had their own backend ready, and we’d successfully migrated the app onto it. I used that chance to refactor the code and switch from callbacks to promises (Hydra library), which made the codebase less verbose and more structured.
For simpler user engagement we’ve implemented social logins (Facebook and Google) along with standard email/password login. Also the client asked me to implement a referral system, so people could increase their chances of winning a raffle by inviting friends. I used Branch SDK for that. It gave us the ability to know the user’s referrer even before the user has installed the app.
I integrated CircleCI for automated tests: it ran unit tests every time we pushed commits to GitHub and sends reports directly to Slack. CircleCI integration along with a strategy of covering just implemented feature by unit tests reduced number of issues and crashes: we had 0 crashes since then.
After 6 months of development the project has grown and PurpleVolt has hired another iOS developer. I took the lead of iOS development, explained the architecture of the project and prepared a detailed README for him. I also commented the code base as much as possible, so it’s easier for someone to jump into the project.
By the beginning of 2018 our team has grown to 10 people, including designers, QA, Android, iOS and backend developers. We’ve communicated via Slack channels and assigned tasks to each other on Trello. These tools greatly improved our cooperation. Since I was the only person who worked on the project from its beginning, I was often asked to clarify the requirements or suggest a way to improve or change UX on a certain feature. This helped to reduce a workload of the product manager and allowed him to focus on the strategy of the project and design tasks.
A git branching model I set up included 3 main branches: master, beta and develop. If there was a large feature to work on, I created a new branch for that feature, so it’s possible to quickly hold off the progress on the feature and switch to develop branch. Later I made a full continuous integration using Fastlane and CircleCI: pushing to beta branch triggered a new beta release to TestFlight automatically. Pushing to master branch triggered a submission of a release candidate build (which is pointing to the production server) to TestFlight automatically. After RC build is reviewed by QA team, it got submitted to the AppStore. This model saved us a lot of time.
Studio Music Player is a music app playing tracks from iTunes library. The client wanted to have an app for people, who wants to have a precise control over the sound quality. The app was initially written on Swift 1.3, then migrated to Swift 2 and Swift 3. According to the requirements I’ve implemented a wide number of features and tweaks: equalizer, factory and user presets, sound effects, skins and user playlists. Storing presets and user playlists required to integrate Core Data framework.
I worked closely with the client in order to bring his vision of the app design to life. AutoLayout was used to make the app Universal (suitable for both iPhone and iPad) and to look good in both Landscape and Portrait mode. The client also wanted to let the user to select a skin for entire app. I implemented a system, which redraws the current screen and also notifies all other opened screens that the user has changed the skin.
According to requirements factory presets must be easy to update without resubmitting the app, so I suggested to store them on the web, and let the app to download them and then save locally on device. Since the app works with audio files, it must be fast and well optimized. I made a bunch of small and large optimizations using Xcode Instruments. We’ve also covered edge-cases of playing audio, e.g. when Siri is called, when incoming or outgoing call is occurred, when headphones are plugged or unplugged. When a device (headphones, bluetooth speakers, car) is connected with iPhone, the app automatically selects an associated preset.
The client asked to prepare two app versions: Paid and Free version with In-App Purchases. I implemented it by having two targets (Paid and Free) in the project to avoid having two distinct project and integrated In-App Purchases with using CargoBay library.
Localization was another major feature requested by the client. He wanted to translate the UI to 21 languages. I extracted all localizable strings from source code and storyboards to *.strings files, then the client had them translated to necessary languages. We’ve integrated the files back to the project and got internationalized interface.
There is a spin-off project: Studio Music Player DX with the ability to play tracks stored in Dropbox folder and from iTunes Shared folder. Other than that it has the same functionality as Studio Music Player.
I worked with CenterPunch at the end of 2014 to build a quiz app. As Swift programming language was too young at that time the project was written on Objective C. There wasn’t a complex business logic in the requirements, so I’ve advised to select Parse.com as a backend for the app to save on overall cost and reduce development time. As we figured out later, their servces fully met our needs.
The app has nice and very flexible design, as the client asked to implement a mechanism allowing setting colors for each quiz and section individually without resubmitting the app to AppStore. Quizzes also have different types, so the app is able to present quizzes in different formats according to their types. For example, there is a Tinder-like quiz, where the user can swipe cards left or right. Another quiz type involves a countdown timer. All of quizzes are controlled by CenterPunch remotely and don’t require the app to be updated or rebuilt.
I’ve integrated 2 SDKs for analytics: Mixpanel and Facebook, and set appropriate events for these SDKs. Analytic reports helped CenterPunch to better understand the user’s behavior within the app and to find ways to improve UX.
In January 2016 Parse.com announced they’re winding down Parse service and making it open-source. I was hired again in late 2016 to migrate from Parse.com. I’ve successfully migrated the database and backend to self-hosted Parse Server + MongoDB instance on AWS S3, without downtime and any data loss.
In late 2021 I was hired by CenterPunch again to update the app for new Apple devices.
Andrey has been a vital and extraordinary contributor to my project and team.
He was professional, provided accurate estimates and delivered high quality work on schedule. In addition to his excellent technical skills, Andrey also provided key architecture and design recommendations, which ultimately led to a better product.
I would gladly work with Andrey on future projects.