Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disciples of RNG – University of Ottawa #6

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions ios/MapPing/Classes/Domain/Model/Part.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,17 @@
struct Part: Codable {
enum CodingKeys: String, CodingKey {
case name
case notes
case type
case address
case latitude = "lat"
case longitude = "lon"
}

// add all needed attributes
let name: String
let latitude: Float
let longitude: Float
let notes: String
let type: String
let address: String?
let latitude: Float?
let longitude: Float?
}
22 changes: 19 additions & 3 deletions ios/MapPing/Classes/Domain/Service/PartService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,28 @@
import Foundation

class PartService {

private let partsUrl = URL(string: "https://s3.amazonaws.com/shared.ws.mirego.com/competition/mapping.json")!

var partsObservable = Observable<[Part]>()

func refreshParts() {
partsObservable.notify(data: [])
// TODO 🙄

var request = URLRequest(url: partsUrl)
// retrieve data from URL and parse into the partsObservable observable
URLSession.shared.dataTask(with: request) { (data, response, error) in
if error != nil {
print(error!.localizedDescription)
}

guard let data = data else { return }
//Implement JSON decoding and parsing
do {
let partsData = try JSONDecoder().decode([Part].self, from: data)
self.partsObservable.notify(data: partsData)

} catch let jsonError {
print(jsonError)
}
}.resume()
}
}
92 changes: 88 additions & 4 deletions ios/MapPing/Classes/UI/List/ListViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,79 @@
//

import UIKit
import CoreLocation

class ListViewController: BaseViewController {
class ListViewController: BaseViewController, UITableViewDelegate, UITableViewDataSource, CLLocationManagerDelegate {

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.data.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: PartCellView = PartCellView()

var part = self.data[indexPath.row]

let partCellView = PartCellView()

private var mainView: ListView {
return self.view as! ListView
if let longitude = part.longitude {

var distance = "unkown"

if self.last_location != nil{

/***
This giant behemoth creates 2 CLLocation objects from the latitudes and longitudes, and then calcules the distance in m between them
them converts to km, then converts to a string format.
***/

distance = (NSString(format: "%.2f", CLLocation(latitude: CLLocationDegrees(part.latitude!), longitude: CLLocationDegrees(part.longitude!)).distance(from: CLLocation(latitude: (self.last_location?.latitude)!, longitude: (self.last_location?.longitude)!))/1000.0) as String) + " km"
}

// configure cell to have all the relevant information to properly display icon, text, distance, etc.
cell.configure(partImageName: "part-" + part.type, title: part.name, subTitle: part.notes, coordinates: (NSString(format: "%.2f", part.longitude!) as String) + "° N, " + (NSString(format: "%.2f", part.latitude!) as String) + "° W", distance: distance)
} else {

// use geo coder to get lat and lon from address when lat and lon not available

if let address = part.address{
let geoCoder = CLGeocoder()
geoCoder.geocodeAddressString(address) { (placemarks, error) in
guard
let placemarks = placemarks,
let location = placemarks.first?.location
else {
return
}

var distance = "unkown"

if self.last_location != nil{
distance = (NSString(format: "%.2f", CLLocation(latitude: CLLocationDegrees((self.last_location?.latitude)!), longitude: CLLocationDegrees((self.last_location?.longitude)!)).distance(from: CLLocation(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude))/1000.0) as String) + " km"
}

cell.configure(partImageName: "part-" + part.type, title: part.name, subTitle: part.notes, coordinates: (NSString(format: "%.2f", location.coordinate.longitude) as String) + "°, " + (NSString(format: "%.2f", location.coordinate.latitude) as String) + "°", distance: distance)

}
}
}

return cell

}


private var tableView: UITableView = UITableView()
private let partService: PartService
private var data = [Part]()
private var last_location: CLLocationCoordinate2D?
let locationManager = CLLocationManager()

init(partService: PartService) {
self.partService = partService
super.init(nibName: nil, bundle: nil)
title = "Map Ping"
self.data = [Part]()
navigationIcon = #imageLiteral(resourceName: "icn-list")
}

Expand All @@ -33,12 +93,36 @@ class ListViewController: BaseViewController {
override func loadView() {
view = ListView()
}

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let locValue: CLLocationCoordinate2D = manager.location?.coordinate else { return }
self.last_location = locValue
print(locValue)
}

override func viewDidLoad() {
super.viewDidLoad()

self.locationManager.requestAlwaysAuthorization()

// For use in foreground
self.locationManager.requestWhenInUseAuthorization()

if CLLocationManager.locationServicesEnabled() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.startUpdatingLocation()
}

self.tableView = UITableView(frame: UIScreen.main.bounds, style: UITableViewStyle.plain)
self.tableView.delegate = self
self.tableView.dataSource = self
self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
self.view.addSubview(self.tableView)

_ = partService.partsObservable.register { (_, parts) in
print("Nb of parts received: \(parts.count)")
self.data = parts
}

}
}
10 changes: 8 additions & 2 deletions ios/MapPing/Classes/UI/List/Subviews/PartCellView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@

import UIKit

class PartCellView: UIView {

// changed it to UITableViewCell to be able to have nice scrolling lists
class PartCellView: UITableViewCell {

private let partImage = UIImageView()
private let title = UILabel()
Expand All @@ -16,7 +18,7 @@ class PartCellView: UIView {
private let distance = UILabel()

init() {
super.init(frame: .zero)
super.init(style: UITableViewCellStyle.default, reuseIdentifier: "cell")

partImage.backgroundColor = .white
partImage.contentMode = .center
Expand All @@ -38,7 +40,11 @@ class PartCellView: UIView {
distance.setProperties(font: .italicSystemFont(ofSize: 12), textColor: .brownishGrey)
addSubview(distance)

// make sure cells have a set height

height = 100

heightAnchor.constraint(equalToConstant: height).isActive = true
}

required init(coder aDecoder: NSCoder) {
Expand Down
4 changes: 4 additions & 0 deletions ios/MapPing/SupportingFiles/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSLocationWhenInUseUsageDescription</key>
<string>MapPing wants to use your location.</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>MapPing wants to use your location.</string>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
Expand Down