Skip to content

Conversation

@amandakpaiva
Copy link

Description

Implement the Busbud mobile app coding challenge, forked from coding-challenge-native-b.

This is a native MVVM iOS application that utilizes Busbud's API to display a list of nearby cities.
This app is localized in English and Brazilian Portuguese (pt-BR) using Localizable.strings files.

Motivation and Context

This implementation fulfills the requirements of the Busbud coding challenge by:

  • Developing a mobile app with native iOS technology.
  • Displaying relevant city information fetched dynamically using Busbud's API.
  • Applying best practices in architecture and coding standards.

This project showcases skills in API integration, iOS development, and clean code practices.

Changes Included

  1. Core Feature Implementation:

    • City.swift: Created the City model to represent location data, including properties for name, latitude, longitude, and distance.
    • CityService.swift: Developed a service for fetching city data and calculating distances between cities and the user's location.
    • CityViewModel.swift: Added logic to manage data fetching, filtering, and presenting nearby cities in the view.
  2. User Interface:

    • NearbyCitiesView.swift: Displays a list of nearby cities using CityViewModel and handles user interactions.
    • CityDetailsView.swift: Displays detailed information about a selected city.

Error Scenarios

The app handles different error scenarios, represented by the ViewState enumeration. Each state is responsible for displaying specific messages to the user depending on the conditions.

1. permissionDenied

  • Scenario: The user has denied or restricted location permissions.
  • How it happens: This state is triggered when the app does not have permission to access the user's location, which may occur if the user denies the permissions or if location restrictions are set on the device.
  • What is displayed: A message informing that the app does not have permission to access the location.

2. obtainingLocation

  • Scenario: The app is waiting for the user's location.
  • How it happens: This state is initially set when the CityViewModel is instantiated and the locationManager starts fetching the user's location. During this time, the app is trying to obtain the location to proceed with fetching nearby cities.
  • What is displayed: The app may display a loading animation or a state indicating that the location is being fetched.

3. cities

  • Scenario: Cities were successfully loaded.
  • How it happens: This state is triggered when the app successfully retrieves nearby cities and displays them to the user.
  • What is displayed: A list of nearby cities is displayed on the screen.

4. error(String)

  • Scenario: Error fetching cities or obtaining location.
  • How it happens: This state is used in three cases:
    1. If the user's location is not available (e.g., if GPS is turned off or the location cannot be determined).
    2. If no cities are found nearby.
    3. If an error occurs while trying to fetch the cities (e.g., network failure, API error).
  • What is displayed: A detailed error message is displayed to the user depending on the scenario. The error could be:
    • "Location is not available"
    • "No cities found nearby"
    • "Failed to fetch cities"

Error Handling Details

  • Error when location is not available: If the user's location is not available, the viewState is changed to .error with the message "Location is not available".
  • Error when fetching cities: If the city fetch fails, the viewState is changed to .error with the message "Failed to fetch cities".
  • Error when no nearby cities are found: If the API response does not contain any cities, the viewState is changed to .error with the message "No cities found nearby".
  • Failure in CLLocationManager: If the CLLocationManager fails to obtain the location, the viewState is changed to .error.
  1. Utilities and Extensions:

    • CLLocation+Extensions.swift: Extended CLLocation with utility methods for calculating distances.
    • Double+Extensions.swift: Added formatting utilities for displaying distance values.
  2. App Configuration:

    • BusBudiOSChallengeApp.swift: Integrated the Nearby Cities feature into the app's navigation structure.
    • Localization:
      • Added Localizable.strings files to support English (en) and Portuguese (pt-BR) translations.
    • Dark Mode Support: The app supports both Light and Dark Mode, adapting the UI to the user's system preferences.
    • Location Permission: The app requests location permission from the user to fetch nearby cities based on their current location.
  3. Unit Test:

    • CityServiceTests.swift: Verified the correctness of city data fetching and distance calculations.
    • CityViewModelTests.swift: Tested the view model logic for handling and presenting city data.
    • DistanceCalculateTests.swift: Ensured accurate distance calculations using utility extensions.
  4. Project Configuration:

    • Updated project files (.pbxproj, .xcworkspace) to reflect new files and dependencies.

Testing and Verification

  • Unit tests written with XCTest achieve high coverage for services, view models, and utilities.
  • Verified feature functionality in the iOS Simulator, ensuring proper display of nearby cities, localization, Dark Mode support, and navigation to city details.

How Has This Been Tested?

  • Unit tests were added to validate the CityViewModel and DistanceCalculate components.
  • Configurations were made to include the target Xcode scheme in the pbxproj file.
  • The app was tested in a simulated environment to ensure UI functionality, localization, Dark Mode, location permission request, and API integration.

This project was developed with:

  • Xcode version: Version 15.0
  • iOS version: 17.0

Screenshots:

Instructions to Clone and Run the Project

Prerequisites

Ensure that you have the following tools installed on your machine:

  • Xcode (latest version recommended)
  • Git

Cloning the Repository

  1. Open your terminal.

  2. Navigate to the directory where you want to clone the repository.

  3. Run the following command:

    git clone https://github.com/amandakpaiva/coding-challenge-native-b.git

amandakpaiva and others added 8 commits December 18, 2024 20:05
### Commit Description

**feat: Add Nearby Cities feature with models, views, and tests**  

- Implemented `City` model to represent location data.  
- Added `CityViewModel` for managing nearby cities logic and user interactions.  
- Created `NearbyCitiesView` to display a list of nearby cities.  
- Developed `CityDetailsView` to show detailed information about a selected city.  
- Integrated `CityService` for fetching and calculating nearby city data using location-based services.  
- Added utility extensions for `CLLocation` and `Double` to support distance calculations and formatting.  
- Updated `BusBudiOSChallengeApp` to integrate the new feature into the app's navigation.  
- Configured assets (`AppIcon`, `AccentColor`) and updated `Info.plist` for feature support.  
- Wrote unit tests for `CityService`, `CityViewModel`, and distance calculation logic.  
- Updated project configuration files (`project.pbxproj`, `.xcworkspace`) for the new additions.
@amandakpaiva amandakpaiva changed the title Implemet Implement the Busbud mobile app coding challenge - iOS feat - Busbud mobile app coding challenge - iOS - Amanda Paiva Dec 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant