Giter Club home page Giter Club logo

weather-app's Introduction

☔️ Weather App

11.08.2021 ~ 16.08.2021

Design Pattern

design-pattern

Interactor — contains business logic related to the data (Entities) or networking, like creating new instances of entities or fetching them from the server. For those purposes you’ll use some Services and Managers which are not considered as a part of VIPER module but rather an external dependency.

Presenter — contains the UI related (but UIKit independent) business logic, invokes methods on the Interactor.

Entities — your plain data objects, not the data access layer, because that is a responsibility of the Interactor.

Router — responsible for the segues between the VIPER modules.

In this project, I used view models to tranform lots of data from the model and inject information to the view directly.

The VIPER architecture is based on the single responsibility principle (S.O.L.I.D.) which leads us to the theory of a clean architecture.

Using this architecture one can easily test at the boundaries between each layers. One feature, one module. For each module VIPER has five (sometimes six) different classes with distinct roles. VIPER makes the code easier to isolate dependencies and to test the interactions at the boundaries between layers.

Structure

2

10

3

4

5

6

7

8

API

5 day weather forecast documentation

Weather conditions documentation

API Example

Consideration

For the SOLID Principle(Dependency Inversion Principle), Should I write the code like below?

protocol NetworkRequest: AnyObject {
    associatedtype ModelType
    func decode(_ data: Data) -> ModelType?
    func load(withCompletion completion: @escaping (ModelType?) -> Void)
}

extension NetworkRequest {
    fileprivate func load(_ url: URL, withCompletion completion: @escaping (ModelType?) -> Void) {
        let session = URLSession(configuration: .default, delegate: nil, delegateQueue: .main)
        let task = session.dataTask(with: url, completionHandler: { [weak self] (data: Data?, response: URLResponse?, error: Error?) -> Void in
            guard error == nil else {
                return completion(nil)
            }
            
            guard let header = response as? HTTPURLResponse, (200..<300) ~= header.statusCode else {
                return completion(nil)
            }
            
            guard let data = data else {
                return completion(nil)
            }
            
            completion(self?.decode(data))
        })
        task.resume()
    }
}

protocol APIResource {
    associatedtype ModelType: Decodable
    var latitude: String { get }
    var longitude: String { get }
}

extension APIResource {
    var url: URL {
        
        let baseURL = "https://api.openweathermap.org/data/2.5/forecast"
        let API_KEY = ""
        
        var urlComponent = URLComponents(string: baseURL)
        
        urlComponent?.queryItems = [
            URLQueryItem(name: "APPID", value: "\(API_KEY)"),
            URLQueryItem(name: "lat", value: "\(latitude)"),
            URLQueryItem(name: "lon", value: "\(longitude)"),
            URLQueryItem(name: "units", value: "metric")
        ]
        
        return (urlComponent?.url)!
    }
}

struct WeatherResource: APIResource {
    typealias ModelType = WeatherResponse
    
    let longitude: String
    let latitude: String
}


class APIRequest<Resource: APIResource> {
    let resource: Resource
    
    init(resource: Resource) {
        self.resource = resource
    }
}

extension APIRequest: NetworkRequest {
    func decode(_ data: Data) -> (Resource.ModelType)? {
        do {
            let result = try JSONDecoder().decode(WeatherResponse.self, from: data)
            return result as? Resource.ModelType
        } catch {
            return nil
        }
    }
    
    func load(withCompletion completion: @escaping (Resource.ModelType?) -> Void) {
        load(resource.url, withCompletion: completion)
    }
}

Git Commit Message Guide

  • feat: A new feature
  • fix: A bug fix
  • docs: Changes to documentation
  • style: Formatting, missing semi colons, etc; no code change
  • refactor: Refactoring production code
  • test: Adding tests, refactoring test; no production code change
  • chore: Updating build tasks, package manager configs, etc; no production code change

Third-Party Libraries

After Code Review

  1. Indiscriminate use of Singleton is not good.
  2. If I use local data, it is better to use it actively than to try to reduce its use.
  3. I should also consider the possibility that data may be different in the process of saving it to local data. Therefore, if there is information to be brought from local data, it is better to bring all the information that way.
  4. It is more effective to use observer than to use viewWillAppear.
  5. If I think I don't need to use lazy var, I don't need to use it.
  6. I need to think more about the effective method to implement something.

weather-app's People

Contributors

iosdevted avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 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.