contirobert / Weather-SwiftUI

A weather app that uses the Dark Sky API built using SwiftUI! Get the current weather for a particular location and check out the 5-day forecast!
113 stars 17 forks source link

Feature: User-Specified Location #1

Open contirobert opened 5 years ago

contirobert commented 5 years ago

Add a custom feature that allows the user to specify the location (by zip code). If the user does not specify a location, the default should remain New York City.

mwcs01 commented 5 years ago

I built in using core location to your project with the following.

LocationViewModel.swift

import Foundation

struct LocationViewModel {
    var mylatitude: Double?
    var mylongitude: Double?
    var myLocation: String?

    init() {
        self.mylatitude = 43.2012
        self.mylongitude = -88.1087
        self.myLocation = "Germantown"
    }

    init(model: CurrentLocaiton) {
        self.mylatitude = model.mylatitude
        self.myLocation = model.myLocation
        self.mylongitude = model.mylongitude
    }
}

CurrentLocaiton.swift

import Foundation

struct CurrentLocaiton {
    var mylatitude: Double?
    var mylongitude: Double?
    var myLocation: String?

    init() {
        self.mylatitude = 43.2012
        self.mylongitude = -88.1087
        self.myLocation = "Germantown"
    }
}

LocationService.swift

import CoreLocation
import Combine

class LocationService: NSObject {
    var didChange = PassthroughSubject<LocationService, Never>()
    var locationModel = LocationViewModel()
    var newestLocatoin: ((CLLocationCoordinate2D?) -> Void)?
    var statusUpdated: ((CLAuthorizationStatus) -> Void)?
    var lat: Double?
    var long: Double?
    let manager: CLLocationManager

    var status: CLAuthorizationStatus {
        return CLLocationManager.authorizationStatus()
    }

    init(manager: CLLocationManager = CLLocationManager()) {
        self.manager = manager
        super.init()
        manager.delegate = self
    }

    func getPermission() {
        manager.requestWhenInUseAuthorization()
    }

    func getLocation() {
        manager.requestLocation()
    }
}

extension LocationService: CLLocationManagerDelegate {
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        if let location = locations.sorted(by: {$0.timestamp > $1.timestamp} ).first {
            self.newestLocatoin?(location.coordinate)
            locationModel.mylatitude = location.coordinate.latitude
            locationModel.mylongitude = location.coordinate.longitude
            let geoCoder = CLGeocoder()
            geoCoder.reverseGeocodeLocation(location, completionHandler: {
                (placemarks, error) -> Void in
                let placeArray = placemarks as [CLPlacemark]?
                var placeMark: CLPlacemark!
                placeMark = placeArray?[0]
                print(placeMark.locality!)
                self.locationModel.myLocation = placeMark.locality
            })

        } else {
            self.newestLocatoin?(nil)
        }
    }

    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        print("Failed to get ther user location: \(error.localizedDescription)")
    }

    func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
        print("Location status: \(status)")
        self.statusUpdated?(status)
    }
}

In Coordinate.swift changed static var newYorkCity: Coordinate {

    static var newYorkCity: Coordinate {
        let locationModel = LocationViewModel()
        if locationModel.mylatitude != nil {
            return Coordinate(latitude: locationModel.mylatitude!, longitude: locationModel.mylongitude!)
        } else  {
            return Coordinate(latitude: 43.2012, longitude: -88.1087)
        }
    }

Network Manager Added

    var currentLocation = LocationViewModel() {
        didSet {
            didChange.send(self)
        }
    }

HeaderView Added

let locationModel = LocationViewModel()
And changed 

Text("(locationModel.myLocation ?? "None")").font(.title).fontWeight(.light).color(.black)

In AppDelgate made the following changes

 let locationService = LocationService()

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        // Location service callbacks
        locationService.newestLocatoin = { [weak self] coordinate in
            guard let _ = self, let coordinate = coordinate else { return }
            print("Location is: \(coordinate)")
        }

        switch locationService.status {
        case .notDetermined:
            locationService.getPermission()
        case .authorizedWhenInUse:
            locationService.getLocation()
        default:
            assertionFailure("Location is: \(locationService.status)")
        }
        return true
    }

Hope this is helpful. The project is looking good and a great place for others to start with learning SwiftUI.

contirobert commented 4 years ago

@mwcs01 this is great! Did you want to submit a pull request?

mwcs01 commented 4 years ago

I have found an issue that I am trying to fix first.

Semsemq commented 1 year ago

help me please i'm new in delovper this first project