Passio Nutrition-AI
  • Nutrition-AI SDK Overview
  • Guides
    • Nutrition AI SDK
      • SDK Key and minimum requirements
      • Installation
      • Configure the SDK
      • Use Cases
        • Food recognition
        • Nutrition data
        • Barcode scanning
        • Nutrition Facts scanning
        • Search, Food Icons, RefCode
        • Speech recognition
        • Nutrition Advisor
        • Suggestions and Meal Plans
        • User created foods and reports
    • iOS SDK Docs
      • Before getting started
      • Getting the ml models to the device
      • Run the demos first
      • Adding Passio SDK into your project
      • Initialize and configure the SDK
      • Start/Stop food detection
      • Food Recognition Delegate
      • Migration from SDK 1.4.X to 2.x
      • SDK API
      • Quick Start Guide
        • Installation
        • Configure the SDK (UIKit)
        • Recognise food using image
        • Food Details
    • Android SDK Docs
      • Getting started
        • Include the library
        • Camera
        • SDK Initialization and Configuration
        • Food detection session
        • Visual, Barcode and Packaged Food detection
        • Nutritional Database
        • Sandbox app
      • Troubleshooting on Android
      • Migration from SDK version 1.4.x to 2.x
      • Quick Start Guide
        • Importing the Android SDK to a project
        • Configure SDK and handle the result
        • RecognizeImageRemote
        • Food Details
    • React Native SDK Docs
      • Getting Started
        • Installation
        • SDK Initialization and Configuration
      • API Reference
        • configure & requestCameraAuthorization
        • recognizeImageRemote
        • searchForFood & searchForFoodSemantic
        • startFoodDetection
          • FoodDetectionEvent
        • fetchFoodItemForProductCode
        • fetchFoodItemForRefCode
        • fetchFoodItemForDataInfo
        • startNutritionFactsDetection
        • fetchFoodItemForPassioID
        • recognizeSpeechRemote
        • Fetch Nutrients
        • onDowloadingPassioModelCallBacks
        • detectFoodFromImageURI
        • addToPersonalization
        • updateLanguage
        • fetchHiddenIngredients
        • fetchVisualAlternatives
        • fetchPossibleIngredients
      • Properties
        • PassioFoodItem
        • PassioFoodDataInfo
        • PassioFoodAmount
        • PassioIngredient
        • PassioNutrients
        • UnitMass
        • ServingUnit
        • ServingSize
        • PassioSearchResult
        • NutritionFacts
        • PassioNutritionPreview
        • PassioSpeechRecognitionModel
        • PassioLogAction
        • PassioAdvisorFoodInfo
        • FoodCandidates
        • FoodDetectionEvent
        • NutritionDetectionEvent
        • DetectedCandidate
        • BarcodeCandidate
        • PackagedFoodCode
        • AmountEstimate
        • ImagesInfo
        • PassioStatus
        • FoodDetectionEvent
        • NutritionFacts
        • PassioMealPlan
        • PassioMealPlanItem
      • Nutriton Advisor
        • initConversation
        • sendMessage
        • sendImage
        • Guide
          • useNutritionAdvisor
        • Properties
          • PassioAdvisorResponse
          • PassioAdvisorMessageResultStatus
          • PassioAdvisorResultStatus
      • Quick Start Guide
        • Installation
        • Configure the SDK
        • RecognizeImageRemote
        • Food Detail
      • Guide
        • Integrate SDK Setup
        • Integrate Quick Scan
        • Integrate Food Search
        • Integrate Food Editor with Recipe
        • Integrate MealPlan
        • Integrate Suggestions
        • Integrate recognizeImageRemote
      • Components
        • DetectionCameraView
        • PassioIconView
      • Changelog
      • More
        • Display Macro Chart
          • MockFood
          • Utils PassioNutrient
        • Display Micro Progress
        • Getting nutrition value for a FoodItem
        • Getting nutrition value for a Recipe
        • Recalculate the nutrition value based on serving size options.
      • Migrations
        • Migrating from SDK 2.X to version 3.X
        • Structure Migrations From SDK 3.X to SDK 2.X
        • [Deprecated] Migrating from SDK 1.X to version 2.X
        • [Deprecated] Getting Started (v1)
          • Installation
          • SDK Initialization and Configuration
          • Start food detection
          • FoodDetectionEvent
          • Nutritional Database
      • Troubleshooting on RN
      • V2
        • Getting Started
          • Installation
          • SDK Initialization and Configuration
          • Start food detection
          • FoodDetectionEvent
        • RN SDK API
          • Properties
            • PersonalizedAlternative
            • FoodSearchResult
            • PassioNutrient
            • FoodDetectionEvent
            • DownloadModelCallBack
            • UPCProduct
            • ServingUnit
            • PassioStatus
            • PassioIDAttributes
            • PassioIDEntityType
            • PassioFoodItem
            • PassioRecipe
            • ServingSize
            • Measurement
            • UnitMass
            • NutritionFacts
        • Food Image
        • Search Food Item
        • Quick Scan
        • Multi Scan
        • MealPlan
        • Recipe
      • How do I Integrate a Passio SDK in EXPO?
    • Flutter SDK Docs
      • Getting Started
    • Before You Continue
    • Setup For Android
    • Initialize and configure the SDK
  • Fundamentals
    • Nutrition-AI Developer FAQ
      • Nutrition Data
      • Supported Phones
      • Security
      • Testing Volume Estimation
      • Testing Nutrition-AI SDK
      • Nutrition-AI Test Methodology
    • Nutrition API - Mobile SDK interoperability
      • JSON Response parsing
  • Versions
    • 3.2.4
      • SDK Key and minimum requirements
      • Installation
      • Configure the SDK
      • Use Cases
        • Food recognition
        • Nutrition data
        • Barcode scanning
        • Nutrition Facts scanning
        • Search, Food Icons, RefCode
        • Speech recognition
        • Nutrition Advisor
        • Suggestions and Meal Plans
        • User created foods and reports
    • 3.2.2
      • SDK Key and minimum requirements
      • Installation
      • Configure the SDK
      • Use Cases
        • Food recognition
        • Nutrition data
        • Barcode scanning
        • Nutrition Facts scanning
        • Search, Food Icons, RefCode
        • Speech recognition
        • Nutrition Advisor
        • Suggestions and Meal Plans
        • User created foods and reports
    • 3.2.0
      • SDK Key and minimum requirements
      • Installation
      • Configure the SDK
      • Use Cases
        • Food recognition
        • Nutrition data
        • Barcode scanning
        • Nutrition Facts scanning
        • Search, Food Icons, RefCode
        • Speech recognition
        • Nutrition Advisor
        • Suggestions and Meal Plans
    • 3.1.4
      • SDK Key and minimum requirements
      • Installation
      • Configure the SDK
      • Use Cases
        • Food recognition
        • Nutrition data
        • Barcode scanning
        • Search, Food Icons, RefCode
        • Speech recognition
        • Nutrition Advisor
        • Suggestions and Meal Plans
Powered by GitBook
On this page
  • Search
  • UI Example
  • Food Icons
  • RefCode
  • Using v2 PassioID in the v3 SDK
Export as PDF
  1. Versions
  2. 3.2.4
  3. Use Cases

Search, Food Icons, RefCode

Search

The Passio Nutrition AI SDK search functionality gives access to over 2.2 million food records in our nutritional database. The search api takes in a text query and returns a list of PassioFoodDataInfo results as well as a list of suggested searches.

There are two different search APIs available in the SDK:

  1. searchForFood - tries to give best string matches based on the input parameter, often providing the same food from different brands. Example: Input parameter "eggs" will provide results like "Trader Joe's eggs", "Eggland's Best eggs", "Eggs in carton, Lucerne", ...

  2. searchForFoodSemantic - will try to contextually match the most similar foods to the input parameter. Example: Iinput parameter "eggs" will provide results like "Cooked eggs", "Scrambled eggs", "Eggs benedict", ...

Both searchForFood and searchForFoodSemantic have the same input parameter and result structures.

public func searchForFood(byText: String, completion: @escaping (SearchResponse?) -> Void)

public struct PassioFoodDataInfo: Codable {
    public let brandName: String
    public let foodName: String
    public let iconID: PassioID
    public let labelId: String
    public let resultId: String
    public let score: Double
    public let scoredName: String
    public let type: String
    public let nutritionPreview: PassioSearchNutritionPreview?
    public let isShortName: Bool
}

public struct PassioSearchNutritionPreview: Codable {
    public var calories: Int
    public let carbs: Double
    public let fat: Double
    public let protein: Double
    public var servingUnit: String
    public var servingQuantity: Double
    public var weightUnit: String
    public var weightQuantity: Double
}
fun searchForFood(
    term: String,
    callback: (result: List<PassioFoodDataInfo>, searchOptions: List<String>) -> Unit
)

data class PassioFoodDataInfo(
    val foodName: String,
    val brandName: String,
    val iconID: PassioID,
    val score: Double,
    val scoredName: String,
    val labelId: String,
    val type: String,
    val resultId: String,
    val isShortName: Boolean,
    val nutritionPreview: PassioSearchNutritionPreview
)

data class PassioSearchNutritionPreview(
    val calories: Int,
    val carbs: Double,
    val protein: Double,
    val fat: Double,
    val servingUnit: String,
    val servingQuantity: Double,
    val weightUnit: String,
    val weightQuantity: Double
)
searchForFood(searchQuery: string): Promise<PassioSearchResult | null>

export interface PassioSearchResult {
  results: PassioFoodDataInfo[] | null
  alternatives?: string[] | null
}

export interface PassioFoodDataInfo {
  brandName?: string
  foodName: string
  iconID: PassioID | string
  labelId: string
  nutritionPreview?: PassioSearchNutritionPreview
  resultId: string
  score?: number
  scoredName?: string
  type?: string
  isShortName?: boolean
}

export interface PassioNutritionPreview {
  calories: number
  servingQuantity?: number
  servingUnit?: string
  weightQuantity: number
  weightUnit: string
  fat: number
  protein: number
  carbs: number
}
Future<PassioSearchResponse> searchForFood(String byText) {
    return NutritionAIPlatform.instance.searchForFood(byText);
}

class PassioSearchResponse {
  final List<PassioFoodDataInfo> results;
  final List<String> alternateNames;
}

class PassioFoodDataInfo {
  final String brandName;
  final String foodName;
  final PassioID iconID;
  final String labelId;
  final PassioSearchNutritionPreview nutritionPreview;
  final String resultId;
  final double score;
  final String scoredName;
  final String type;
  final bool useShortName;
}

class PassioSearchNutritionPreview {
  final int calories;
  final double carbs;
  final double fat;
  final double protein;
  final double servingQuantity;
  final String servingUnit;
  final double weightQuantity;
  final String weightUnit;
}

The PassioFoodDataInfo is used a reference object to fetch the full nutritional data. It has all of the attributes needed for displaying on a typical search screen: the name of the food, name of the brand (if possible), iconId, and a nutritional preview detailing the macro nutrients for a specified serving size and weight.

To fetch the PassioFoodItem using a search result, invoke the fetchFoodItemForDataInfo.

The search will return 50 items that best match the input term, as well as a list of suggested searches that are semantically or contextually close to the input term.

Example: searching for term "coffee"

  • search results: "Coffee, Brewed", "Coffee, Breakfast Blend", Coffee - Brewed From Grounds", "Coffee, Brewed, Decaffeinated", "Coffee, Instant, Reconstituted Decaffeinated", ...

  • suggested searches: "coffee with whole milk", "coffee with creamer", "iced coffee"

UI Example

  1. Create an input text field to collect the user query

  2. Create a horizontal list scroll to display the suggestions

  3. Create a vertical list to display the results of the search

  4. If the user clicks on a suggestion, pass that string to the search API and reload the UI with the new results

Food Icons

The SDK gives the ability to fetch food icons for a specific passioId. There are two functions that can be used: lookupIconsFor and fetchIconsFor.

  1. lookupIconsFor does a local search of the icons without doing any networking calls. It returns two icons. One is a placeholder icon depending on the type of food associated with the passioId. The second one is cached icon from a previous fetchIconsFor call, it it exists.

  2. fetchIconsFor does a networking call to fetch an icon associated with the passioId, but it will check the local cache and return a previously fetched icon.

If displaying a PassioFoodItem, PassioIngredient or a PassioFoodDataInfo icon, pass the iconId to the appropriate icon function.

Example of how to use both of these functions to first display the placeholder icon, and then fetch the remote icon:

public extension UIImageView {
    // for tableView Cell.

    func loadPassioIconBy(passioID: PassioID,
                          entityType: PassioIDEntityType,
                          size: IconSize = .px90,
                          completion: @escaping (PassioID, UIImage) -> Void) {
        let (placeHolderIcon, icon) = PassioNutritionAI.shared.lookupIconsFor(passioID: passioID,
                                                                     size: size,
                                                                     entityType: entityType)
        if let icon = icon {
            self.image = icon
        } else {
            self.image = placeHolderIcon
            PassioNutritionAI.shared.fetchIconFor(passioID: passioID) { image in
                if let image = image {
                    completion(passioID, image)
                }
            }
        }
    }
}

// call with your UIImageView
imageFoodIcon.loadPassioIconBy(passioID: passioID, entityType: .item) { id, image in
     DispatchQueue.main.async {
         self.imageFoodIcon.image = image
     }
}
fun ImageView.loadPassioIcon(
    passioID: PassioID,
    type: PassioIDEntityType = PassioIDEntityType.item,
    iconSize: IconSize = IconSize.PX90
) {
    this.tag = passioID
    val localImageResult = PassioSDK.instance.lookupIconsFor(context, passioID, iconSize, type)

    if (localImageResult.second != null) {
        setImageDrawable(localImageResult.second)
        return
    }

    setImageDrawable(localImageResult.first)

    PassioSDK.instance.fetchIconFor(context, passioID, iconSize) { drawable ->
        if (drawable != null && this.tag == passioID) {
            setImageDrawable(drawable)
        }
    }
}

A component for displaying food icons from the Passio SDK.

import {
  PassioIconView,
  type IconSize
} from '@passiolife/nutritionai-react-native-sdk-v3'
         <View
            style={{
              height: 24,
              width: 24,
              overflow: 'hidden',
              borderRadius: 12,
            }}
          >
            <PassioIconView
              style={{
                height: 24,
                width: 24,
              }}
              config={{
                passioID: item.passioID,
                iconSize: IconSize.PX180,
              }}
            />
       </View>
class PassioImageWidget extends StatefulWidget {
  const PassioImageWidget({
    required this.iconId,
    this.type = PassioIDEntityType.item,
    this.iconSize = IconSize.px90,
    this.radius = 30,
    this.heroTag,
    super.key,
  });

  final String iconId;
  final PassioIDEntityType type;
  final IconSize iconSize;
  final double radius;
  final Object? heroTag;

  @override
  State<PassioImageWidget> createState() => _PassioImageWidgetState();
}

class _PassioImageWidgetState extends State<PassioImageWidget> {
  final ValueNotifier<PlatformImage?> _image = ValueNotifier(null);

  @override
  void initState() {
    _fetchImage();
    super.initState();
  }

  @override
  void dispose() {
    _image.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return ValueListenableBuilder<PlatformImage?>(
      valueListenable: _image,
      builder: (context, value, child) => value != null
          ? Hero(
              tag: widget.heroTag ?? UniqueKey(),
              child: CircleAvatar(
                radius: widget.radius,
                backgroundImage: MemoryImage(value.pixels),
              ),
            )
          : const CircularProgressIndicator(),
    );
  }

  Future<void> _fetchImage() async {
    try {
      final result = await NutritionAI.instance.lookupIconsFor(
        widget.iconId,
        iconSize: widget.iconSize,
        type: widget.type,
      );

      setImage(result.cachedIcon ?? result.defaultIcon);
      if (result.cachedIcon != null) {
        return;
      }

      if (result.cachedIcon == null && widget.iconId.isNotEmpty) {
        final fetchedImage = await NutritionAI.instance.fetchIconFor(
          widget.iconId,
          iconSize: widget.iconSize,
        );
        if (fetchedImage != null) {
          setImage(fetchedImage);
        }
      }
    } catch (error) {
      // Handle potential errors during image fetching
      log("Error fetching image: $error");
    }
  }

  void setImage(PlatformImage? image) {
    if (mounted) {
      _image.value = image;
    }
  }
}

RefCode

There are several functions that are used to retrieve the PassioFoodItem object, depending on the origin of the data. If the food item is being scanned using an image, the food item is fetched using either fetchFoodItemForPassioID or fetchFoodItemForProductCode. If search is being used to access to food item, the appropriate call is the fetchFoodItemForDataInfo.

But if there is a use case that requires to save just one attribute to a database, that will later on be used to retrieve the full PassioFoodItem object, then the refCode attribute is the answer. The refCode in combination with the fetchFoodItemForRefCode will retrieve the original food item object from Passio's nutritional database.

PassioNutritionAI.shared.fetchFoodItemFor(passioID: "VEG0025") { (foodItem) in
        if let refCode = foodItem?.refCode {
            PassioNutritionAI.shared.fetchFoodItemFor(refCode: refCode) { refFoodItem in
            // foodItem == refFoodItem
        }
    }
}
PassioSDK.instance.fetchFoodItemForPassioID("VEG0025") { foodItem ->
    // foodItem is the original object from the database
    val refCode = foodItem!!.refCode
    // refCode is stored and used in another session
    PassioSDK.instance.fetchFoodItemForRefCode(refCode) { refFoodItem ->
        // foodItem == refFoodItem
    }
}
const foodItem = await PassioSDK.fetchFoodItemForPassioID('VEG0025')
// foodItem is the original object from the database
const refCode = foodItem?.refCode
// refCode is stored and used in another session
const refCodeFoodItem = await PassioSDK.fetchFoodItemForRefCode(refCode)
final foodItem = await NutritionAI.instance.fetchFoodItemForPassioID('VEG0025');
// foodItem is the original object from the database
final refCode = foodItem!.refCode;
// refCode is stored and used in another session
final refFoodItem = await NutritionAI.instance.fetchFoodItemForRefCode(refCode);
// foodItem == refFoodItem

refCode is a string hash of a complex object and can reach lengths above 180 characters.

Using v2 PassioID in the v3 SDK

If the implementing app is transitioning from generation 2 to generation 3 of the SDK, and has already stored generation 2 PassioIDs, invoking the fetchFoodItemLegacy will retrieve the PassioFoodItem that was previously structured as PassioIDAttributes.

PreviousNutrition Facts scanningNextSpeech recognition

Last updated 3 months ago