Implementing Calorie Tracking Through a Mobile Application
A calorie counting application is first and foremost a product database, a reliable algorithm for calculating macronutrients (KBZHU), and integration with platform health data repositories. UX and ML for food recognition sit on top of this foundation.
Product Database
Building your own database is laborious. For a start, use ready-made APIs:
Open Food Facts — an open database with 3+ million products, REST API is free:
GET https://world.openfoodfacts.org/api/v2/product/{barcode}.json
GET https://world.openfoodfacts.org/cgi/search.pl?search_terms=apple&json=true
The response contains nutriments.energy-kcal_100g, nutriments.proteins_100g, etc. Data quality is uneven: excellent for global brands, gaps for local products.
USDA FoodData Central — a detailed nutritional database for the USA, free API with a key:
GET https://api.nal.usda.gov/fdc/v1/foods/search?query=chicken+breast&api_key={key}
For the Russian market — integrate with databases like "Product Composition" or your own database with crowdsourcing.
Local caching: popular products (top 1000 by search frequency) are cached in Room/CoreData. Search by barcode or name first in the local database, miss — request to API.
Barcode Scanning
The fastest way to add a product. On iOS — DataScannerViewController (iOS 16+, Vision framework under the hood) or AVCaptureMetadataOutput for older versions. On Android — CameraX + BarcodeScanning from ML Kit:
val options = BarcodeScannerOptions.Builder()
.setBarcodeFormats(Barcode.FORMAT_EAN_13, Barcode.FORMAT_EAN_8, Barcode.FORMAT_QR_CODE)
.build()
val scanner = BarcodeScanning.getClient(options)
val imageAnalysis = ImageAnalysis.Builder()
.setTargetResolution(Size(1280, 720))
.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
.build()
imageAnalysis.setAnalyzer(executor) { imageProxy ->
val mediaImage = imageProxy.image ?: return@setAnalyzer imageProxy.close()
val image = InputImage.fromMediaImage(mediaImage, imageProxy.imageInfo.rotationDegrees)
scanner.process(image)
.addOnSuccessListener { barcodes ->
barcodes.firstOrNull()?.rawValue?.let { barcode ->
onBarcodeDetected(barcode)
}
}
.addOnCompleteListener { imageProxy.close() }
}
Calculating Macronutrients
Basic formulas:
BMR (Mifflin-St Jeor):
- Males:
10 × weight(kg) + 6.25 × height(cm) − 5 × age + 5 - Females:
10 × weight(kg) + 6.25 × height(cm) − 5 × age − 161
TDEE = BMR × activity coefficient (1.2–1.9). Deficit/surplus — target calories minus TDEE.
Daily macronutrient norm in grams: protein 1.6–2.2 g/kg body weight (for weight loss/gain), fats 0.8–1.2 g/kg, carbohydrates — remainder from total calories.
Integration with HealthKit / Health Connect
iOS — recording calories:
let calorieType = HKQuantityType(.dietaryEnergyConsumed)
let calorieSample = HKQuantitySample(
type: calorieType,
quantity: HKQuantity(unit: .kilocalorie(), doubleValue: 450),
start: mealTime,
end: mealTime
)
healthStore.save(calorieSample) { _, _ in }
You can also write dietaryProtein, dietaryFatTotal, dietaryCarbohydrates — then the data will appear in the "Nutrition" section in the Health app.
Android — Health Connect:
val nutritionRecord = NutritionRecord(
startTime = mealTime,
startZoneOffset = ZoneOffset.systemDefault().getRules().getOffset(mealTime),
endTime = mealTime.plusMinutes(30),
endZoneOffset = ZoneOffset.systemDefault().getRules().getOffset(mealTime),
energy = Energy.kilocalories(450.0),
protein = Mass.grams(35.0),
totalCarbohydrate = Mass.grams(60.0),
totalFat = Mass.grams(15.0),
mealType = NutritionRecord.MEAL_TYPE_LUNCH
)
healthConnectClient.insertRecords(listOf(nutritionRecord))
Food Recognition by Photo (Optional)
ML Kit ImageLabeling based on MobileNetV2 recognizes ~1000 object categories — not dishes, but objects like "apple", "sandwich". For accurate dish recognition, a specialized model is needed. Options:
- Logmeal API — REST API for food recognition, ~92% accuracy on standard dishes
- Custom model on CoreML / TensorFlow Lite, trained on Food-101 dataset or your own
Matching the recognition result with the product database — fuzzy search by category name.
Timeline
Basic application with manual entry, barcode scanner, and HealthKit/Health Connect integration — 6–10 weeks. With food recognition by photo, server synchronization, and analytics — 3–5 months.







