Giter VIP home page Giter VIP logo

airquality-c's Introduction

AirQuality-ObjC

Project Summary

Students will build an app that allows them to filter countries, states in those countries, and cities in those states and get the current air quality of that city. Network calls will be made using JSONSerialization in Objective C.

Setup

If you havent already fork and clone this repository and work from the starter branch.

AirVisual provides weather and polution data for given locations around the globe. The documentation can be found here.

  • Create an account and confirm your email address to recieve your API key.
  • The documentation has a downloadable Postman link in the upper right hand corner that autofills all available calls in Postman.
  • Plug in the base url (https://api.airvisual.com/) and your API key into the Postman requests to look at the data returned.

Step One

Create the needed models for the get specified city data request that we will be using to pull information on specific cities.

Instructions

CityAirQuality Model Declarations

  • Create the CityAirQuality.h/.m files

  • Review the endpoint in the docuementation and see what JSON (information) you will get back.

    • Using this information, add the properties to the CityAirQuality.h file.
      Properties
    • @property (nonatomic, copy, readonly) NSString * city;
    • @property (nonatomic, copy, readonly) NSString * state;
    • @property (nonatomic, copy, readonly) NSString * country;
    • You'll notice that the end point has two more levels of dicitonaries: weather and pollution. We will create two more models to handle these endpoints. For now, add them as properties to the CityAirQuality.h file.
      Properties
    • @property (nonatomic, copy, readonly) DVMWeather * weather;
    • @property (nonatomic, copy, readonly) DVMPollution * pollution;
  • Add the designated initializer declaration for this Model object

    Designated Initializer -(instancetype)initWithCity:(NSString *)city state:(NSString *)state country:(NSString *)country weather:(DVMWeather *)weather pollution:(DVMPollution *)pollution;
  • Add the convenience initializer in an extension called JSONConvertable

    Designated Initializer -(instancetype)initWithDictionary:(NSDictionary *)dictionary;

Weather Model Declaration

  • Create the Weather.h/.m files

  • Review the endpoint for the weather level of the JSON object and add the appropriate properties to the .h file

    Properties
  • @property (nonatomic, readonly) NSInteger temperature;
  • @property (nonatomic, readonly) NSInteger humidity;
  • @property (nonatomic, readonly) NSInteger windSpeed;
  • Add the designated initializer declaration for this Model object

    Designated Initializer -(instancetype)initWithWeatherInfo:(NSInteger)temperature humidity:(NSInteger)humidity windSpeed:(NSInteger)windSpeed;
  • Add the convenience initializer in an extension called JSONConvertable

    Designated Initializer -(instancetype)initWithDictionary:(NSDictionary *)dictionary;

Pollution Model Declaration

  • Create the Pollution.h/.m files

  • Review the endpoint for the pollution level of the JSON object and add the appropriate properties to the .h file

    • The only thing we really care about here is the AQI, add @property (nonatomic, readonly) NSInteger airQualityIndex; as the only property
  • Add the designated initializer declaration for this Model object

    Designated Initializer -(instancetype)initWithInt:(NSInteger) aqi;
  • Add the convenience initializer in an extension called JSONConvertable

    Designated Initializer -(instancetype)initWithDictionary:(NSDictionary *)dictionary;

Step Two

Implement the initializers for the created models.

Instructions

Pollution Model Implementation

  • Implement the declared initializers in the Pollution.m file.
    • The designated initializer will live in the implementation body
    • The JSONConvertable convenience initializer will live in an extension

Weather Model Implementation

  • Implement the declared initializers in in the Weather.m file.
    • The designated initializer will live in the implementation body
    • The JSONConvertable convenience initializer will live in an extension

CityAirQuality Model Implementation

  • Implement the declared initializers in in the CityAirQuality.m file.
    • The designated initializer will live in the implementation body
    • The JSONConvertable convenience initializer will live in an extension

ModelControllers

Create the CityAirQualityController.h/.m files

Step Three

Create and implement the api calls needed to pull air quality data for a city.

Instructions

CityAirQualityController.h

On this file we will declare the various network call methods we will be using.

  • Add fetchSupportedCountries, fetchSupportedStatesInCountry, fetchSupportedCitiesInState, and fetchDataForCity to the .h file
    • fetchSupportedCountries will take in no parameters and complete with an array of strings
    • fetchSupportedStatesInCountry will take in a string parameter for the country and complete with an array of strings
    • fetchSupportedCitiesInState will take in a string parameter for the country, a string parameter for the state, and complete with an array of strings
    • fetchDataForCity will take in a string parameter for the country, a string parameter for the state, a string parameter for the city, and complete with a CityAirQuality object

CityAirQualityController.m

We have four network call methods to implement. To make our lives easier when implementing them, we will use string constants to store the frequently used string values for the API calls.

  • Above the class declaration, add string constants for the following:
    • baseUrlString with value "https://api.airvisual.com/"
    • versionComponent with value "v2"
    • countryComponent with value "countries"
    • stateComponent with value "states"
    • cityComponent with value "cities"
    • cityDetailsComponent with value "city"
    • apiKey with your key as the value

Implement the function bodies inside the class declaration.

  • fetchSupportedCountries method body
    • Start with defining a url from the baseUrlString
    • Append the versionComponent string as a pathComponent
    • Append the countryComponent string as a pathComponent
    • Add your apiKey as a queryItem with the key of "key"
    • With your finalURL constructed, perform a shared URLSession dataTaskWithURL and completion
      • handle your error
      • print out your response
      • unwrap your data
        • Create a topLevel dicitonary from serializing the JSON from the unwrapped data
        • Step into your data dictioary from the topLevel dictionary
        • Loop through the data dictionary and create an array of strings from the names of the countries found
        • Complete with the array of strings
  • fetchSupportedStatesInCountry method body
    • Follow the same flow as the fetchSupportedCountries method
    • Change the countryComponent for the stateComponent
    • Add a queryItem for the country, use the string value for the country parameter as the value and "country" as the key
    • Perform your dataTask with the finalURL and complete with the array of strings found for the states
  • fetchSupportedCitiesInState method body
    • Follow the same flow as the fetchSupportedCitiesInState method
    • Change the stateComponent for the cityComponent
    • Add a queryItem for the country, use the string value for the country parameter as the value and "country" as the key
    • Add a queryItem for the state, use the string value for the state parameter as the value and "state" as the key
    • Perform your dataTask with the finalURL and complete with the array of strings found for the cities
  • fetchDataForCity method body
    • Follow the same flow as the fetchSupportedCitiesInState method
    • Change the cityComponent for the cityDetailsComponent
    • Add a queryItem for the country, use the string value for the country parameter as the value and "country" as the key
    • Add a queryItem for the state, use the string value for the state parameter as the value and "state" as the key
    • Add a queryItem for the city, user the string value for the city parameter as the value and "city" as the key
    • Perform your dataTask with the finalURL and complete with the CityAirQuality object found

Step Four

Instructions

Bridging Header

  • Create a new CocoaTouch Class file named CountriesListViewController subclassed from a UIViewController, change the language to Swift, and add a `Bridging-Header
  • In the Bridging-Header import all of the .h files.

Storyboards

Looking at our network call methods, we have three methods that return an array of results that build off of one another. We'll display the results of our network calls in tableViews with basic cells.

  • Navigate to Main.storyboard. Delete the existing ViewController, drag out a new ViewController, set it as your initial ViewController, and embed it in a NavigationController
  • Drag a tableView onto the ViewController and constrain it to all zeros along the top, bottom, leading, and trailing
  • Add a prototype cell to the tableView and make it a basic cell, give it a reuseIdentifier "countryCell"
  • Subclass the ViewController as CountriesListViewController
  • Drag out another ViewController, add a tableView with a basic prototype cell and constrain it
  • From the CountriesListViewController, drag a show segue from the tableViewCell to the new ViewController
    • Give the segue a reuseIdentifier "toStatesVC"
    • Create a new CocoaTouch Class file named StatesListViewController subclassed from UIViewController, and subclass the storyboard ViewController.
  • Repeat the above process for the CitiesListViewController
  • Lastly, add a ViewController with labels to display the selected city's name, state, country, airQualityIndex, temperature, humidity, and windspeed.

CountriesListViewController

We will implement the code needed to display the Supported Countries.

  • Start by opening the assistant editor and dragging out an outlet for the tableView called tableView
  • Extend the class and conform to UITableViewDelegate and UITableViewDataSource and plug in the stubs.

We will need an array of countries to finish the the tableView data source methods.

  • Create a local variable called countries that is an empty array of String
  • Using that array, finish writing the dataSource methods for the tableView
  • In viewDidLoad assign the tableView.delegate and tableView.dataSource to self
  • Call the fetchSupportedCountries method in viewDidLoad, assign the self.countries property to the array of strings returned in the completion block

Since the network call is handled asychronosly, we will need to refresh the tableView when the call is complete. We will do this with a property observer.

  • At the bottom of the class, write a method called updateTableView
    • In the body of the function, call self.tableView.reloadData() on the main thread
  • On the countries property, implement a didSet and call the updateTableView method

We will need to pass the selected country string along to the next ViewController to perform the fetchSupportedStatesInCountry network call

  • In prepare(for segue:), check your segue identifier, unwrap the indexPath and destination, and define a property for the selected index `let selectedCountry = countries[indexPath.row]
  • On the StatesListViewController, declare an option property for the country to recieve the data passed through the segue
  • Back on CountriesListViewController, assign the destinationVC's country property to the selectedCountry property

StatesListViewController

Repeat the process you just finished above for this ViewController. The only changes will be the name of the dataSource array, and you'll call the fetchSupportedCitiesInState method to populate your tableView. Additionally, you will need to pass the values for both the country property and the selected state through prepare(for segue:)

CitiesListViewController

Now, you'll repeate the proccess again for the supported cities. You will need to pass values for the country, state, and selected city to the CityDetailViewController to perform the fetchDataForCity method.

CityDetailsViewController

In viewDidLoad, call the fetchDataForCity method and assign the lables with the string values in the completion block. You should have lables to show the city name, state, country, airQualityIndex, temperature, humidity, and windspeed.

Black Diamonds

  • Implement a UISearchController to search through the countries, states, and cities on their viewControllers
    • Think about how you might be able to cut down on reused code the most using an extension and generics.
  • Instead of using UITableViewDelegate and UITableViewDataSource, use UITableViewDiffableDataSource
  • Switch from a tableView to a collectionView to display the results of the network calls.

airquality-c's People

Contributors

nateandrus avatar ryangreenburg avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.