โ† Back to portfolio
๐Ÿ˜Ž๐Ÿ’ง AquaVibe
App Store: v1.0.4 ยท 2025-08

๐Ÿ˜Ž๐Ÿ’ง AquaVibe

Track your wellness journey with AquaVibe, now published in the App Store as Mood Water Tracker: AquaVibe ๐Ÿ˜Š๐Ÿ’ฆ

The application allows users to set up to 3 daily reminders for consistent tracking and visualize their well-being with beautiful, interactive charts ๐Ÿ“ˆ

๐Ÿ‘จโ€๐Ÿ’ป Technology Used

  • SwiftUI
  • HealthKit
  • Charts
  • UserNotifications
  • WishKit
  • StoreKit2, RevenueCat
  • TelemetryDeck
  • AVKit, AVFoundation

๐Ÿ“Œ What Changed In The Repo

Biggest evolution was shipping AquaVibe from zero to production app during RevenueCat Ship-a-ton, and implementing reliable State of Mind fetching/saving with HealthKit for iOS 18+.

๐ŸŽฅ AquaVibe In Action

AquaVibe demo video

๐Ÿ† Standout Success

AquaVibe was created from scratch to a fully working iOS application during RevenueCat Ship-a-ton competition.

AquaVibe won a Participation Prize in RevenueCat Ship-a-ton competition.

The most challenging part was understanding State of Mind logic. Documentation and sample projects were not enough, so extensive testing was needed to verify how to correctly fetch and save mood/emotion data to Apple HealthKit.

State of Mind is also new from iOS 18, so high-quality implementation references were limited.

func fetchStateOfMindData(forKind kind: HKStateOfMind.Kind) async throws -> [HKStateOfMind] {
        do {
            let stateOfMindType = HKSampleType.stateOfMindType()
            
            // Create a predicate for the specified kind
            let kindPredicate = HKQuery.predicateForStatesOfMind(with: kind)
            
            // Combine with the sample type predicate
            let combinedPredicate = NSCompoundPredicate(andPredicateWithSubpredicates: [
                HKQuery.predicateForSamples(withStart: nil, end: nil, options: .strictStartDate),
                kindPredicate
            ])
            
            let descriptor = HKSampleQueryDescriptor(
                predicates: [.sample(type: stateOfMindType, predicate: combinedPredicate)],
                sortDescriptors: [SortDescriptor(\.startDate, order: .reverse)]
            )
            
            let samples = try await descriptor.result(for: store)
            
            if let stateOfMindSamples = samples as? [HKStateOfMind] {
                print("โœ… Fetch done for \(kind)")
                print("Number of samples: \(stateOfMindSamples.count)")
                return stateOfMindSamples
            } else {
                print("โŒ No HKStateOfMind samples found for \(kind)")
                return []
            }
        } catch {
            print("โŒ Error fetching state of mind data for \(kind): \(error.localizedDescription)")
            return []
        }
    }
AquaVibe app screenshot
AquaVibe UI preview

โœ… Entireness

Nevertheless, while creating this mood and water intake reminder app, I have also included:

  • Concurrency
  • Error handling & alerts
  • Text input validation
  • Project organization - MVVM Architecture
  • Current App Store release: v1.0.4 (08/2025)

โ„น๏ธ License

AquaVibe is the property of Marcin Jฤ™drzejak. Unauthorized copying, distribution, or modification of this application is strictly prohibited.