319 lines
12 KiB
Swift
319 lines
12 KiB
Swift
//
|
|
// MapViewViewController.swift
|
|
// pocloud
|
|
//
|
|
// Created by Patrick McDonagh on 5/22/18.
|
|
// Copyright © 2018 patrickjmcd. All rights reserved.
|
|
//
|
|
|
|
import UIKit
|
|
import Alamofire
|
|
import SwiftyJSON
|
|
import SVProgressHUD
|
|
import MapKit
|
|
import PromiseKit
|
|
import RealmSwift
|
|
|
|
class MapViewController: UIViewController, MKMapViewDelegate {
|
|
|
|
let baseURL = (UIApplication.shared.delegate as! AppDelegate).baseURL
|
|
let realm = try! Realm()
|
|
|
|
let locationManager = CLLocationManager()
|
|
|
|
|
|
|
|
var user : User?
|
|
var addresses : Results<Address>?
|
|
var gateways : Results<Gateway>?
|
|
var devices : Results<Device>?
|
|
var deviceTypes : Results<DeviceType>?
|
|
|
|
var selectedGateway : Gateway?
|
|
|
|
@IBOutlet weak var mapView: MKMapView!
|
|
|
|
override func viewDidLoad() {
|
|
super.viewDidLoad()
|
|
// Do any additional setup after loading the view.
|
|
|
|
mapView.delegate = self
|
|
checkLocationAuthorizationStatus()
|
|
SVProgressHUD.show()
|
|
loadData()
|
|
firstly {
|
|
getDeviceTypes()
|
|
}.then { _ in
|
|
self.getAddresses()
|
|
}.then { _ in
|
|
self.getGateways()
|
|
}.then { _ in
|
|
self.getDevices()
|
|
}.done { _ in
|
|
self.showMarkersOnMap()
|
|
SVProgressHUD.dismiss()
|
|
}.catch { error in
|
|
print("Error in getting data in MapViewViewController: \(error)")
|
|
}
|
|
|
|
let buttonItem = MKUserTrackingBarButtonItem(mapView: mapView)
|
|
self.navigationItem.rightBarButtonItem = buttonItem
|
|
|
|
}
|
|
|
|
|
|
func showMarkersOnMap() {
|
|
for gtw in gateways! {
|
|
let coord = CLLocationCoordinate2D(latitude: (gtw.address?.lat)!, longitude: (gtw.address?.long)!)
|
|
let gatewayAnnotation = GatewayAnnotation(coordinate: coord, title: gtw.name, subtitle: gtw.macAddress, gateway: gtw)
|
|
mapView.addAnnotation(gatewayAnnotation)
|
|
}
|
|
}
|
|
|
|
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
|
|
let identifier = "marker"
|
|
|
|
if annotation.isKind(of: GatewayAnnotation.self) {
|
|
var view: MKMarkerAnnotationView
|
|
|
|
if let dequeuedView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? MKMarkerAnnotationView {
|
|
dequeuedView.annotation = annotation
|
|
view = dequeuedView
|
|
} else {
|
|
view = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: identifier)
|
|
view.canShowCallout = true
|
|
view.calloutOffset = CGPoint(x: -5, y: 5)
|
|
view.rightCalloutAccessoryView = UIButton(type: .detailDisclosure)
|
|
}
|
|
return view
|
|
|
|
} else {
|
|
return nil
|
|
}
|
|
|
|
}
|
|
|
|
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
|
|
let gatewayAnnotation = (view.annotation as! GatewayAnnotation)
|
|
selectedGateway = gatewayAnnotation.gateway
|
|
performSegue(withIdentifier: "openDetailView", sender: nil)
|
|
|
|
}
|
|
|
|
func checkLocationAuthorizationStatus() {
|
|
if CLLocationManager.authorizationStatus() == .authorizedWhenInUse {
|
|
mapView.showsUserLocation = true
|
|
} else {
|
|
locationManager.requestWhenInUseAuthorization()
|
|
}
|
|
}
|
|
|
|
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
|
|
if segue.identifier == "openDetailView" {
|
|
let destinationVC = segue.destination as! MapDetailViewController
|
|
destinationVC.user = user!
|
|
destinationVC.gateway = selectedGateway
|
|
}
|
|
|
|
if segue.identifier == "openListView" {
|
|
let destinationVC = segue.destination as! DeviceListViewController
|
|
destinationVC.user = user!
|
|
}
|
|
}
|
|
|
|
|
|
//MARK: - Data Methods
|
|
|
|
func getAddresses() ->Promise<Any> {
|
|
let url = "\(baseURL)/addresses"
|
|
let headers : HTTPHeaders = [
|
|
"Authorization": user!.authToken
|
|
]
|
|
|
|
return Promise { seal in
|
|
Alamofire.request(url, method: .get, headers: headers)
|
|
.validate()
|
|
.responseJSON { response in
|
|
switch response.result {
|
|
|
|
case .success:
|
|
let addressesJSON : JSON = JSON(response.result.value!)
|
|
for(_, json) : (String, JSON) in addressesJSON {
|
|
do {
|
|
try self.realm.write {
|
|
let addr = Address()
|
|
addr.id = json["id"].intValue
|
|
addr.apartment = json["apartment"].stringValue
|
|
addr.city = json["city"].stringValue
|
|
addr.country = json["country"].stringValue
|
|
addr.lat = json["lat"].doubleValue
|
|
addr.long = json["long"].doubleValue
|
|
addr.state = json["state"].stringValue
|
|
addr.street1 = json["street1"].stringValue
|
|
addr.street2 = json["street2"].stringValue
|
|
addr.zip = json["zip"].stringValue
|
|
addr.zoneId = json["zoneid"].intValue
|
|
self.realm.add(addr, update: true)
|
|
}
|
|
} catch {
|
|
seal.reject(error)
|
|
}
|
|
}
|
|
seal.fulfill(true)
|
|
case .failure(let error):
|
|
seal.reject(error)
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
func getDevices() ->Promise<Any> {
|
|
let url = "\(baseURL)/devices"
|
|
let headers : HTTPHeaders = [
|
|
"Authorization": user!.authToken
|
|
]
|
|
|
|
return Promise { seal in
|
|
Alamofire.request(url, method: .get, headers: headers)
|
|
.validate()
|
|
.responseJSON { response in
|
|
|
|
switch response.result {
|
|
|
|
case .success:
|
|
let devicesJSON : JSON = JSON(response.result.value!)
|
|
for(_, json) : (String, JSON) in devicesJSON {
|
|
do {
|
|
try self.realm.write {
|
|
let dev = Device()
|
|
dev.companyId = json["companyId"].intValue
|
|
dev.deviceTypeId = json["deviceTypeId"].intValue
|
|
dev.gatewayId = json["gatewayId"].intValue
|
|
dev.id = json["id"].intValue
|
|
dev.macAddress = json["macAddress"].stringValue
|
|
dev.techName = json["techname"].stringValue
|
|
dev.tenantId = json["tenantId"].intValue
|
|
dev.vanityName = json["vanityName"].stringValue
|
|
|
|
let pGateway = self.gateways?.filter("id == %d", dev.gatewayId).first
|
|
let pDeviceType = self.deviceTypes?.filter("id == %d", dev.deviceTypeId).first
|
|
|
|
self.realm.add(dev, update: true)
|
|
pGateway?.devices.append(dev)
|
|
pDeviceType?.devices.append(dev)
|
|
}
|
|
} catch {
|
|
seal.reject(error)
|
|
}
|
|
}
|
|
seal.fulfill(true)
|
|
case .failure(let error):
|
|
seal.reject(error)
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
func getGateways() -> Promise<Any> {
|
|
let url = "\(baseURL)/gateways"
|
|
let headers : HTTPHeaders = [
|
|
"Authorization": user!.authToken
|
|
]
|
|
|
|
return Promise { seal in
|
|
Alamofire.request(url, method: .get, headers: headers)
|
|
.responseJSON { response in
|
|
switch response.result {
|
|
|
|
case .success:
|
|
let gatewaysJSON : JSON = JSON(response.result.value!)
|
|
for(_, json) : (String, JSON) in gatewaysJSON {
|
|
|
|
do {
|
|
try self.realm.write {
|
|
let gtw = Gateway()
|
|
gtw.addressId = json["addressId"].intValue
|
|
gtw.companyId = json["companyId"].intValue
|
|
gtw.diaVersion = json["diaVersion"].stringValue
|
|
gtw.gatewayConfigurationId = json["gatewayConfigurationId"].intValue
|
|
gtw.gatewayTypeId = json["gatewayTypeId"].intValue
|
|
gtw.id = json["id"].intValue
|
|
gtw.macAddress = json["macAddress"].stringValue
|
|
gtw.name = json["name"].stringValue
|
|
gtw.panId = json["panId"].stringValue
|
|
gtw.tenantId = json["tenantId"].intValue
|
|
gtw.userId = json["userId"].intValue
|
|
|
|
let associatedAddress = self.addresses?.filter("id == %d", gtw.addressId).first
|
|
gtw.address = associatedAddress
|
|
self.realm.add(gtw, update: true)
|
|
}
|
|
} catch {
|
|
seal.reject(error)
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
seal.fulfill(true)
|
|
case .failure(let error):
|
|
seal.reject(error)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
func getDeviceTypes() -> Promise<Any> {
|
|
let url = "\(baseURL)/devicetypes"
|
|
let headers : HTTPHeaders = [
|
|
"Authorization": user!.authToken
|
|
]
|
|
|
|
return Promise { seal in
|
|
Alamofire.request(url, method: .get, headers: headers)
|
|
.responseJSON { response in
|
|
switch response.result {
|
|
|
|
case .success:
|
|
let deviceTypesJson : JSON = JSON(response.result.value!)
|
|
for(_, json) : (String, JSON) in deviceTypesJson {
|
|
do {
|
|
try self.realm.write {
|
|
let dt = DeviceType()
|
|
dt.companyId = json["CompanyId"].intValue
|
|
dt.id = json["id"].intValue
|
|
dt.imgUrl = json["imgUrl"].stringValue
|
|
dt.name = json["name"].stringValue
|
|
dt.note = json["note"].stringValue
|
|
dt.tenantId = json["tenantId"].intValue
|
|
dt.vanityName = json["vanityName"].stringValue
|
|
self.realm.add(dt, update: true)
|
|
}
|
|
} catch {
|
|
seal.reject(error)
|
|
}
|
|
}
|
|
seal.fulfill(true)
|
|
case .failure(let error):
|
|
seal.reject(error)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//MARK: - Realm Functions
|
|
|
|
func loadData() {
|
|
devices = realm.objects(Device.self)
|
|
deviceTypes = realm.objects(DeviceType.self)
|
|
gateways = realm.objects(Gateway.self)
|
|
addresses = realm.objects(Address.self)
|
|
}
|
|
|
|
}
|