Adds SideMenu and company view
This commit is contained in:
27
pocloud/Cells/AdminCompanyCell.swift
Normal file
27
pocloud/Cells/AdminCompanyCell.swift
Normal file
@@ -0,0 +1,27 @@
|
||||
//
|
||||
// AdminCompanyCell.swift
|
||||
// pocloud
|
||||
//
|
||||
// Created by Patrick McDonagh on 6/6/18.
|
||||
// Copyright © 2018 patrickjmcd. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class AdminCompanyCell: UITableViewCell {
|
||||
|
||||
@IBOutlet weak var companyNameLabel: UILabel!
|
||||
@IBOutlet weak var companyCountLabel: PillUILabel!
|
||||
|
||||
override func awakeFromNib() {
|
||||
super.awakeFromNib()
|
||||
// Initialization code
|
||||
}
|
||||
|
||||
override func setSelected(_ selected: Bool, animated: Bool) {
|
||||
super.setSelected(selected, animated: animated)
|
||||
|
||||
// Configure the view for the selected state
|
||||
}
|
||||
|
||||
}
|
||||
93
pocloud/Controller/AdminViewController.swift
Normal file
93
pocloud/Controller/AdminViewController.swift
Normal file
@@ -0,0 +1,93 @@
|
||||
//
|
||||
// AdminViewController.swift
|
||||
// pocloud
|
||||
//
|
||||
// Created by Patrick McDonagh on 6/6/18.
|
||||
// Copyright © 2018 patrickjmcd. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import RealmSwift
|
||||
import PromiseKit
|
||||
|
||||
class AdminViewController: UITableViewController {
|
||||
let realm = try! Realm()
|
||||
let baseURL = (UIApplication.shared.delegate as! AppDelegate).baseURL
|
||||
let user = (UIApplication.shared.delegate as! AppDelegate).user
|
||||
let appAuth = AppAuth()
|
||||
|
||||
var companiesWithGateways : Results<Company>?
|
||||
var companiesNoGateways : Results<Company>?
|
||||
|
||||
var selectedCompany : Company?
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
// Get company data from Realm
|
||||
companiesWithGateways = realm.objects(Company.self).filter("gateways.@count > 0")
|
||||
companiesNoGateways = realm.objects(Company.self).filter("gateways.@count == 0")
|
||||
|
||||
if (companiesWithGateways!.count + companiesNoGateways!.count) == 0{
|
||||
firstly {
|
||||
getAllMeshifyData(baseURL: self.baseURL, authToken: self.user!.authToken)
|
||||
}.done {
|
||||
self.tableView.reloadData()
|
||||
}.catch { error in
|
||||
print("Error getting all meshify data in AdminViewController: \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Table view data source
|
||||
|
||||
override func numberOfSections(in tableView: UITableView) -> Int {
|
||||
return 2
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
if section == 0 {
|
||||
return companiesWithGateways?.count ?? 0
|
||||
} else {
|
||||
return companiesNoGateways?.count ?? 0
|
||||
}
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
|
||||
if section == 0 {
|
||||
return "Companies with Devices"
|
||||
} else {
|
||||
return "Companies with NO Devices"
|
||||
}
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: "companyCell", for: indexPath) as! AdminCompanyCell
|
||||
if indexPath.section == 0 {
|
||||
cell.companyNameLabel.text = companiesWithGateways![indexPath.row].name
|
||||
cell.companyCountLabel.text = String(companiesWithGateways![indexPath.row].gateways.count)
|
||||
} else {
|
||||
cell.companyNameLabel.text = companiesNoGateways![indexPath.row].name
|
||||
cell.companyCountLabel.isHidden = true
|
||||
cell.accessoryType = .none
|
||||
}
|
||||
return cell
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||
if indexPath.section == 0 {
|
||||
selectedCompany = companiesWithGateways![indexPath.row]
|
||||
performSegue(withIdentifier: "openCompanyDetailView", sender: self)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
|
||||
if segue.identifier == "openCompanyDetailView" {
|
||||
let targetVC = segue.destination as! CompanyViewController
|
||||
targetVC.thisCompany = selectedCompany
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -36,6 +36,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
|
||||
// Chameleon.setGlobalThemeUsingPrimaryColor(UIColor.flatSkyBlue(), with: UIContentStyle.contrast)
|
||||
// print(Realm.Configuration.defaultConfiguration.fileURL)
|
||||
Migrations().checkSchema()
|
||||
FirebaseApp.configure()
|
||||
|
||||
return true
|
||||
|
||||
102
pocloud/Controller/CompanyViewController.swift
Normal file
102
pocloud/Controller/CompanyViewController.swift
Normal file
@@ -0,0 +1,102 @@
|
||||
//
|
||||
// CompanyViewController.swift
|
||||
// pocloud
|
||||
//
|
||||
// Created by Patrick McDonagh on 6/6/18.
|
||||
// Copyright © 2018 patrickjmcd. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import MapKit
|
||||
|
||||
class CompanyViewController: UIViewController, MKMapViewDelegate, UITableViewDataSource, UITableViewDelegate {
|
||||
|
||||
@IBOutlet weak var mapView: MKMapView!
|
||||
@IBOutlet weak var tableView: UITableView!
|
||||
|
||||
var thisCompany : Company?
|
||||
var selectedGateway : Gateway?
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
tableView.delegate = self
|
||||
tableView.dataSource = self
|
||||
mapView.delegate = self
|
||||
|
||||
title = thisCompany?.name
|
||||
|
||||
addMapDot()
|
||||
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
if let company = thisCompany{
|
||||
return company.gateways.count
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: "companyGatewayCell", for: indexPath)
|
||||
cell.textLabel?.text = thisCompany?.gateways[indexPath.row].name
|
||||
return cell
|
||||
}
|
||||
|
||||
|
||||
|
||||
func addMapDot(){
|
||||
let coord = CLLocationCoordinate2D(latitude: (thisCompany?.address!.lat)!, longitude: (thisCompany?.address!.long)!)
|
||||
let gatewayAnnotation = GatewayAnnotation(coordinate: coord, title: (thisCompany?.name)!, subtitle: (thisCompany?.address?.streetAddress)!, gateway: nil)
|
||||
mapView.addAnnotation(gatewayAnnotation)
|
||||
let regionRadius: CLLocationDistance = 1000
|
||||
let coordinateRegion = MKCoordinateRegionMakeWithDistance(coord, regionRadius, regionRadius)
|
||||
mapView.setRegion(coordinateRegion, animated: true)
|
||||
}
|
||||
|
||||
|
||||
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 tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||
selectedGateway = thisCompany?.gateways[indexPath.row]
|
||||
performSegue(withIdentifier: "openGatewayDetail", sender: self)
|
||||
}
|
||||
|
||||
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
|
||||
let location = view.annotation as! GatewayAnnotation
|
||||
let launchOptions = [MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving]
|
||||
location.mapItem().openInMaps(launchOptions: launchOptions)
|
||||
}
|
||||
|
||||
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
|
||||
if segue.identifier == "openGatewayDetail" {
|
||||
let destinationVC = segue.destination as! MapDetailViewController
|
||||
destinationVC.gateway = selectedGateway
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -13,6 +13,7 @@ import RealmSwift
|
||||
import SwiftyJSON
|
||||
import SVProgressHUD
|
||||
import FirebaseDatabase
|
||||
import ChameleonFramework
|
||||
|
||||
class DeviceDetailViewController: UITableViewController {
|
||||
let realm = try! Realm()
|
||||
@@ -28,6 +29,7 @@ class DeviceDetailViewController: UITableViewController {
|
||||
var values : [String : MeshifyValue] = [:]
|
||||
var updatedChannelNames : [String] = [String]()
|
||||
var changedChannelNames : [String] = [String]()
|
||||
let numFormatter = NumberFormatter()
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
@@ -35,6 +37,10 @@ class DeviceDetailViewController: UITableViewController {
|
||||
let macAddress = String((thisDevice?.macAddress.replacingOccurrences(of: ":", with: "").uppercased().dropLast(4))!)
|
||||
let deviceTypeName = (thisDevice?.parentDeviceType.first?.name)!
|
||||
|
||||
numFormatter.minimumFractionDigits = 0
|
||||
numFormatter.maximumFractionDigits = 3
|
||||
numFormatter.minimumIntegerDigits = 1
|
||||
|
||||
SVProgressHUD.show()
|
||||
firstly {
|
||||
loadData()
|
||||
@@ -138,6 +144,18 @@ class DeviceDetailViewController: UITableViewController {
|
||||
print("Error fetching data in DeviceDetailViewController: \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
func tryRound(value : String, places numberOfPlaces: Int) -> String {
|
||||
if let doubledValue = Double(value) {
|
||||
if let formattedString = numFormatter.string(from: NSNumber(value: doubledValue)) {
|
||||
return formattedString
|
||||
} else {
|
||||
return value
|
||||
}
|
||||
} else {
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -158,6 +176,7 @@ class DeviceDetailViewController: UITableViewController {
|
||||
let chanName = thisDevice?.parentDeviceType.first?.channels[indexPath.row].name
|
||||
let chanVal = values[chanName!]
|
||||
|
||||
|
||||
if let i = changedChannelNames.index(of: chanName!) {
|
||||
changedChannelNames.remove(at: i)
|
||||
cell.backgroundColor = UIColor.flatLime()
|
||||
@@ -180,8 +199,8 @@ class DeviceDetailViewController: UITableViewController {
|
||||
}
|
||||
}
|
||||
|
||||
cell.channelValueLabel?.text = tryRound(value: chanVal!.value, places: 3)
|
||||
cell.accessoryType = .disclosureIndicator
|
||||
cell.channelValueLabel?.text = chanVal?.value
|
||||
return cell
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ import SVProgressHUD
|
||||
import FirebaseAuth
|
||||
|
||||
class DeviceListViewController: UITableViewController {
|
||||
@IBOutlet weak var searchBar: UISearchBar!
|
||||
let realm = try! Realm()
|
||||
|
||||
let user = (UIApplication.shared.delegate as! AppDelegate).user
|
||||
@@ -37,6 +38,8 @@ class DeviceListViewController: UITableViewController {
|
||||
refreshControl?.attributedTitle = NSAttributedString(string: "Pull to refresh")
|
||||
refreshControl?.addTarget(self, action: #selector(refresh), for: UIControlEvents.valueChanged)
|
||||
|
||||
searchBar.delegate = self
|
||||
|
||||
navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Log Out", style: .plain, target: self, action: #selector(self.logOut))
|
||||
|
||||
SVProgressHUD.show()
|
||||
@@ -60,13 +63,15 @@ class DeviceListViewController: UITableViewController {
|
||||
func loadJSONData() -> Promise<Void>{
|
||||
return Promise { promise in
|
||||
firstly {
|
||||
getDeviceTypes(baseURL: self.baseURL, authToken: (self.user?.authToken)!)
|
||||
getDeviceTypes(baseURL: self.baseURL, authToken: self.user!.authToken)
|
||||
}.then { _ in
|
||||
getAddresses(baseURL: self.baseURL, authToken: (self.user?.authToken)!)
|
||||
getCompanies(baseURL: self.baseURL, authToken: self.user!.authToken)
|
||||
}.then { _ in
|
||||
getAddresses(baseURL: self.baseURL, authToken: self.user!.authToken)
|
||||
}.then { _ in
|
||||
getGateways(baseURL: self.baseURL, authToken: (self.user?.authToken)!)
|
||||
getGateways(baseURL: self.baseURL, authToken: self.user!.authToken)
|
||||
}.then { _ in
|
||||
getDevices(baseURL: self.baseURL, authToken: (self.user?.authToken)!)
|
||||
getDevices(baseURL: self.baseURL, authToken: self.user!.authToken)
|
||||
}.done{ _ in
|
||||
promise.fulfill(())
|
||||
}.catch { error in
|
||||
@@ -150,3 +155,29 @@ class DeviceListViewController: UITableViewController {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension DeviceListViewController : UISearchBarDelegate {
|
||||
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
|
||||
devices = devices?.filter("vanityName CONTAINS[cd] %@", searchBar.text!).sorted(byKeyPath: "vanityName", ascending: true)
|
||||
tableView.reloadData()
|
||||
}
|
||||
|
||||
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
|
||||
if searchBar.text?.count == 0 {
|
||||
firstly {
|
||||
self.loadRealmData()
|
||||
}.then{ _ in
|
||||
self.loadJSONData()
|
||||
}.done { _ in
|
||||
self.tableView.reloadData()
|
||||
|
||||
DispatchQueue.main.async {
|
||||
searchBar.resignFirstResponder()
|
||||
}
|
||||
}.catch { error in
|
||||
print("Error in getting data in DeviceListViewController: \(error)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
35
pocloud/Controller/MainNavController.swift
Normal file
35
pocloud/Controller/MainNavController.swift
Normal file
@@ -0,0 +1,35 @@
|
||||
//
|
||||
// MainNavController.swift
|
||||
// pocloud
|
||||
//
|
||||
// Created by Patrick McDonagh on 6/6/18.
|
||||
// Copyright © 2018 patrickjmcd. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class MainNavController: UINavigationController {
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
// Do any additional setup after loading the view.
|
||||
}
|
||||
|
||||
override func didReceiveMemoryWarning() {
|
||||
super.didReceiveMemoryWarning()
|
||||
// Dispose of any resources that can be recreated.
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
// MARK: - Navigation
|
||||
|
||||
// In a storyboard-based application, you will often want to do a little preparation before navigation
|
||||
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
|
||||
// Get the new view controller using segue.destinationViewController.
|
||||
// Pass the selected object to the new view controller.
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
@@ -56,7 +56,8 @@ class MapViewController: UIViewController, MKMapViewDelegate {
|
||||
}
|
||||
|
||||
let buttonItem = MKUserTrackingBarButtonItem(mapView: mapView)
|
||||
self.navigationItem.rightBarButtonItem = buttonItem
|
||||
self.navigationItem.rightBarButtonItems?.append(buttonItem)
|
||||
// self.navigationItem.rightBarButtonItem = buttonItem
|
||||
|
||||
navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Log Out", style: .plain, target: self, action: #selector(self.logOut))
|
||||
|
||||
|
||||
@@ -129,9 +129,11 @@ func getGateways(baseURL : String, authToken : String) -> Promise<Any> {
|
||||
gtw.userId = json["userId"].intValue
|
||||
|
||||
let associatedAddress = realm.objects(Address.self).filter("id == %d", gtw.addressId).first
|
||||
let parentCompany = realm.objects(Company.self).filter("id == %d", gtw.companyId).first
|
||||
|
||||
gtw.address = associatedAddress
|
||||
realm.add(gtw, update: true)
|
||||
parentCompany?.gateways.append(gtw)
|
||||
}
|
||||
} catch {
|
||||
seal.reject(error)
|
||||
@@ -262,20 +264,6 @@ func getChannelValues(deviceId: Int, baseURL : String, authToken : String) -> Pr
|
||||
let channelValJSON : JSON = JSON(response.result.value!)
|
||||
var valueDict : [String : MeshifyValue] = [:]
|
||||
for(chName, json) : (String, JSON) in channelValJSON {
|
||||
// do {
|
||||
// try realm.write {
|
||||
// let chv = ChanValue()
|
||||
// chv.uid = "\(deviceId).\(chName)"
|
||||
// chv.name = chName
|
||||
// chv.value = json["value"].stringValue
|
||||
// chv.timestamp = json["timestamp"].intValue
|
||||
//
|
||||
// realm.add(chv, update: true)
|
||||
// realm.objects(Device.self).filter("id == %d", deviceId).first?.values.append(chv)
|
||||
// }
|
||||
// } catch {
|
||||
// prom.reject(error)
|
||||
// }
|
||||
let chv = MeshifyValue()
|
||||
chv.name = chName
|
||||
chv.value = json["value"].stringValue
|
||||
@@ -320,6 +308,69 @@ func getChannelHistory(deviceId: Int, channelId : Int, baseURL : String, authTok
|
||||
}
|
||||
}
|
||||
|
||||
func getCompanies(baseURL : String, authToken : String) -> Promise<Any> {
|
||||
let realm = try! Realm()
|
||||
let url = "\(baseURL)/companies"
|
||||
let headers : HTTPHeaders = [
|
||||
"Authorization": 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 realm.write {
|
||||
let company = Company()
|
||||
company.id = json["id"].intValue
|
||||
company.name = json["name"].stringValue
|
||||
company.tenantId = json["tenantId"].intValue
|
||||
company.addressId = json["addressId"].intValue
|
||||
company.address = realm.objects(Address.self).filter("id == %d", company.addressId).first
|
||||
realm.add(company, update: true)
|
||||
}
|
||||
} catch {
|
||||
seal.reject(error)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
seal.fulfill(true)
|
||||
case .failure(let error):
|
||||
seal.reject(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func getAllMeshifyData(baseURL : String, authToken : String) -> Promise<Void>{
|
||||
return Promise { promise in
|
||||
firstly {
|
||||
getDeviceTypes(baseURL: baseURL, authToken: authToken)
|
||||
}.then { _ in
|
||||
getCompanies(baseURL: baseURL, authToken: authToken)
|
||||
}.then { _ in
|
||||
getAddresses(baseURL: baseURL, authToken: authToken)
|
||||
}.then { _ in
|
||||
getGateways(baseURL: baseURL, authToken: authToken)
|
||||
}.then { _ in
|
||||
getDevices(baseURL: baseURL, authToken: authToken)
|
||||
}.done{ _ in
|
||||
promise.fulfill(())
|
||||
}.catch { error in
|
||||
promise.reject(error)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func writeChannelValue(deviceId: Int, channelName: String, value : String, baseURL : String, authToken : String) -> Promise<Any> {
|
||||
let timestamp: Int = Int(Date().timeIntervalSince1970)
|
||||
var channelJson : JSON = JSON()
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
//
|
||||
// NavigationController.swift
|
||||
// pocloud
|
||||
//
|
||||
// Created by Patrick McDonagh on 5/29/18.
|
||||
// Copyright © 2018 patrickjmcd. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import ChameleonFramework
|
||||
|
||||
class NavigationController: UINavigationController {
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
// Do any additional setup after loading the view.
|
||||
self.navigationBar.tintColor = UIColor.flatSkyBlue()
|
||||
}
|
||||
|
||||
}
|
||||
37
pocloud/Controller/NavigationMenuController.swift
Normal file
37
pocloud/Controller/NavigationMenuController.swift
Normal file
@@ -0,0 +1,37 @@
|
||||
//
|
||||
// NavigationMenuController.swift
|
||||
// pocloud
|
||||
//
|
||||
// Created by Patrick McDonagh on 6/6/18.
|
||||
// Copyright © 2018 patrickjmcd. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class NavigationMenuController: UITableViewController {
|
||||
|
||||
let appAuth = AppAuth()
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
}
|
||||
|
||||
@IBAction func logOutButtonPressed(_ sender: Any) {
|
||||
print("SHOULD LOG OUT")
|
||||
// appAuth.logOut()
|
||||
self.navigationController!.popToRootViewController(animated: true)
|
||||
// self.dismiss(animated: false) {
|
||||
// let mainVC = (UIApplication.shared.delegate!.window!?.rootViewController!)!
|
||||
// if let navController = mainVC.navigationController {
|
||||
// navController.popToRootViewController(animated: true)
|
||||
// } else {
|
||||
// print("NO NAV CONTROLLER")
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -17,7 +17,7 @@
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>5</string>
|
||||
<string>7</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>NSLocationUsageDescription</key>
|
||||
|
||||
@@ -44,6 +44,10 @@ class Address : Object {
|
||||
// return mapItem
|
||||
// }
|
||||
//
|
||||
public var streetAddress : String {
|
||||
return "\(street1)\n\(street2)\n\(city), \(state) \(zip)\n\(country)"
|
||||
}
|
||||
|
||||
override static func primaryKey() -> String? {
|
||||
return "id"
|
||||
}
|
||||
|
||||
24
pocloud/Model/Company.swift
Normal file
24
pocloud/Model/Company.swift
Normal file
@@ -0,0 +1,24 @@
|
||||
//
|
||||
// Company.swift
|
||||
// pocloud
|
||||
//
|
||||
// Created by Patrick McDonagh on 6/6/18.
|
||||
// Copyright © 2018 patrickjmcd. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import RealmSwift
|
||||
|
||||
class Company : Object {
|
||||
@objc dynamic var id : Int = 0
|
||||
@objc dynamic var name : String = ""
|
||||
@objc dynamic var tenantId : Int = 0
|
||||
@objc dynamic var addressId : Int = 0
|
||||
@objc dynamic var address : Address?
|
||||
|
||||
override static func primaryKey() -> String? {
|
||||
return "id"
|
||||
}
|
||||
|
||||
let gateways = List<Gateway>()
|
||||
}
|
||||
@@ -23,7 +23,9 @@ class Gateway : Object {
|
||||
@objc dynamic var userId : Int = 0
|
||||
@objc dynamic var address : Address?
|
||||
|
||||
|
||||
var devices = List<Device>()
|
||||
var parentCompany = LinkingObjects(fromType: Company.self, property: "gateways")
|
||||
|
||||
override static func primaryKey() -> String? {
|
||||
return "id"
|
||||
|
||||
44
pocloud/Model/Migrations.swift
Normal file
44
pocloud/Model/Migrations.swift
Normal file
@@ -0,0 +1,44 @@
|
||||
//
|
||||
// Migrations.swift
|
||||
// pocloud
|
||||
//
|
||||
// Created by Patrick McDonagh on 6/6/18.
|
||||
// Copyright © 2018 patrickjmcd. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import RealmSwift
|
||||
|
||||
class Migrations {
|
||||
|
||||
func checkSchema() {
|
||||
let config = Realm.Configuration(
|
||||
// Set the new schema version. This must be greater than the previously used
|
||||
// version (if you've never set a schema version before, the version is 0).
|
||||
schemaVersion: 1,
|
||||
|
||||
// Set the block which will be called automatically when opening a Realm with
|
||||
// a schema version lower than the one set above
|
||||
migrationBlock: { migration, oldSchemaVersion in
|
||||
// We haven’t migrated anything yet, so oldSchemaVersion == 0
|
||||
print(oldSchemaVersion)
|
||||
switch oldSchemaVersion {
|
||||
case 1:
|
||||
break
|
||||
default:
|
||||
// Nothing to do!
|
||||
self.zeroToOne(migration: migration)
|
||||
}
|
||||
})
|
||||
Realm.Configuration.defaultConfiguration = config
|
||||
print("Migration done")
|
||||
}
|
||||
|
||||
func zeroToOne(migration : Migration) {
|
||||
print("Performing migration from 0 to 1")
|
||||
migration.enumerateObjects(ofType: Company.className(), { (oldObject, newObject) in
|
||||
migration.delete(oldObject!)
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
@@ -22,13 +22,13 @@
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="POCloud" translatesAutoresizingMaskIntoConstraints="NO" id="1S2-PY-AeP">
|
||||
<rect key="frame" x="16" y="78" width="343" height="128"/>
|
||||
<rect key="frame" x="16" y="130" width="343" height="128"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="128" id="kdi-J3-yap"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Nk0-L4-BTc">
|
||||
<rect key="frame" x="16" y="216" width="343" height="110"/>
|
||||
<rect key="frame" x="16" y="268" width="343" height="110"/>
|
||||
<subviews>
|
||||
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="xGD-1W-wfk" userLabel="passwordField">
|
||||
<rect key="frame" x="0.0" y="40" width="343" height="30"/>
|
||||
@@ -89,7 +89,7 @@
|
||||
</constraints>
|
||||
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
|
||||
</view>
|
||||
<navigationItem key="navigationItem" title="Login" id="Vcq-WU-7nG"/>
|
||||
<navigationItem key="navigationItem" title="Login" largeTitleDisplayMode="always" id="Vcq-WU-7nG"/>
|
||||
<connections>
|
||||
<outlet property="emailField" destination="ktz-LF-BMG" id="YD6-kd-Y0H"/>
|
||||
<outlet property="passwordField" destination="xGD-1W-wfk" id="grX-b5-xhC"/>
|
||||
@@ -98,7 +98,271 @@
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="193" y="127"/>
|
||||
<point key="canvasLocation" x="-940" y="84"/>
|
||||
</scene>
|
||||
<!-- -->
|
||||
<scene sceneID="zqR-cL-CY1">
|
||||
<objects>
|
||||
<tableViewController id="IRa-Tu-z8L" customClass="NavigationMenuController" customModule="pocloud" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="static" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" id="rZD-k6-vfI">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<sections>
|
||||
<tableViewSection id="BZs-uI-hiP">
|
||||
<cells>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" id="MOW-uN-hVD">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="MOW-uN-hVD" id="Zft-87-4vv">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Map View" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="K2m-on-u83">
|
||||
<rect key="frame" x="16" y="0.0" width="343" height="44"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="44" id="WkR-Ec-bck"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="K2m-on-u83" secondAttribute="trailing" constant="16" id="itX-5w-OBv"/>
|
||||
<constraint firstItem="K2m-on-u83" firstAttribute="leading" secondItem="Zft-87-4vv" secondAttribute="leading" constant="16" id="ov7-hP-RzB"/>
|
||||
<constraint firstAttribute="bottom" secondItem="K2m-on-u83" secondAttribute="bottom" id="uWk-am-QXU"/>
|
||||
<constraint firstItem="K2m-on-u83" firstAttribute="top" secondItem="Zft-87-4vv" secondAttribute="top" id="v3E-fu-Z3h"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
<connections>
|
||||
<segue destination="yV3-Bs-nOb" kind="show" identifier="openMapView" id="vHY-2V-RrB"/>
|
||||
</connections>
|
||||
</tableViewCell>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" id="tgi-Lg-OUk">
|
||||
<rect key="frame" x="0.0" y="44" width="375" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="tgi-Lg-OUk" id="cHZ-P5-57P">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="List View" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="O2Q-ia-Znc">
|
||||
<rect key="frame" x="16" y="0.0" width="343" height="44"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="44" id="OUu-Sl-qO8"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="O2Q-ia-Znc" firstAttribute="top" secondItem="cHZ-P5-57P" secondAttribute="top" id="6b0-uT-Dyz"/>
|
||||
<constraint firstAttribute="trailing" secondItem="O2Q-ia-Znc" secondAttribute="trailing" constant="16" id="X35-2D-Vmj"/>
|
||||
<constraint firstAttribute="bottom" secondItem="O2Q-ia-Znc" secondAttribute="bottom" id="gii-t8-r0I"/>
|
||||
<constraint firstItem="O2Q-ia-Znc" firstAttribute="leading" secondItem="cHZ-P5-57P" secondAttribute="leading" constant="16" id="tNz-Jj-6c9"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
<connections>
|
||||
<segue destination="2zN-e5-x2c" kind="show" identifier="openListView" id="9Om-lw-Jgn"/>
|
||||
</connections>
|
||||
</tableViewCell>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" id="MFi-Ch-dpb">
|
||||
<rect key="frame" x="0.0" y="88" width="375" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="MFi-Ch-dpb" id="uOu-qn-Bsk">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Company View" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="PBz-lV-jm5">
|
||||
<rect key="frame" x="16" y="0.0" width="343" height="44"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="44" id="W4g-rH-3kB"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="PBz-lV-jm5" firstAttribute="top" secondItem="uOu-qn-Bsk" secondAttribute="top" id="eFS-1d-xye"/>
|
||||
<constraint firstItem="PBz-lV-jm5" firstAttribute="leading" secondItem="uOu-qn-Bsk" secondAttribute="leading" constant="16" id="uJV-EL-4pQ"/>
|
||||
<constraint firstAttribute="bottom" secondItem="PBz-lV-jm5" secondAttribute="bottom" id="y0g-od-TRr"/>
|
||||
<constraint firstAttribute="trailing" secondItem="PBz-lV-jm5" secondAttribute="trailing" constant="16" id="y7M-Vh-JFu"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
<connections>
|
||||
<segue destination="gRf-OH-LM3" kind="show" identifier="openAdminView" id="gSm-yD-AQS"/>
|
||||
</connections>
|
||||
</tableViewCell>
|
||||
</cells>
|
||||
</tableViewSection>
|
||||
</sections>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="IRa-Tu-z8L" id="x7M-5j-lGC"/>
|
||||
<outlet property="delegate" destination="IRa-Tu-z8L" id="hPj-B4-IPb"/>
|
||||
</connections>
|
||||
</tableView>
|
||||
<navigationItem key="navigationItem" title=" " id="jEZ-M0-fct">
|
||||
<barButtonItem key="rightBarButtonItem" enabled="NO" title="Log Out" id="Efy-Wb-N0o">
|
||||
<connections>
|
||||
<action selector="logOutButtonPressed:" destination="IRa-Tu-z8L" id="fC3-XJ-dWk"/>
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
</navigationItem>
|
||||
</tableViewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="BGw-nQ-anY" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="1522" y="-1304"/>
|
||||
</scene>
|
||||
<!--Admin View-->
|
||||
<scene sceneID="luK-QG-5Bk">
|
||||
<objects>
|
||||
<tableViewController title="Admin View" id="gRf-OH-LM3" customClass="AdminViewController" customModule="pocloud" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" id="pRZ-8h-aCt">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<prototypes>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="companyCell" id="DRr-fl-mHP" customClass="AdminCompanyCell" customModule="pocloud" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="28" width="375" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="DRr-fl-mHP" id="P5X-PW-Uxh">
|
||||
<rect key="frame" x="0.0" y="0.0" width="341" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillProportionally" alignment="center" translatesAutoresizingMaskIntoConstraints="NO" id="EhU-GL-Npw">
|
||||
<rect key="frame" x="16" y="0.0" width="325" height="43.5"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Company Name" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="X2f-5T-wWU">
|
||||
<rect key="frame" x="0.0" y="11.5" width="278.5" height="20.5"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="cnt" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="16b-fu-GPA" customClass="PillUILabel" customModule="pocloud" customModuleProvider="target">
|
||||
<rect key="frame" x="278.5" y="8.5" width="46.5" height="26.5"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.32852089410000002" blue="0.57488495110000004" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<nil key="highlightedColor"/>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="number" keyPath="horizontalPad">
|
||||
<real key="value" value="3"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
<userDefinedRuntimeAttribute type="number" keyPath="verticalPad">
|
||||
<real key="value" value="3"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</label>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="16b-fu-GPA" firstAttribute="width" secondItem="X2f-5T-wWU" secondAttribute="width" multiplier="1:6" id="Thj-dG-e0H"/>
|
||||
</constraints>
|
||||
</stackView>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="EhU-GL-Npw" secondAttribute="trailing" id="SSP-KX-dUn"/>
|
||||
<constraint firstAttribute="bottom" secondItem="EhU-GL-Npw" secondAttribute="bottom" id="gWW-wI-VKJ"/>
|
||||
<constraint firstItem="EhU-GL-Npw" firstAttribute="top" secondItem="P5X-PW-Uxh" secondAttribute="top" id="rlm-TY-nIF"/>
|
||||
<constraint firstItem="EhU-GL-Npw" firstAttribute="leading" secondItem="P5X-PW-Uxh" secondAttribute="leading" constant="16" id="shl-Ek-QFo"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
<connections>
|
||||
<outlet property="companyCountLabel" destination="16b-fu-GPA" id="ycu-fG-ojM"/>
|
||||
<outlet property="companyNameLabel" destination="X2f-5T-wWU" id="wnq-TY-OZG"/>
|
||||
</connections>
|
||||
</tableViewCell>
|
||||
</prototypes>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="gRf-OH-LM3" id="0ea-wk-hcW"/>
|
||||
<outlet property="delegate" destination="gRf-OH-LM3" id="stD-ti-ZKX"/>
|
||||
</connections>
|
||||
</tableView>
|
||||
<navigationItem key="navigationItem" title="Company View" id="mC8-zn-oFH">
|
||||
<barButtonItem key="rightBarButtonItem" title="Menu" id="3os-hB-xsh">
|
||||
<connections>
|
||||
<segue destination="Xem-jg-Xlm" kind="presentation" identifier="openMenu" id="LUR-lb-5qK"/>
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
</navigationItem>
|
||||
<connections>
|
||||
<segue destination="1Oj-LF-SeF" kind="show" identifier="openCompanyDetailView" id="fe4-55-2K0"/>
|
||||
</connections>
|
||||
</tableViewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="DB1-BB-Mof" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="2492" y="-1305"/>
|
||||
</scene>
|
||||
<!--Title-->
|
||||
<scene sceneID="zaO-o6-5qR">
|
||||
<objects>
|
||||
<viewController id="1Oj-LF-SeF" customClass="CompanyViewController" customModule="pocloud" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<view key="view" contentMode="scaleToFill" id="GRC-ek-5fe">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="TeN-MF-HxZ">
|
||||
<rect key="frame" x="0.0" y="20" width="375" height="647"/>
|
||||
<subviews>
|
||||
<mapView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" mapType="standard" translatesAutoresizingMaskIntoConstraints="NO" id="UFa-F1-ny6">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="215.5"/>
|
||||
</mapView>
|
||||
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="tuB-TB-6oT">
|
||||
<rect key="frame" x="0.0" y="215.5" width="375" height="431.5"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<prototypes>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="companyGatewayCell" id="vCb-SM-3BC">
|
||||
<rect key="frame" x="0.0" y="28" width="375" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="vCb-SM-3BC" id="jo4-sq-noy">
|
||||
<rect key="frame" x="0.0" y="0.0" width="342" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
</prototypes>
|
||||
</tableView>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="tuB-TB-6oT" firstAttribute="height" secondItem="UFa-F1-ny6" secondAttribute="height" multiplier="2:1" id="8yd-Ai-MxK"/>
|
||||
</constraints>
|
||||
</stackView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstItem="TeN-MF-HxZ" firstAttribute="trailing" secondItem="VXe-is-TrW" secondAttribute="trailing" id="Yqg-gC-eg1"/>
|
||||
<constraint firstItem="TeN-MF-HxZ" firstAttribute="leading" secondItem="VXe-is-TrW" secondAttribute="leading" id="cxy-jx-iWN"/>
|
||||
<constraint firstItem="VXe-is-TrW" firstAttribute="bottom" secondItem="TeN-MF-HxZ" secondAttribute="bottom" id="jjA-XJ-LOb"/>
|
||||
<constraint firstItem="TeN-MF-HxZ" firstAttribute="top" secondItem="VXe-is-TrW" secondAttribute="top" id="u4f-bI-9xa"/>
|
||||
</constraints>
|
||||
<viewLayoutGuide key="safeArea" id="VXe-is-TrW"/>
|
||||
</view>
|
||||
<navigationItem key="navigationItem" title="Title" id="Ja7-Gn-Q1G"/>
|
||||
<connections>
|
||||
<outlet property="mapView" destination="UFa-F1-ny6" id="q6c-IG-QE3"/>
|
||||
<outlet property="tableView" destination="tuB-TB-6oT" id="Vtm-TF-70f"/>
|
||||
<segue destination="T4w-Nz-H9R" kind="show" identifier="openGatewayDetail" id="DQm-0d-brY"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="7wS-xR-ms3" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="3449" y="-1306"/>
|
||||
</scene>
|
||||
<!--Side Menu Navigation Controller-->
|
||||
<scene sceneID="gOX-yi-sFP">
|
||||
<objects>
|
||||
<navigationController id="Xem-jg-Xlm" customClass="UISideMenuNavigationController" customModule="SideMenu" sceneMemberID="viewController">
|
||||
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="kQ0-0P-nCC">
|
||||
<rect key="frame" x="0.0" y="20" width="375" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</navigationBar>
|
||||
<connections>
|
||||
<segue destination="IRa-Tu-z8L" kind="relationship" relationship="rootViewController" id="rm7-9q-AsM"/>
|
||||
</connections>
|
||||
</navigationController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="2za-Iu-Z6p" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="580" y="-1305"/>
|
||||
</scene>
|
||||
<!--Map View-->
|
||||
<scene sceneID="pGu-9T-qKp">
|
||||
@@ -123,9 +387,9 @@
|
||||
</view>
|
||||
<toolbarItems/>
|
||||
<navigationItem key="navigationItem" title="Map" id="Qgs-vF-MTh">
|
||||
<barButtonItem key="rightBarButtonItem" title="List View" id="5K7-Fn-pYV">
|
||||
<barButtonItem key="rightBarButtonItem" title="Menu" id="5K7-Fn-pYV">
|
||||
<connections>
|
||||
<segue destination="2zN-e5-x2c" kind="show" identifier="openListView" id="23K-gs-PXS"/>
|
||||
<segue destination="Xem-jg-Xlm" kind="show" identifier="openMenu" id="Whl-9k-Yj2"/>
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
</navigationItem>
|
||||
@@ -137,24 +401,24 @@
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="ZSI-bq-lES" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="1137" y="-305"/>
|
||||
<point key="canvasLocation" x="978" y="-227"/>
|
||||
</scene>
|
||||
<!--Detail View-->
|
||||
<!--Location Detail View-->
|
||||
<scene sceneID="LQ9-aX-3sA">
|
||||
<objects>
|
||||
<viewController title="Detail View" id="T4w-Nz-H9R" customClass="MapDetailViewController" customModule="pocloud" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<viewController title="Location Detail View" id="T4w-Nz-H9R" customClass="MapDetailViewController" customModule="pocloud" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<view key="view" contentMode="scaleToFill" id="ecT-Qg-rFR">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<mapView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" mapType="standard" translatesAutoresizingMaskIntoConstraints="NO" id="xug-gE-FQz">
|
||||
<rect key="frame" x="0.0" y="109" width="375" height="200"/>
|
||||
<rect key="frame" x="0.0" y="65" width="375" height="200"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="200" id="tu9-2Y-yHN"/>
|
||||
</constraints>
|
||||
</mapView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="GatewayName" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="izu-lT-xWY">
|
||||
<rect key="frame" x="8" y="64" width="359" height="45"/>
|
||||
<rect key="frame" x="8" y="20" width="359" height="45"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="45" id="jbO-lj-xVg"/>
|
||||
</constraints>
|
||||
@@ -163,7 +427,7 @@
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="tRH-fh-elp">
|
||||
<rect key="frame" x="0.0" y="319" width="375" height="304"/>
|
||||
<rect key="frame" x="0.0" y="275" width="375" height="392"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<prototypes>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" selectionStyle="blue" accessoryType="disclosureIndicator" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="dataViewCell" rowHeight="60" id="5Sz-TR-mVj" customClass="MapDetailDeviceCell" customModule="pocloud" customModuleProvider="target">
|
||||
@@ -237,9 +501,9 @@
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="Rio-1u-3O1" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="1984.8" y="126.38680659670166"/>
|
||||
<point key="canvasLocation" x="2001" y="-325"/>
|
||||
</scene>
|
||||
<!--Title-->
|
||||
<!--Device Detail-->
|
||||
<scene sceneID="q7c-Eh-Thg">
|
||||
<objects>
|
||||
<tableViewController id="eOb-fR-aFg" customClass="DeviceDetailViewController" customModule="pocloud" customModuleProvider="target" sceneMemberID="viewController">
|
||||
@@ -301,7 +565,7 @@
|
||||
</connections>
|
||||
</tableView>
|
||||
<toolbarItems/>
|
||||
<navigationItem key="navigationItem" title="Title" id="sUT-g4-ZVO"/>
|
||||
<navigationItem key="navigationItem" title="Device Detail" id="sUT-g4-ZVO"/>
|
||||
<nil key="simulatedBottomBarMetrics"/>
|
||||
<refreshControl key="refreshControl" opaque="NO" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" id="4fv-Lb-C8k">
|
||||
<rect key="frame" x="0.0" y="0.0" width="1000" height="1000"/>
|
||||
@@ -313,7 +577,7 @@
|
||||
</tableViewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="AE9-Tt-eth" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="2780" y="456.52173913043481"/>
|
||||
<point key="canvasLocation" x="2001" y="532"/>
|
||||
</scene>
|
||||
<!--Channel Detail View Controller-->
|
||||
<scene sceneID="fDD-ow-Xi3">
|
||||
@@ -548,7 +812,7 @@
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="qLG-JD-OG3" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="3600.8000000000002" y="456.52173913043481"/>
|
||||
<point key="canvasLocation" x="3004" y="531"/>
|
||||
</scene>
|
||||
<!--History Graph View Controller-->
|
||||
<scene sceneID="WkV-VI-zTb">
|
||||
@@ -606,7 +870,7 @@
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="Add-tM-hJL" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="4352.8000000000002" y="456.52173913043481"/>
|
||||
<point key="canvasLocation" x="3972" y="530"/>
|
||||
</scene>
|
||||
<!--POCloud Data-->
|
||||
<scene sceneID="CNC-dV-jZs">
|
||||
@@ -616,9 +880,14 @@
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<searchBar key="tableHeaderView" contentMode="redraw" id="z2g-Ak-4Pp">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||
<textInputTraits key="textInputTraits"/>
|
||||
</searchBar>
|
||||
<prototypes>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="deviceListCell" id="rJT-U8-JVI">
|
||||
<rect key="frame" x="0.0" y="28" width="375" height="44"/>
|
||||
<rect key="frame" x="0.0" y="72" width="375" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="rJT-U8-JVI" id="f7t-a1-NDN">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
|
||||
@@ -632,9 +901,9 @@
|
||||
</connections>
|
||||
</tableView>
|
||||
<navigationItem key="navigationItem" title="POCloud Data" id="u6I-Ca-wA2">
|
||||
<barButtonItem key="rightBarButtonItem" title="Map View" id="yA7-No-AKb">
|
||||
<barButtonItem key="rightBarButtonItem" title="Menu" id="yA7-No-AKb">
|
||||
<connections>
|
||||
<segue destination="yV3-Bs-nOb" kind="show" identifier="openMapView" id="HF3-JU-BOm"/>
|
||||
<segue destination="Xem-jg-Xlm" kind="show" identifier="openMenu" id="qTd-vu-ryN"/>
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
</navigationItem>
|
||||
@@ -643,19 +912,20 @@
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</refreshControl>
|
||||
<connections>
|
||||
<outlet property="searchBar" destination="z2g-Ak-4Pp" id="XeB-mp-w39"/>
|
||||
<segue destination="eOb-fR-aFg" kind="show" identifier="openDeviceDetailView" id="wUb-ND-zk7"/>
|
||||
</connections>
|
||||
</tableViewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="uhB-7k-gae" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="1136.8" y="456.52173913043481"/>
|
||||
<point key="canvasLocation" x="-212" y="84"/>
|
||||
</scene>
|
||||
<!--Navigation Controller-->
|
||||
<!--Main Nav Controller-->
|
||||
<scene sceneID="zCd-ds-i4W">
|
||||
<objects>
|
||||
<navigationController id="iJg-Zc-arO" customClass="NavigationController" customModule="pocloud" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="eWM-wh-jgG">
|
||||
<rect key="frame" x="0.0" y="20" width="375" height="44"/>
|
||||
<navigationController id="iJg-Zc-arO" customClass="MainNavController" customModule="pocloud" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" largeTitles="YES" id="eWM-wh-jgG">
|
||||
<rect key="frame" x="0.0" y="20" width="375" height="96"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<color key="barTintColor" red="0.90823972225189209" green="0.92638683319091797" blue="0.9317171573638916" alpha="1" colorSpace="calibratedRGB"/>
|
||||
</navigationBar>
|
||||
@@ -665,14 +935,16 @@
|
||||
</navigationController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="8gs-d8-KhR" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="-774" y="128"/>
|
||||
<point key="canvasLocation" x="-1713" y="85"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
<resources>
|
||||
<image name="POCloud" width="2100" height="512"/>
|
||||
</resources>
|
||||
<inferredMetricsTieBreakers>
|
||||
<segue reference="CI7-x2-asH"/>
|
||||
<segue reference="9Om-lw-Jgn"/>
|
||||
<segue reference="wUb-ND-zk7"/>
|
||||
<segue reference="DQm-0d-brY"/>
|
||||
<segue reference="LUR-lb-5qK"/>
|
||||
</inferredMetricsTieBreakers>
|
||||
</document>
|
||||
|
||||
45
pocloud/View/PillUILabel.swift
Normal file
45
pocloud/View/PillUILabel.swift
Normal file
@@ -0,0 +1,45 @@
|
||||
//
|
||||
// PillUILabel.swift
|
||||
// pocloud
|
||||
//
|
||||
// Created by Patrick McDonagh on 6/6/18.
|
||||
// Copyright © 2018 patrickjmcd. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
@IBDesignable class PillUILabel : UILabel {
|
||||
@IBInspectable var verticalPad: CGFloat = 0
|
||||
@IBInspectable var horizontalPad: CGFloat = 0
|
||||
|
||||
func setup() {
|
||||
layer.cornerRadius = frame.height / 2
|
||||
clipsToBounds = true
|
||||
textAlignment = .center
|
||||
}
|
||||
|
||||
override func awakeFromNib() {
|
||||
super.awakeFromNib()
|
||||
setup()
|
||||
}
|
||||
|
||||
override func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
setup()
|
||||
}
|
||||
|
||||
override func prepareForInterfaceBuilder() {
|
||||
super.prepareForInterfaceBuilder()
|
||||
setup()
|
||||
}
|
||||
|
||||
override var intrinsicContentSize: CGSize {
|
||||
let superSize = super.intrinsicContentSize
|
||||
let newWidth = superSize.width + superSize.height + (2 * horizontalPad)
|
||||
let newHeight = superSize.height + (2 * verticalPad)
|
||||
let newSize = CGSize(width: newWidth, height: newHeight)
|
||||
return newSize
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user