Microsoft Awards $150K to FitRadar as it Scales Global Fitness Community

FitRadar has received $150,000 in Microsoft support to scale its fitness community platform, enhance technology infrastructure, and expand across Europe. The startup aims to simplify sports discovery and participation while strengthening its position in the growing fitness and wellness technology market.

Read more: https://www.analyticsinsight.net/news/startup-news-today-microsoft-awards-150k-to-fitradar-as-it-scales-global-fitness-community

Hosting paid events just got easier

Great news from FitRadar – now you can create paid events without registering in Stripe. That’s right – no extra steps, no third-party setup. Just open the app, create your event, set the price, and you’re ready to go.

Whether you’re a fitness coach, yoga instructor, or just love organizing active meetups – it’s never been easier to earn through your passion.

Plus, your events will be visible to a growing community of people looking for fun, motivating ways to stay active. You set the vibe, the schedule, and the price — and we help you get noticed.

FitRadar is all about making fitness social, accessible, and rewarding – for everyone. So if you’ve been waiting for a chance to start or grow your own fitness community, now’s the time.

Download the app today and start turning your energy into income 👉 https://ej.uz/fitradar

SwiftUI Tricks: Part 2

Continue for a series of articles about tips and tricks for SwiftUI.

Photo by Amza Andrei on Unsplash

It is hard to imagine application without buttons. Sometimes it is not obvious. any clickable link i.e. text or image or combination of both may be realised on top of button functionality power. In FitRadar user is interacting with application by pressing and clicking and pushing many UI elements expanding details about trainer, trainer’s rating, statistics and other information. Same for sport event which has many attributes and user can instantly get access to any of it.

Here is technical problem to solve: quite often you don’t want your UI element look like button (change color on press, etc). The most advised approach online would be to use custom button style PlainButtonStyle.

Button {
// do some logic
} label: {
// some fancy UI
}
.buttonStyle(PlainButtonStyle())

However, it’s still keep it’s visual effect as described in documentation

/// A button style that doesn't style or decorate its content while idle, but
/// may apply a visual effect to indicate the pressed, focused, or enabled state
/// of the button.

Here is trick to remove any visual or behavioural indication of a button. Let’s declare a custom style

struct NoneButtonStyle: ButtonStyle {
func makeBody(configuration: Self.Configuration) -> some View {
configuration.label
}
}

Now use where you want to keep functionality of a button yet keep it simple

Button {
// do some logic
} label: {
// some fancy UI
}
.buttonStyle(NoneButtonStyle())

That’s all for today. Join the waiting list at https://www.fitradar.me to be the first one to know when app released.

P.S. Text by Dmitrijs Beloborodvs

Making sure data is valid and business rules are kept

fitness
workout
gym
sports
personal trainer
venture capital
startup

Our Fitradar back-end solution is created based on Clean Architecture as described in this article and explained in this conference talk. One part of the back-end solution is incoming request validation, and in order to implement it as a part of the MediatR pipeline we are using FluentValidation library that replaces built-in ASP.NET Core validation system. At the beginning of the project it seemed that all we have to do is just to create a custom validator derived from AbstractValidator and perform the validation of an Application Model in a single class. And that is how we started to implement the validation. And since the library has quite enhanced capabilities that allow implementing complex validation rules for a while we didn’t notice any problems. Until the moment when we realized that not all validation rules are simple incoming Data Model validation. Some of the rules expressed our business logic rules and restrictions. And so we started to think about splitting the rules across the layers and following are multi step validation solution we came up with:

  • Application level validation. At this level incoming JSON data model fields validation is performed. The field types are validated automatically by ASP.NET core built-in Model binding but the other validation rules are executed by FluentValidation including:
    • required field validation
    • text field length validation
    • numeric field range validation
  • Domain level validation. At the domain level we apply Domain Driven Design approach and therefore instead of FluentValidation we decided to use Specification pattern. We liked the idea that we can move the validation logic outside the Domain Entity to the separate Validator. By doing that we were able to bind validation logic to incoming commands instead of Domain Entity. For example we have an entity SportEvent and several commands that call methods inside that entity like Update Sport Event and Cancel Sport Event. Now because the different commands have different business requirements for the same Entity property it would be hard to implement them with FluentValidation. For example property BookedSeats in case of Update Sport Event command should be 0, but in case of Cancel Sport Event command it is allowed that someone has already booked a particular Sport Event. And bellow is how the Cancel Sport Event validator looks like:
public sealed class EventCancellationValidator : EntityValidatorBase
{
    public EventCancellationValidator()
    {
        AddValidation("CancellationTimeValidation",            
                new ValidationRule<SportEventInstance>(
                new Specification<SportEventInstance>(sportEvent =>
                    sportEvent.StartTime > DateTime.UtcNow),
                ValidationErrorCodes.CANCELLATION_TOO_LATE, "It is not possible to cancel the 
        Sport Event after it has started", "SportEventStartTime"));
    }
}
  • Database level validation. For accessing database we are using Entity Framework Core and to make sure the database models are in tune with database constraints we are using built in property attributes and classes that implement IEntityTypeConfiguration interface that allows to define database constraints like Primary Key, Foreign Key and Unique Key.

P.S. Please follow our Facebook page for more!

SwiftUI Tricks: Part 1

Photo by Clint Patterson on Unsplash

This is the first of mini articles in a series of SwiftUI tips and tricks.

One of the common tasks in mane applications is to determine screen width and layout items accordingly. FitRadar is not an exception. Many UI elements should be adjusted to screen size. There are two problems, tho: “screen” and “width”.

Screen

Most often developer’s think of a “view on screen” when saying “screen”. Physical screen size is equal to view controller size and vice versa. Yet we know that today (as per middle of 2021) we have iPad which allow run two apps side by side, or even one app in two “panels”. Know knows what else Apple introduce in future. We expect our fitness app to run on all possible devices: phones, tablets, watches, etc. So, we can’t rely on physical screen.

Width

Since there is no yet (as per middle of 2021) devices with changing screen, most often developers think of a width of screen as a constant value. However, changing screen zoom (General -> Display & Brightness ->Display Zoom) actually change it. The other and most common scenario: rotation.

So, knowing these two problems we cannot rely anymore on something simple as

UIScreen.main.bounds.size.width

GeometryReader

GeometryReader is second most advised way to get current view geometry. It does it best, but practise show that item places inside it acts differently on iOS 13 and iOS 14. And we actually want to avoid place our UI elements inside it.

For the trick we use PreferenceKey. Just add following code somewhere in project

struct SizePreferenceKey: PreferenceKey {   typealias Value = CGSize   static var defaultValue: Value = .zero   static func reduce(value: inout Value, nextValue: () -> Value) {    value = nextValue()   }}

Next, define some variable to keep current screen width

@State private var screenWidth: CGFloat = 0

Place geometry reader somewhere on the view which size you need to track. But other UI elements can now be placed outside GeometryReader

VStack {    GeometryReader { proxy in        Spacer()         .preference(key: SizePreferenceKey.self, value: proxy.size)    }    .frame(height: 1)    .onPreferenceChange(SizePreferenceKey.self) { preferences in        self.screenWidth = preferences.width    }    Rectangle()        .fill(Color.red)        .frame(width: screenWidth / 2, height: screenWidth / 3)}

This solution works equally on iOS 13 and 14. Enjoy!

P.S. Please visit our website: https://www.fitradar.me/ and join the mailing list! Fitness is closer than you think.

P.S.S. Text by https://dmi3j.medium.com/