Skip to main content

Overview

Breeze requires certain permissions to provide location-based air quality data. All permissions are requested only when needed and include clear explanations for users.

Required Permissions

Location Permission

Breeze requests “When In Use” location access to show air quality data for your current location.

Privacy Description

The location permission description is defined in Info.plist:
Info.plist:51-52
<key>NSLocationWhenInUseUsageDescription</key>
<string>Breeze needs your location to show air quality data for your area.</string>
This message appears in the iOS permission dialog when users tap “Use My Location.”
Location permission is optional. Users can always search for cities manually without granting location access.

How Permissions Are Requested

Location Permission Flow

The app requests location permission when users tap the “Use My Location” button:
DashboardViewModel.swift:52-68
/// Request user's current location
func requestLocation() {
    isLoading = true
    errorMessage = nil
    
    switch locationManager.authorizationStatus {
    case .notDetermined:
        locationManager.requestWhenInUseAuthorization()
    case .authorizedWhenInUse, .authorizedAlways:
        locationManager.requestLocation()
    case .denied, .restricted:
        errorMessage = "Location access denied. Please enable in Settings."
        isLoading = false
    @unknown default:
        errorMessage = "Unknown location authorization status."
        isLoading = false
    }
}

Authorization Status Handling

The app responds to authorization changes:
DashboardViewModel.swift:215-225
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
    switch manager.authorizationStatus {
    case .authorizedWhenInUse, .authorizedAlways:
        manager.requestLocation()
    case .denied, .restricted:
        errorMessage = "Location access denied."
        isLoading = false
    default:
        break
    }
}
The app automatically requests location data once permission is granted, providing a seamless user experience.

Permission States

Initial state when the app hasn’t requested permission yet.
  • App shows the iOS permission dialog when requestLocation() is called
  • User can choose “Allow While Using App” or “Don’t Allow”

Location Manager Setup

The DashboardViewModel initializes and manages the location manager:
DashboardViewModel.swift:44-47
override init() {
    super.init()
    locationManager.delegate = self
}

CLLocationManagerDelegate

The view model implements location delegate methods:
DashboardViewModel.swift:181-208
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    guard let location = locations.first else { return }
    
    locationName = "Your Location"
    
    // Reverse geocode to get city name
    CLGeocoder().reverseGeocodeLocation(location) { [weak self] placemarks, _ in
        if let placemark = placemarks?.first {
            var components: [String] = []
            if let city = placemark.locality {
                components.append(city)
            }
            if let country = placemark.country {
                components.append(country)
            }
            if !components.isEmpty {
                self?.locationName = components.joined(separator: ", ")
            }
        }
    }
    
    Task {
        await fetchAllData(
            latitude: location.coordinate.latitude,
            longitude: location.coordinate.longitude
        )
    }
}
The app uses reverse geocoding to display a friendly location name (e.g., “San Francisco, United States”) instead of raw coordinates.

User Experience

Permission Dialog

When users tap “Use My Location” for the first time:
  1. iOS shows the standard permission dialog
  2. Dialog includes the custom message from NSLocationWhenInUseUsageDescription
  3. User chooses “Allow While Using App” or “Don’t Allow”

Error Handling

If permission is denied or location fails:
DashboardViewModel.swift:210-213
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
    errorMessage = "Unable to get your location."
    isLoading = false
}
The error message appears in the UI, and users can try again or search for a city manually.

Privacy Considerations

App Transport Security

Breeze enforces secure network connections:
Info.plist:53-57
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <false/>
</dict>
All API requests use HTTPS. HTTP connections are blocked by default for security.

Encryption Declaration

For App Store submission:
Info.plist:58-59
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
Breeze uses standard iOS encryption and doesn’t implement custom cryptography, so this is set to false.

App Store Requirements

When submitting to the App Store, ensure:
1

Privacy manifest

Declare all data collection in the privacy manifest (if using Xcode 15+).
2

Permission descriptions

All NSLocationWhenInUseUsageDescription strings are clear and explain why permission is needed.
3

Data usage disclosure

Update App Store Connect with data usage details (location data for air quality).
4

Privacy policy

Provide a privacy policy URL if collecting or transmitting user data.

Testing Permissions

Simulator Testing

In the iOS Simulator, when the permission dialog appears, click Allow While Using App.
Click Don’t Allow in the permission dialog. The app should handle this gracefully with an error message.
  • Go to Settings → Privacy & Security → Location Services
  • Find Breeze and change the setting
  • Or reset all permissions: Simulator → Reset Content and Settings
In Xcode, go to Debug → Simulate Location and choose a city (e.g., San Francisco, London).

Device Testing

On a physical device:
  1. Install the app via Xcode
  2. Tap “Use My Location”
  3. Grant permission when prompted
  4. Verify that the app receives real location updates
Test both indoor and outdoor scenarios, as GPS accuracy varies by environment.

Troubleshooting

  • Ensure NSLocationWhenInUseUsageDescription is in Info.plist
  • Check that you’re calling requestWhenInUseAuthorization() correctly
  • Reset simulator permissions if testing on simulator
  • Check device/simulator Settings → Privacy → Location Services is ON
  • Verify the app has location permission in Settings → Breeze → Location
  • On device, check if parental controls are restricting location access
The error message persists until the user takes action. Guide users to:
  1. Open Settings
  2. Scroll to Breeze
  3. Tap Location
  4. Select While Using the App

Next Steps

Dashboard View

Learn how the dashboard uses location data

Location Services

Deep dive into location features

Build docs developers (and LLMs) love