Adds firebase live data
Also no longer crashes when touching something while loading
This commit is contained in:
@@ -11,6 +11,7 @@ import PromiseKit
|
||||
import Alamofire
|
||||
import SwiftyJSON
|
||||
import RealmSwift
|
||||
import Firebase
|
||||
|
||||
@UIApplicationMain
|
||||
class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
@@ -35,195 +36,9 @@ 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)
|
||||
FirebaseApp.configure()
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
//MARK: - Data Methods
|
||||
|
||||
// func getAddresses() ->Promise<Any> {
|
||||
// let realm = try! Realm()
|
||||
// let url = "\(baseURL)/addresses"
|
||||
// let headers : HTTPHeaders = [
|
||||
// "Authorization": user!.authToken
|
||||
// ]
|
||||
//
|
||||
// return Promise { promise 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 realm.write {
|
||||
// let addr = Address()
|
||||
// addr.id = json["id"].intValue
|
||||
// addr.apartment = json["id"].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
|
||||
// realm.add(addr, update: true)
|
||||
// }
|
||||
// } catch {
|
||||
// promise.reject(error)
|
||||
// }
|
||||
// }
|
||||
// promise.fulfill(true)
|
||||
// case .failure(let error):
|
||||
// promise.reject(error)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//
|
||||
// func getDevices(gateways : Results<Gateway>, deviceTypes : Results<DeviceType>) ->Promise<Any> {
|
||||
// let realm = try! Realm()
|
||||
// let url = "\(baseURL)/devices"
|
||||
// let headers : HTTPHeaders = [
|
||||
// "Authorization": user!.authToken
|
||||
// ]
|
||||
//
|
||||
// return Promise { promise 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 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 = gateways.filter("id == %d", dev.gatewayId).first
|
||||
// let pDeviceType = deviceTypes.filter("id == %d", dev.deviceTypeId).first
|
||||
//
|
||||
// realm.add(dev, update: true)
|
||||
// pGateway?.devices.append(dev)
|
||||
// pDeviceType?.devices.append(dev)
|
||||
// }
|
||||
// } catch {
|
||||
// promise.reject(error)
|
||||
// }
|
||||
// }
|
||||
// promise.fulfill(true)
|
||||
// case .failure(let error):
|
||||
// promise.reject(error)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//
|
||||
// func getGateways(addresses : Results<Address>) -> Promise<Any> {
|
||||
//
|
||||
// let realm = try! Realm()
|
||||
// let url = "\(baseURL)/gateways"
|
||||
// let headers : HTTPHeaders = [
|
||||
// "Authorization": user!.authToken
|
||||
// ]
|
||||
//
|
||||
// return Promise { promise 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 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 = addresses.filter("id == %d", gtw.addressId).first
|
||||
//
|
||||
// gtw.address = associatedAddress
|
||||
// realm.add(gtw, update: true)
|
||||
// }
|
||||
// } catch {
|
||||
// promise.reject(error)
|
||||
// }
|
||||
// }
|
||||
// promise.fulfill(true)
|
||||
// case .failure(let error):
|
||||
// promise.reject(error)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//
|
||||
// func getDeviceTypes() -> Promise<Any> {
|
||||
// let realm = try! Realm()
|
||||
// let url = "\(baseURL)/devicetypes"
|
||||
// let headers : HTTPHeaders = [
|
||||
// "Authorization": user!.authToken
|
||||
// ]
|
||||
//
|
||||
// return Promise { promise 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 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
|
||||
// realm.add(dt, update: true)
|
||||
// }
|
||||
// } catch {
|
||||
// promise.reject(error)
|
||||
// }
|
||||
// }
|
||||
// promise.fulfill(true)
|
||||
// case .failure(let error):
|
||||
// promise.reject(error)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ import PromiseKit
|
||||
import RealmSwift
|
||||
import SwiftyJSON
|
||||
import SVProgressHUD
|
||||
import FirebaseDatabase
|
||||
|
||||
class DeviceDetailViewController: UITableViewController {
|
||||
let realm = try! Realm()
|
||||
@@ -21,10 +22,18 @@ class DeviceDetailViewController: UITableViewController {
|
||||
var thisDevice : Device?
|
||||
var deviceTypes : Results<DeviceType>?
|
||||
var selectedChannel : Channel?
|
||||
|
||||
var channelLookup : [String : Int] = [:]
|
||||
var values : [String : MeshifyValue] = [:]
|
||||
var updatedChannelNames : [String] = [String]()
|
||||
var changedChannelNames : [String] = [String]()
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
let macAddress = String((thisDevice?.macAddress.replacingOccurrences(of: ":", with: "").uppercased().dropLast(4))!)
|
||||
let deviceTypeName = (thisDevice?.parentDeviceType.first?.name)!
|
||||
|
||||
SVProgressHUD.show()
|
||||
firstly {
|
||||
loadData()
|
||||
@@ -34,6 +43,8 @@ class DeviceDetailViewController: UITableViewController {
|
||||
print("Error in loadData: \(error)")
|
||||
}
|
||||
|
||||
|
||||
|
||||
self.navigationItem.title = thisDevice?.vanityName
|
||||
|
||||
self.refreshControl = UIRefreshControl()
|
||||
@@ -45,17 +56,74 @@ class DeviceDetailViewController: UITableViewController {
|
||||
getChannels(deviceTypeId: thisDevice!.deviceTypeId, baseURL: baseURL, authToken: (user?.authToken)!)
|
||||
}.then { _ in
|
||||
getChannelValues(deviceId: self.thisDevice!.id, baseURL: self.baseURL, authToken: (self.user?.authToken)!)
|
||||
}.done { _ in
|
||||
}.done { (valueDict) in
|
||||
self.values = valueDict
|
||||
self.tableView.reloadData()
|
||||
SVProgressHUD.dismiss()
|
||||
self.refreshControl?.endRefreshing()
|
||||
if let dev = self.thisDevice {
|
||||
for chanIndex in 0..<dev.values.count {
|
||||
let chanName = dev.values[chanIndex].name
|
||||
self.channelLookup[chanName] = chanIndex
|
||||
}
|
||||
}
|
||||
self.getFirebaseDeviceValues(deviceMacAddress: macAddress, deviceTypeName: deviceTypeName)
|
||||
}.catch { error in
|
||||
print("Error fetching data in DeviceDetailViewController: \(error)")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override func viewWillDisappear(_ animated: Bool) {
|
||||
Database.database().reference().removeAllObservers()
|
||||
}
|
||||
|
||||
func getFirebaseDeviceValues(deviceMacAddress : String, deviceTypeName : String) {
|
||||
// let getVals = Database.database().reference().child("devices")
|
||||
// .child(deviceMacAddress)
|
||||
// .child(deviceTypeName)
|
||||
// .child("channels")
|
||||
// .observe(.value) { snapshot in
|
||||
// let snapValue = snapshot.value as! NSDictionary
|
||||
//
|
||||
//
|
||||
// let chanVal = MeshifyValue()
|
||||
// chanVal.name = (value["name"] as? String)!
|
||||
// chanVal.timestamp = Int((value["timestamp"] as? String)!)!
|
||||
// chanVal.value = (value["value"] as? String)!
|
||||
// self.values[chanVal.name] = chanVal
|
||||
// print("should set \(chanVal.value) as \(chanVal.name)")
|
||||
// self.updatedChannelNames.append(chanVal.name)
|
||||
// self.tableView.reloadData()
|
||||
// }
|
||||
// Database.database().reference().removeObserver(withHandle: getVals)
|
||||
|
||||
Database.database().reference().child("devices")
|
||||
.child(deviceMacAddress)
|
||||
.child(deviceTypeName)
|
||||
.child("channels")
|
||||
.observe(.childChanged) { snapshot in
|
||||
let value = snapshot.value as! NSDictionary
|
||||
let chanVal = MeshifyValue()
|
||||
|
||||
chanVal.name = (value["name"] as? String)!
|
||||
chanVal.timestamp = Int((value["timestamp"] as? String)!)!
|
||||
chanVal.value = (value["value"] as? String)!
|
||||
let prevChanValue = self.values[chanVal.name]?.value
|
||||
if prevChanValue != chanVal.value {
|
||||
self.changedChannelNames.append(chanVal.name)
|
||||
} else {
|
||||
self.updatedChannelNames.append(chanVal.name)
|
||||
}
|
||||
self.values[chanVal.name] = chanVal
|
||||
self.tableView.reloadData()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@objc func refresh() {
|
||||
updatedChannelNames.removeAll()
|
||||
changedChannelNames.removeAll()
|
||||
SVProgressHUD.show()
|
||||
firstly {
|
||||
getChannels(deviceTypeId: thisDevice!.deviceTypeId, baseURL: baseURL, authToken: (user?.authToken)!)
|
||||
@@ -75,7 +143,8 @@ class DeviceDetailViewController: UITableViewController {
|
||||
// MARK: - Table view data source
|
||||
|
||||
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
return (thisDevice?.parentDeviceType.first?.channels.count)!
|
||||
// return (thisDevice?.parentDeviceType.first?.channels.count)!
|
||||
return values.count
|
||||
}
|
||||
|
||||
|
||||
@@ -84,10 +153,34 @@ class DeviceDetailViewController: UITableViewController {
|
||||
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: "deviceDetailCell", for: indexPath) as! DeviceDetailChannelCell
|
||||
cell.channelNameLabel?.text = thisDevice?.parentDeviceType.first?.channels[indexPath.row].subTitle
|
||||
|
||||
let chanName = thisDevice?.parentDeviceType.first?.channels[indexPath.row].name
|
||||
let chanVal = thisDevice?.values.filter("name == %@", chanName!)
|
||||
let chanVal = values[chanName!]
|
||||
|
||||
if let i = changedChannelNames.index(of: chanName!) {
|
||||
changedChannelNames.remove(at: i)
|
||||
cell.backgroundColor = UIColor.flatLime()
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
|
||||
UIView.animate(withDuration: 1, animations: {
|
||||
cell.backgroundColor = UIColor.white
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if let i = updatedChannelNames.index(of: chanName!) {
|
||||
updatedChannelNames.remove(at: i)
|
||||
cell.backgroundColor = UIColor.flatYellow()
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
|
||||
UIView.animate(withDuration: 1, animations: {
|
||||
cell.backgroundColor = UIColor.white
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
cell.accessoryType = .disclosureIndicator
|
||||
cell.channelValueLabel?.text = chanVal?.first?.value
|
||||
cell.channelValueLabel?.text = chanVal?.value
|
||||
return cell
|
||||
}
|
||||
|
||||
|
||||
@@ -29,9 +29,9 @@ class DeviceListViewController: UITableViewController {
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
// self.refreshControl = UIRefreshControl()
|
||||
// refreshControl?.attributedTitle = NSAttributedString(string: "Pull to refresh")
|
||||
// refreshControl?.addTarget(self, action: #selector(refresh), for: UIControlEvents.valueChanged)
|
||||
self.refreshControl = UIRefreshControl()
|
||||
refreshControl?.attributedTitle = NSAttributedString(string: "Pull to refresh")
|
||||
refreshControl?.addTarget(self, action: #selector(refresh), for: UIControlEvents.valueChanged)
|
||||
|
||||
SVProgressHUD.show()
|
||||
firstly {
|
||||
@@ -66,21 +66,21 @@ class DeviceListViewController: UITableViewController {
|
||||
|
||||
}
|
||||
|
||||
// @objc func refresh() {
|
||||
//
|
||||
// SVProgressHUD.show()
|
||||
// self.realm.refresh()
|
||||
// firstly {
|
||||
// self.loadJSONData()
|
||||
// }.done { _ in
|
||||
// self.tableView.reloadData()
|
||||
// self.refreshControl?.endRefreshing()
|
||||
// SVProgressHUD.dismiss()
|
||||
// }.catch { error in
|
||||
// print("Error in getting data in DeviceListViewController: \(error)")
|
||||
// }
|
||||
//
|
||||
// }
|
||||
@objc func refresh() {
|
||||
|
||||
SVProgressHUD.show()
|
||||
self.realm.refresh()
|
||||
firstly {
|
||||
self.loadJSONData()
|
||||
}.done { _ in
|
||||
self.tableView.reloadData()
|
||||
self.refreshControl?.endRefreshing()
|
||||
SVProgressHUD.dismiss()
|
||||
}.catch { error in
|
||||
print("Error in getting data in DeviceListViewController: \(error)")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Table view data source
|
||||
|
||||
@@ -95,8 +95,8 @@ class DeviceListViewController: UITableViewController {
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
|
||||
let deviceTypesWithDevices = deviceTypes?.filter(deviceTypeFilter)
|
||||
return deviceTypesWithDevices?[section].vanityName ?? "Unknown"
|
||||
let deviceTypesWithDevices = deviceTypes?.filter(deviceTypeFilter)
|
||||
return ((deviceTypesWithDevices?.count)! > 0) ? deviceTypesWithDevices?[section].vanityName : "Unknown"
|
||||
}
|
||||
|
||||
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
|
||||
@@ -109,15 +109,20 @@ class DeviceListViewController: UITableViewController {
|
||||
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: "deviceListCell", for: indexPath)
|
||||
let deviceTypesWithDevices = deviceTypes?.filter(deviceTypeFilter)
|
||||
cell.textLabel?.text = deviceTypesWithDevices?[indexPath.section].devices[indexPath.row].vanityName
|
||||
cell.accessoryType = .disclosureIndicator
|
||||
if (deviceTypesWithDevices?.count)! > 0 {
|
||||
cell.textLabel?.text = deviceTypesWithDevices?[indexPath.section].devices[indexPath.row].vanityName
|
||||
cell.accessoryType = .disclosureIndicator
|
||||
}
|
||||
return cell
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||
let deviceTypesWithDevices = deviceTypes?.filter(deviceTypeFilter)
|
||||
selectedDevice = deviceTypesWithDevices?[indexPath.section].devices[indexPath.row]
|
||||
performSegue(withIdentifier: "openDeviceDetailView", sender: self)
|
||||
if let thisSection = deviceTypesWithDevices?[indexPath.section] {
|
||||
selectedDevice = thisSection.devices[indexPath.row]
|
||||
// print(selectedDevice)
|
||||
performSegue(withIdentifier: "openDeviceDetailView", sender: self)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ class LoginViewController: UIViewController {
|
||||
let encoder = PropertyListEncoder()
|
||||
|
||||
do{
|
||||
let data = try encoder.encode(user)
|
||||
let data = try encoder.encode((UIApplication.shared.delegate as! AppDelegate).user)
|
||||
try data.write(to: dataFilePath!)
|
||||
} catch {
|
||||
print("Error encoding item array, \(error)")
|
||||
|
||||
@@ -247,8 +247,7 @@ func getChannels(deviceTypeId: Int, baseURL : String, authToken : String) -> Pro
|
||||
}
|
||||
|
||||
|
||||
func getChannelValues(deviceId: Int, baseURL : String, authToken : String) -> Promise<Any> {
|
||||
let realm = try! Realm()
|
||||
func getChannelValues(deviceId: Int, baseURL : String, authToken : String) -> Promise<[String : MeshifyValue]> {
|
||||
let url = "\(baseURL)/devices/\(deviceId)/values"
|
||||
let headers : HTTPHeaders = [
|
||||
"Authorization": authToken
|
||||
@@ -261,24 +260,29 @@ func getChannelValues(deviceId: Int, baseURL : String, authToken : String) -> Pr
|
||||
|
||||
case .success:
|
||||
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)
|
||||
}
|
||||
// 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
|
||||
chv.timestamp = json["timestamp"].intValue
|
||||
valueDict[chv.name] = chv
|
||||
}
|
||||
prom.fulfill(true)
|
||||
prom.fulfill(valueDict)
|
||||
case .failure(let error):
|
||||
prom.reject(error)
|
||||
}
|
||||
@@ -286,6 +290,7 @@ func getChannelValues(deviceId: Int, baseURL : String, authToken : String) -> Pr
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func getChannelHistory(deviceId: Int, channelId : Int, baseURL : String, authToken : String) -> Promise<[ChannelHistoryValue]> {
|
||||
let url = "\(baseURL)/devices/\(deviceId)/values/\(channelId)"
|
||||
let headers : HTTPHeaders = [
|
||||
|
||||
40
pocloud/GoogleService-Info.plist
Normal file
40
pocloud/GoogleService-Info.plist
Normal file
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>AD_UNIT_ID_FOR_BANNER_TEST</key>
|
||||
<string>ca-app-pub-3940256099942544/2934735716</string>
|
||||
<key>AD_UNIT_ID_FOR_INTERSTITIAL_TEST</key>
|
||||
<string>ca-app-pub-3940256099942544/4411468910</string>
|
||||
<key>CLIENT_ID</key>
|
||||
<string>912892220088-1gkj9ms3fq60678tvgn5n1gndn7p4g9j.apps.googleusercontent.com</string>
|
||||
<key>REVERSED_CLIENT_ID</key>
|
||||
<string>com.googleusercontent.apps.912892220088-1gkj9ms3fq60678tvgn5n1gndn7p4g9j</string>
|
||||
<key>API_KEY</key>
|
||||
<string>AIzaSyCwSawi9ezxz6vqCWtPoHybsxJDkU3gh_E</string>
|
||||
<key>GCM_SENDER_ID</key>
|
||||
<string>912892220088</string>
|
||||
<key>PLIST_VERSION</key>
|
||||
<string>1</string>
|
||||
<key>BUNDLE_ID</key>
|
||||
<string>com.patrickjmcd.pocloud</string>
|
||||
<key>PROJECT_ID</key>
|
||||
<string>pocloud-ff2c9</string>
|
||||
<key>STORAGE_BUCKET</key>
|
||||
<string>pocloud-ff2c9.appspot.com</string>
|
||||
<key>IS_ADS_ENABLED</key>
|
||||
<true></true>
|
||||
<key>IS_ANALYTICS_ENABLED</key>
|
||||
<false></false>
|
||||
<key>IS_APPINVITE_ENABLED</key>
|
||||
<false></false>
|
||||
<key>IS_GCM_ENABLED</key>
|
||||
<true></true>
|
||||
<key>IS_SIGNIN_ENABLED</key>
|
||||
<true></true>
|
||||
<key>GOOGLE_APP_ID</key>
|
||||
<string>1:912892220088:ios:59660a786d897a5c</string>
|
||||
<key>DATABASE_URL</key>
|
||||
<string>https://pocloud-ff2c9.firebaseio.com</string>
|
||||
</dict>
|
||||
</plist>
|
||||
15
pocloud/Model/MeshifyValue.swift
Normal file
15
pocloud/Model/MeshifyValue.swift
Normal file
@@ -0,0 +1,15 @@
|
||||
//
|
||||
// MeshifyValue.swift
|
||||
// pocloud
|
||||
//
|
||||
// Created by Patrick McDonagh on 5/31/18.
|
||||
// Copyright © 2018 patrickjmcd. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
class MeshifyValue {
|
||||
var name : String = ""
|
||||
var value : String = ""
|
||||
var timestamp : Int = 0
|
||||
}
|
||||
@@ -644,6 +644,9 @@
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
</navigationItem>
|
||||
<refreshControl key="refreshControl" opaque="NO" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" id="WnO-fc-pmd">
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</refreshControl>
|
||||
<connections>
|
||||
<segue destination="eOb-fR-aFg" kind="show" identifier="openDeviceDetailView" id="wUb-ND-zk7"/>
|
||||
</connections>
|
||||
|
||||
Reference in New Issue
Block a user