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
  • Include the Camera and Gallery usage keys
  • Ask User for Camera Permission
  • Take a Picture
  • Pick Picture from Gallery
  • Recognise the picture using SDK
  • Display the recognition results in the UI
Export as PDF
  1. Guides
  2. iOS SDK Docs
  3. Quick Start Guide

Recognise food using image

The Quick start project demonstrate recognising food items from an image, either by taking a photo using the camera or selecting an image from the gallery.

PreviousConfigure the SDK (UIKit)NextFood Details

Last updated 6 months ago

Include the Camera and Gallery usage keys

Include the and keys in your app’s Info.plist file. It tells the user why the app is requesting access to the device’s camera and photo library.

Ask User for Camera Permission

  • Once the Passio SDK status is isReadyForDetection, we can start capturing image or picking it from gallery. Implement following code for asking user for Camera permission. Once user grants the permission, we can configure the camera for capturing images.

import AVFoundation
func askForCapturePermission() {
    if AVCaptureDevice.authorizationStatus(for: .video) == .authorized {
        configureCamera()
    } else {
        AVCaptureDevice.requestAccess(for: .video) { granted in
            DispatchQueue.main.async {
                if granted {
                    self.configureCamera()
                } else {
                    self.statusLabel.text = "Please grant permission from Settings to use camera."
                }
            }
        }
    }
}

Take a Picture

  • Above the viewDidLoad method, where you create variables you want to be accessible anywhere in the ViewController file, create the following Instance Variables

var captureSession: AVCaptureSession!
var stillImageOutput: AVCapturePhotoOutput!
var videoPreviewLayer: AVCaptureVideoPreviewLayer!
  • Set up the Camera session and configure Input and Output

func configureCamera() {
    
    statusLabel.text = "Setting up camera..."
    captureSession = AVCaptureSession()
    captureSession.sessionPreset = .photo
    
    guard let backCamera = AVCaptureDevice.default(for: .video) else {
        statusLabel.text = "Unable to access back camera!"
        return
    }
    do {
        let input = try AVCaptureDeviceInput(device: backCamera)
        stillImageOutput = AVCapturePhotoOutput()
        
        if captureSession.canAddInput(input) &&
            captureSession.canAddOutput(stillImageOutput) {
            captureSession.addInput(input)
            captureSession.addOutput(stillImageOutput)
            setupLivePreview()
        }
    }
    catch let error {
        statusLabel.text = "Error Unable to initialize back camera:  \(error.localizedDescription)"
    }
}
  • Configure the Live Preview and start the Session on the background thread

func setupLivePreview() {
    
    statusView.isHidden = true
    
    videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
    videoPreviewLayer.videoGravity = .resizeAspectFill
    videoPreviewLayer.connection?.videoOrientation = .portrait
    self.captureView.layer.insertSublayer(videoPreviewLayer, at: 0)
    
    DispatchQueue.global(qos: .userInitiated).async { [weak self] in
        guard let self = self else { return }
        self.captureSession.startRunning()
        DispatchQueue.main.async {
            self.videoPreviewLayer.frame = self.captureView.bounds
        }
    }
}
  • On click of capture button, provide a setting and a deleget to deliver the capturedPhoto to. This delegate will be this ViewController so we also need to conform to the protocol AVCapturePhotoCaptureDelegate

@IBAction func captureButtonTapped(_ sender: UIButton) {
    captureImage()
}
func captureImage() {
    let settings = AVCapturePhotoSettings(format: [AVVideoCodecKey: AVVideoCode
    stillImageOutput.capturePhoto(with: settings, delegate: self)
}
  • The AVCapturePhotoOutput will deliver the captured photo to the assigned delegate which is our current ViewController by a delegate method

func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
    guard let imageData = photo.fileDataRepresentation() else { return }
    guard let image = UIImage(data: imageData) else { return }
    // Use this image
}

Pick Picture from Gallery

  • Ask for Photo Gallery permission:

PHPhotoLibrary.requestAuthorization() { status in
    DispatchQueue.main.async {
        if status == .authorized {
            self.presentImagePicker()
        } else {
            // Permission denied by user.
        }
    }
}
  • Present the PHPickerViewController with configuration

func presentImagePicker() {
    var configuration = PHPickerConfiguration()
    configuration.selectionLimit = 1 // or any number
    configuration.filter = .images
    
    let picker = PHPickerViewController(configuration: configuration)
    picker.isModalInPresentation = true
    picker.delegate = self
    
    DispatchQueue.main.async {
        self.present(picker, animated: true)
    }
}
  • Implement the delegate for getting user picked images

func picker(_ picker: PHPickerViewController, 
            didFinishPicking results: [PHPickerResult]) {
    
    picker.dismiss(animated: true) { [weak self] in
        
        if results.count < 1 { return }
        
        var selectedImages: [UIImage] = []
        let itemProviders = results.map(\.itemProvider)
        let dispatchGroup = DispatchGroup()
        
        for itemProvider in itemProviders {
            dispatchGroup.enter()
            if itemProvider.canLoadObject(ofClass: UIImage.self) {
                itemProvider.loadObject(ofClass: UIImage.self) { image , error  in
                    if let image = image as? UIImage {
                        selectedImages.append(image)
                        dispatchGroup.leave()
                    } else {
                        dispatchGroup.leave()
                    }
                }
            } else {
                dispatchGroup.leave()
            }
        }
        dispatchGroup.notify(queue: .main) { [weak self] in
            guard let self else { return }
            if selectedImages.count < 1 { return }
            // Use these images
        }
    }
}

Recognise the picture using SDK

The following function is responsible for sending a captured image to the Passio SDK for remote image recognition . It sends image to a remote server for recognition, and after receiving the response it updates the table view which will present a list of recognised food.

@IBOutlet weak var foodListTable: UITableView!
var foodInfo: [PassioAdvisorFoodInfo] = []
func fetchData() {
    // Pass the image we just picked from above steps
    guard let image = selectedImage else { return }
    updateLoader(show: true)
    PassioNutritionAI.shared.recognizeImageRemote(image: image) { passioAdvisorFoodInfo in
        DispatchQueue.main.async {
            self.updateLoader(show: false)
            self.didFetch(foods: passioAdvisorFoodInfo)
        }
    }
}
func didFetch(foods: [PassioAdvisorFoodInfo]) {
    if foods.count < 1 {
        // No food detected. Present the alert.
        return
    }
    foodInfo = foods
    foodListTable.reloadData()
}

Display the recognition results in the UI

For each food recognised, we can create a table view cell e.g. FoodListCell and pass the PassioAdvisorFoodInfo object

@IBOutlet weak var foodImageView: UIImageView!
@IBOutlet weak var foodNameLabel: UILabel!
@IBOutlet weak var foodDetailsLabel: UILabel!

func configure(food: PassioAdvisorFoodInfo) {
    
    if let foodInfo = food.foodDataInfo {
        
        foodImageView.loadIcon(id: foodInfo.iconID)
        foodNameLabel.text = foodInfo.foodName.capitalized
        
        if let nutritionPreview = foodInfo.nutritionPreview {
            let servingQuantity = nutritionPreview.servingQuantity.twoDigits
            foodDetailsLabel.text = "\(servingQuantity) \(nutritionPreview.servingUnit) | \(nutritionPreview.calories) cal"
        } else {
            foodDetailsLabel.text = ""
        }
    }
    
    else if let packagedFoodItem = food.packagedFoodItem {
        
        foodNameLabel.text = packagedFoodItem.name
        
        let servingQuantity = packagedFoodItem.amount.selectedQuantity.twoDigits
        let calories = packagedFoodItem.nutrientsReference().calories()?.value ?? 0
        foodDetailsLabel.text = "\(servingQuantity) \(packagedFoodItem.amount.selectedUnit) | \(calories.twoDigits) cal"
    }
    
    else {
        foodNameLabel.text = ""
        foodDetailsLabel.text = ""
    }
NSCameraUsageDescription
NSPhotoLibraryUsageDescription