Smart Home App
In this project, I made app for practice JSON parsing for IOS application. In this project I made my own backend service with Heroku and Node.js . Backend side is very simple only send random variable for mobile application. You can find all files and videos in here.
Backend | Node.js
I create simple backend (API) for this example SmartHome Application. I use Node.js for developing. This backend send the json for each specific query. You can download full code in here. This backend don’t have storage system such as MongoDB. I developt this backend for my specific query. Also I deploy this backend on Heroku (http://fathomless-stream-95255.herokuapp.com). You can test with Postman and even you can use this for your example project.
Bellow code shows index.js
Index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
const express = require('express'); const app = express(); const morgan = require('morgan'); const bodyParser = require('body-parser'); const productRoutes = require('./api/routes/product'); const ordersRoutes = require('./api/routes/orders'); const PORT = process.env.PORT || 5000 app.use(morgan('dev')); app.use(bodyParser.urlencoded({extended: false})); app.use(bodyParser.json()); app.use('/rooms', productRoutes); app.use('/login', ordersRoutes); app.use((req, res, next) => { const error = new Error('Not found'); error.status = 404; next(error); }) app.use((error, req, res, next) => { res.status(error.status || 500); res.json({ error: { message: error.message } }); }); app.listen(PORT, () => console.log(`Listening on ${ PORT }`)) |
This snippet code shows my login page activity. if user use this routes /login/:username/:password this code works
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
router.get('/:username/:password', (req, res, next) => { const username = req.params.username; const password = req.params.password; console.log(username); if ((username == "Cemalettin") && (password == "12345") ){ res.status(200).json({ userID: "1", rooms: ["livingroom", "bathroom","bedroom","kitchen","garden","saloon","babyroom","balcony"] }); } else if ((username == "Mehmet") && (password == "123456") ){ res.status(200).json({ userID: "2", rooms: ["garden", "bathroom","bedroom","kitchen","saloon","livingroom","babyroom","balcony"] }); } else { res.status(200).json({ userID: "0" }); } }); |
After that each rooms and sensor variable get with /rooms/:userid/:roomid . Bellow code is not perfect. I don’t prefer to use it. However you can learn concept how to work API
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
const express = require('express'); const router = express.Router(); console.log("tesst"); router.get('/:userID', (req, res, next) => { const user_id = req.params.userID; if (user_id == "1") res.status(200).json({ rooms: ["Livingroom", "Bathroom","Bedroom","Kitchen","Garden","Saloon","Babyroom","Balcony"], roomsicon: ["livingroom", "bathroom","bedroom","kitchen","garden","saloon","babyroom","balcony"] }); if (user_id == "2") res.status(200).json({ rooms: ["Garden", "Bathroom","Bedroom","Kitchen","Saloon","Livingroom","Babyroom","Balcony"], roomsicon: ["garden", "bathroom","bedroom","kitchen","saloon","livingroom","babyroom","balcony"] }); }); router.post('/', (req, res, next) => { res.status(201).json({ message: 'Handling Get requests to /products' }); }); router.get('/:userID/:productId', (req, res, next) =>{ const room_id = req.params.productId; const user_id = req.params.userID; if(Math.random() >= 0.5){ lights = "On" } else{ lights = "Off" } if(Math.random() >= 0.5){ movement = "Detected" } else{ movement = "Not-Detected" } if(Math.random() >= 0.5){ gas = "Gas" } else{ gas = "Okey" } if(user_id == '1'){ if (room_id === 'Livingroom'){ res.status(200).json({ SensorNames: ["Temperature", "Humidity","Lights","Movement"], SensorIcon: ["temperature", "humidity",lights,movement], SensorValues: [parseFloat(Math.random() * (27 - 25) + 25).toPrecision(3), parseFloat(Math.random() * (60 - 50) + 50).toPrecision(3),lights,movement] }); } else if (room_id === 'Bedroom'){ res.status(200).json({ SensorNames: ["Temperature", "Humidity","Lights","Movement"], SensorIcon: ["temperature", "humidity",lights,movement], SensorValues: [parseFloat(Math.random() * (27 - 25) + 25).toPrecision(3), parseFloat(Math.random() * (60 - 50) + 50).toPrecision(3),lights,movement] }); } else if (room_id === 'Kitchen'){ res.status(200).json({ SensorNames: ["Temperature", "Humidity","Lights","Gas"], SensorIcon: ["temperature", "humidity",lights,gas], SensorValues: [parseFloat(Math.random() * (27 - 25) + 25).toPrecision(3), parseFloat(Math.random() * (60 - 50) + 50).toPrecision(3),lights,gas] }); } else if (room_id === 'Bathroom'){ res.status(200).json({ SensorNames: ["Temperature", "Humidity","Lights","Gas"], SensorIcon: ["temperature", "humidity",lights,gas], SensorValues: [parseFloat(Math.random() * (27 - 25) + 25).toPrecision(3), parseFloat(Math.random() * (60 - 50) + 50).toPrecision(3),lights,gas] }); } else if (room_id === 'Saloon'){ res.status(200).json({ SensorNames: ["Temperature", "Humidity","Lights","Movement"], SensorIcon: ["temperature", "humidity",lights,movement], SensorValues: [parseFloat(Math.random() * (27 - 25) + 25).toPrecision(3), parseFloat(Math.random() * (60 - 50) + 50).toPrecision(3),lights,movement] }); } else if (room_id === 'Babyroom'){ res.status(200).json({ SensorNames: ["Temperature", "Humidity","Lights","Movement"], SensorIcon: ["temperature", "humidity",lights,movement], SensorValues: [parseFloat(Math.random() * (27 - 25) + 25).toPrecision(3), parseFloat(Math.random() * (60 - 50) + 50).toPrecision(3),lights,movement] }); } else if (room_id === 'Garden'){ res.status(200).json({ SensorNames: ["Temperature", "Humidity","Lights","Movement"], SensorIcon: ["temperature", "humidity",lights,movement], SensorValues: [parseFloat(Math.random() * (27 - 25) + 25).toPrecision(3), parseFloat(Math.random() * (60 - 50) + 50).toPrecision(3),lights,movement] }); } else if (room_id === 'Balcony'){ res.status(200).json({ SensorNames: ["Temperature", "Humidity","Lights","Movement"], SensorIcon: ["temperature", "humidity",lights,movement], SensorValues: [parseFloat(Math.random() * (27 - 25) + 25).toPrecision(3), parseFloat(Math.random() * (60 - 50) + 50).toPrecision(3),lights,movement] }); } else { res.status(200).json({ message: 'You passed an ID' }); } } if(user_id == '2'){ if (room_id === 'Livingroom'){ res.status(200).json({ SensorNames: ["Temperature", "Humidity","Lights","Movement"], SensorIcon: ["temperature", "humidity",lights,movement], SensorValues: [parseFloat(Math.random() * (27 - 25) + 25).toPrecision(3), parseFloat(Math.random() * (60 - 50) + 50).toPrecision(3),lights,movement] }); } else if (room_id === 'Bedroom'){ res.status(200).json({ SensorNames: ["Temperature", "Humidity","Lights","Movement"], SensorIcon: ["temperature", "humidity",lights,movement], SensorValues: [parseFloat(Math.random() * (27 - 25) + 25).toPrecision(3), parseFloat(Math.random() * (60 - 50) + 50).toPrecision(3),lights,movement] }); } else if (room_id === 'Kitchen'){ res.status(200).json({ SensorNames: ["Temperature", "Humidity","Lights","Gas"], SensorIcon: ["temperature", "humidity",lights,gas], SensorValues: [parseFloat(Math.random() * (27 - 25) + 25).toPrecision(3), parseFloat(Math.random() * (60 - 50) + 50).toPrecision(3),lights,gas] }); } else if (room_id === 'Bathroom'){ res.status(200).json({ SensorNames: ["Temperature", "Humidity","Lights","Gas"], SensorIcon: ["temperature", "humidity",lights,gas], SensorValues: [parseFloat(Math.random() * (27 - 25) + 25).toPrecision(3), parseFloat(Math.random() * (60 - 50) + 50).toPrecision(3),lights,gas] }); } else if (room_id === 'Saloon'){ res.status(200).json({ SensorNames: ["Temperature", "Humidity","Lights","Movement"], SensorIcon: ["temperature", "humidity",lights,movement], SensorValues: [parseFloat(Math.random() * (27 - 25) + 25).toPrecision(3), parseFloat(Math.random() * (60 - 50) + 50).toPrecision(3),lights,movement] }); } else if (room_id === 'Babyroom'){ res.status(200).json({ SensorNames: ["Temperature", "Humidity","Lights","Movement"], SensorIcon: ["temperature", "humidity",lights,movement], SensorValues: [parseFloat(Math.random() * (27 - 25) + 25).toPrecision(3), parseFloat(Math.random() * (60 - 50) + 50).toPrecision(3),lights,movement] }); } else if (room_id === 'Garden'){ res.status(200).json({ SensorNames: ["Temperature", "Humidity","Lights","Movement"], SensorIcon: ["temperature", "humidity",lights,movement], SensorValues: [parseFloat(Math.random() * (27 - 25) + 25).toPrecision(3), parseFloat(Math.random() * (60 - 50) + 50).toPrecision(3),lights,movement] }); } else if (room_id === 'Balcony'){ res.status(200).json({ SensorNames: ["Temperature", "Humidity","Lights","Movement"], SensorIcon: ["temperature", "humidity",lights,movement], SensorValues: [parseFloat(Math.random() * (27 - 25) + 25).toPrecision(3), parseFloat(Math.random() * (60 - 50) + 50).toPrecision(3),lights,movement] }); } else { res.status(200).json({ message: 'You passed an ID' }); } } }); router.patch('/:productId', (req, res, next) => { res.status(200).json({ message: 'Updated' }); }); router.delete('/:productId', (req, res, next) => { res.status(200).json({ message: 'Deleted product' }); }); module.exports = router; |
Ios Mobile App | Swift
Bellow picture shows the main storyboard. Application have 3 page which are, login, rooms and roomsdetails pages.
Firstly I created models
userModel.swift
1 2 3 4 |
import Foundation struct userModel : Codable { let userID : String } |
roomModel.swift
1 2 3 4 5 |
import Foundation struct roomModel : Decodable { let rooms : [String] let roomsicon : [String] } |
sensorsModel.swift
1 2 3 4 5 6 |
import Foundation struct sensorsModel : Decodable { let SensorNames : [String] let SensorValues : [String] let SensorIcon : [String] } |
currentUser.swift
I create this model for hold the current user in phone memory. I mean, when user close application and start to application again application regonize the current user and doesn’t want to login again.
1 2 3 4 |
import Foundation struct userModel : Codable { let userID : String } |
webService.swift
1 2 3 4 |
import Foundation struct webService{ static var baseURL = "http://fathomless-stream-95255.herokuapp.com" } |
After that I create ViewControllers codes.
LoginViewController.swift
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
// // ViewController.swift // smartHome // // Created by Cemalettin Yılmaz on 10.12.2018. // Copyright © 2018 Cemalettin Yılmaz. All rights reserved. // import UIKit import MaterialComponents.MaterialTextFields import MaterialComponents.MaterialButtons //extension ViewController: WebServiceDelegate{ // func login(Username: String, Password: String) -> userModel { // userID = userModel.i // } //} class LoginViewController: UIViewController { @IBOutlet weak var warningLabel: UILabel! @IBOutlet weak var LoginButton: MDCButton! @IBOutlet weak var Username: MDCTextField! @IBOutlet weak var Password: MDCTextField! public var usernameTextFieldController: MDCTextInputControllerOutlined! public var passwordTextFieldController: MDCTextInputControllerOutlined! var userID : String? override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) Username.text = nil Password.text = nil warningLabel.text = nil } override func viewDidLoad() { super.viewDidLoad() hideKeyboardOnTap() NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil) Username.placeholder = "Username" Password.placeholder = "Password" usernameTextFieldController = MDCTextInputControllerOutlined.init(textInput: Username) usernameTextFieldController.isFloatingEnabled = true passwordTextFieldController = MDCTextInputControllerOutlined.init(textInput: Password) passwordTextFieldController.isFloatingEnabled = true Username.autocorrectionType = .no Password.autocorrectionType = .no LoginButton.layer.cornerRadius = 10 } @IBAction func loginPressed(_ sender: Any) { guard let name = Username.text else { warningLabel.text = "Invalid username or password" return} guard let pass = Password.text else { warningLabel.text = "Invalid username or password" return} if name.count == 0 { warningLabel.text = "Invalid username or password" return} if pass.count == 0 { warningLabel.text = "Invalid username or password" return} let sv = UIViewController.displaySpinner(onView: self.view) // let loggedUser = ws?.login(Username: name, Password: pass) let baseURL = webService.baseURL let targetURL = "\(baseURL)/login/\(name)/\(pass)" let target = URL(string: targetURL) guard let url = target else {return} let task = URLSession.shared.dataTask(with: url) { (data, response, error) in DispatchQueue.main.async { let decoder = JSONDecoder() let user = try! decoder.decode(userModel.self, from: data!) if user.userID != "0" { currentUser.userID = user.userID self.performSegue(withIdentifier: "login", sender: nil) } else { UIViewController.removeSpinner(spinner: sv) self.warningLabel.text = "Invalid username or password" } } } task.resume() } public func hideKeyboardOnTap() { let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.hideKeyboard)) tap.cancelsTouchesInView = false view.addGestureRecognizer(tap) } @objc public func hideKeyboard() { view.endEditing(true) } @objc func keyboardWillShow(notification: NSNotification) { if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue { if self.view.frame.origin.y == 0 { self.view.frame.origin.y -= keyboardSize.height } } } @objc func keyboardWillHide(notification: NSNotification) { if self.view.frame.origin.y != 0 { self.view.frame.origin.y = 0 } } } extension UIViewController { class func displaySpinner(onView : UIView) -> UIView { let spinnerView = UIView.init(frame: onView.bounds) spinnerView.backgroundColor = UIColor.init(red: 0.5, green: 0.5, blue: 0.5, alpha: 0.5) let ai = UIActivityIndicatorView.init(style: .whiteLarge) ai.startAnimating() ai.center = spinnerView.center DispatchQueue.main.async { spinnerView.addSubview(ai) onView.addSubview(spinnerView) } return spinnerView } class func removeSpinner(spinner :UIView) { DispatchQueue.main.async { spinner.removeFromSuperview() } } } |
RoomsViewController.swift
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
// // MyCollectionViewController.swift // tableViewExample // // Created by Cemalettin Yılmaz on 10.12.2018. // Copyright © 2018 Cemalettin Yilmaz. All rights reserved. // import UIKit extension RoomsViewController : UIScrollViewDelegate { func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) { if Int(targetContentOffset.pointee.y)%collectionCellHeight > collectionCellHeight/2 { targetContentOffset.pointee.y = CGFloat(collectionCellHeight*(Int(targetContentOffset.pointee.y)/collectionCellHeight + 1)) } else { targetContentOffset.pointee.y = CGFloat(collectionCellHeight*(Int(targetContentOffset.pointee.y)/collectionCellHeight)) } } } extension RoomsViewController : UICollectionViewDataSource, UICollectionViewDelegateFlowLayout { func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return rooms.count } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let myCell = collectionView.dequeueReusableCell(withReuseIdentifier: "MyCollectionCell", for: indexPath) as! RoomCollectionViewCell myCell.nameLabel.text = rooms[indexPath.row] myCell.collectionViewCellImage.image = UIImage(named: roomsicon[indexPath.row]) myCell.layer.cornerRadius = 10 return myCell } func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { let screenWidth = self.view.frame.size.width let screenHeight = self.view.frame.size.height return CGSize(width: screenWidth/2 - 30, height: screenHeight/3) } } class RoomsViewController: UIViewController { var collectionCellHeight = 100 @IBOutlet weak var myCollectionView: UICollectionView! var rooms : [String] = [] var roomsicon : [String] = [] override func viewDidLoad() { super.viewDidLoad() getRoomNames(userID: currentUser.userID) collectionCellHeight = Int(view.frame.size.height/3 + 5) } func getRoomNames(userID : String){ let baseURL = webService.baseURL let targetURL = "\(baseURL)/rooms/\(userID)" let target = URL(string: targetURL) guard let url = target else {return} let task = URLSession.shared.dataTask(with: url) { (data, response, error) in DispatchQueue.main.async { let decoder = JSONDecoder() let myRoomModel = try! decoder.decode(roomModel.self, from: data!) self.rooms = myRoomModel.rooms self.roomsicon = myRoomModel.roomsicon self.myCollectionView.reloadData() } } task.resume() } @IBAction func logoutButtonPressed(_ sender: Any) { currentUser.userID = "0" let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! let archiveURL = documentsDirectory.appendingPathComponent("userID") .appendingPathExtension("plist") let propertyListEncoder = PropertyListEncoder() var ucs = userModel(userID: "0") let encodedNote = try? propertyListEncoder.encode(ucs) try? encodedNote?.write(to: archiveURL, options: .noFileProtection) self.performSegue(withIdentifier: "logout", sender: nil) } 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. guard segue.identifier == "toRoomDetail" else {return} let cell = sender as! RoomCollectionViewCell let indexPath = myCollectionView.indexPath(for: cell) let selectedRoom = rooms[indexPath!.row] let detailViewController = segue.destination as! RoomDetailViewController detailViewController.currentRoom = selectedRoom } } |
RoomDetailViewController.swift
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
// // PostDetailViewController.swift // smartHome // // Created by Cemalettin Yılmaz on 10.12.2018. // Copyright © 2018 Cemalettin Yılmaz. All rights reserved. // import UIKit extension RoomDetailViewController : UIScrollViewDelegate { func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) { if Int(targetContentOffset.pointee.y)%tableViewCellRowHeight > tableViewCellRowHeight/2 { targetContentOffset.pointee.y = CGFloat(tableViewCellRowHeight*(Int(targetContentOffset.pointee.y)/tableViewCellRowHeight + 1)) } else { targetContentOffset.pointee.y = CGFloat(tableViewCellRowHeight*(Int(targetContentOffset.pointee.y)/tableViewCellRowHeight)) } } } extension RoomDetailViewController : UITableViewDataSource { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return mySensors?.SensorNames.count ?? 0 } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let myCell = tableView.dequeueReusableCell(withIdentifier: "sensorCell") as! SensorTableViewCell myCell.sensorName.text = mySensors?.SensorNames[indexPath.row] myCell.sensorValue.text = mySensors?.SensorValues[indexPath.row] myCell.sensorImage.image = UIImage(named: (mySensors?.SensorIcon[indexPath.row])!) return myCell } // func tableV } class RoomDetailViewController: UIViewController { @IBOutlet weak var myTableView: UITableView! var mySensors : sensorsModel? var currentRoom : String? var tableViewCellRowHeight = 150 override func viewDidLoad() { super.viewDidLoad() navigationItem.title = currentRoom getSensors(roomName: currentRoom!, userID: currentUser.userID) // Do any additional setup after loading the view. } func getSensors(roomName : String , userID : String){ let baseURL = webService.baseURL let targetURL = "\(baseURL)/rooms/\(userID)/\(roomName)" let target = URL(string: targetURL) guard let url = target else {return} let task = URLSession.shared.dataTask(with: url) { (data, response, error) in DispatchQueue.main.async { let decoder = JSONDecoder() self.mySensors = try! decoder.decode(sensorsModel.self, from: data!) self.myTableView.reloadData() } } task.resume() } } |
After that I create collection controllers
RoomCollectionViewCell.swift
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
// // RoomCollectionViewCell.swift // smartHome // // Created by Cemalettin Yılmaz on 10.12.2018. // Copyright © 2018 Cemalettin Yılmaz. All rights reserved. // import UIKit class RoomCollectionViewCell: UICollectionViewCell { @IBOutlet weak var collectionViewCellImage: UIImageView! @IBOutlet weak var nameLabel: UILabel! override func awakeFromNib() { super.awakeFromNib() collectionViewCellImage.layer.cornerRadius = 20 // Initialization code } } |
SensorTableViewCell.swift
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
// // SensorTableViewCell.swift // smartHome // // Created by Cemalettin Yılmaz on 10.12.2018. // Copyright © 2018 Cemalettin Yılmaz. All rights reserved. // import UIKit class SensorTableViewCell: UITableViewCell { @IBOutlet weak var sensorImage: UIImageView! @IBOutlet weak var sensorName: UILabel! @IBOutlet weak var sensorValue: UILabel! 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 } } |
Also I added in Delegate code for saving current user id.
AppDelegate.swift
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
// // AppDelegate.swift // smartHome // // Created by Cemalettin Yılmaz on 10.12.2018. // Copyright © 2018 Cemalettin Yılmaz. All rights reserved. // import UIKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { let propertyListDecoder = PropertyListDecoder() let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! let archiveURL = documentsDirectory.appendingPathComponent("userID") .appendingPathExtension("plist") if let retrievedNoteData = try? Data(contentsOf: archiveURL),let decodedNote = try? propertyListDecoder.decode(userModel.self,from: retrievedNoteData) { if decodedNote.userID == "0" { return true } else { let storyboard = UIStoryboard.init(name: "Main", bundle: nil) currentUser.userID = decodedNote.userID self.window!.rootViewController = storyboard.instantiateViewController(withIdentifier: "navController") } } return true } func applicationWillResignActive(_ application: UIApplication) { // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. } func applicationDidEnterBackground(_ application: UIApplication) { // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. } func applicationWillEnterForeground(_ application: UIApplication) { // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. } func applicationDidBecomeActive(_ application: UIApplication) { // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. } func applicationWillTerminate(_ application: UIApplication) { let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! let archiveURL = documentsDirectory.appendingPathComponent("userID") .appendingPathExtension("plist") let propertyListEncoder = PropertyListEncoder() var current = userModel(userID: currentUser.userID) let encodedNote = try? propertyListEncoder.encode(current) try? encodedNote?.write(to: archiveURL, options: .noFileProtection) // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. } } |