--- tags: 2assessments, MobileApp --- # #tty1 Assessment Review (Smarthome Mobile App) > This review was performed on the solution for the Smarthome Mobile App assessment, submitted on 24 Jun 2019. > > [name=Roger So <roger@terminal1.co>] [time=25 Jun 2019]</span> ## Assessment Summary <span style="padding:10px;"> | Didn't Pass | Pass | Senior | Exceptional | |:-:|:-:|:-:|:-:| | ![skill level 0](https://i.imgur.com/vK28Pqn.png =50x) | ![skill level 1](https://i.imgur.com/7MOSoYr.png =50x) | ![skill level 2](https://i.imgur.com/ZqyUDk5.png =50x) | ![skill level 3](https://i.imgur.com/1z36KAO.png =50x) | </span> Please find [assessment grading](#assessment-grading) criteria and [problem statement](#problem-statement) at the bottom of this page. | Grade | Skill | Notes | | ------------------------------------------------------ | ------------------------------------ | --------------------------------------------------------------------------------------------------------------------- | | ![skill level 2](https://i.imgur.com/ZqyUDk5.png =50x) | iOS Platform | Uses CocoaPods for dependency management. Uses two `ViewControllers` defined using Storyboard. Uses MVVM design pattern and RxSwift. | | ![skill level 1](https://i.imgur.com/7MOSoYr.png =50x) | Algorithmic Programming | The project uses proper data structures to hold the list of rooms, which is then used to build the UI dynamically. | | ![skill level 1](https://i.imgur.com/7MOSoYr.png =50x) | UX Design and Prototyping | simple design, but not easy to see overall controls and status. | | ![skill level 2](https://i.imgur.com/ZqyUDk5.png =50x) | Object Oriented Programming | The project demonstrates some understanding of object-oriented programming and swift language extension. | | ![skill level 0](https://i.imgur.com/vK28Pqn.png =50x) | Testing, CI/CD, and Site Reliability | No unit test or integration test | ## Assessment Details ### iOS Platform Summary: Swift iOS project. Uses two`ViewController`s defined using Storyboard. MVVM architecture. - The project is written in Swift. - The project uses CocoaPods to pull in 3 dependencies: RxAlamofire, RxSwift and couchbase-lite-ios. Alamofire is commonly used package for network requests, RxSwift and RxAlamofire are commonly used for Swift MVVM. couchbase is not so common used for data persistence. - UI View Controllers are defined using storyboard. `UITableViewCell` are defined using storyboard, rather in separate Xib files. - Proper lifecycle management: UI lifecycle handled in `ViewControllers`. - Proper modularity: UI setups implemented in separated extension file `RoomListUIE.siwft` and `RoomDetailsUIE.swift`. TableView data source and delegate are implemented in separated extension files `RoomListTVE.swift` and `RoomDetailsTVE.swift`. Networking and data manipulation are implement in `ViewModels`. - Network requests are performed in the background thread by Alamofire. In the callback handler, UI updates are correctly posted back to the main thread. Threading context is managed by RX. - Asynchronous block callback doesn't use weak self, may result memory leaks. ```swift WeatherAPICalls.getWeatherInfo().subscribe(onNext: { (result) in ... self.updateData(indexes: ACDevices, onWeather: true) ... } ``` ### Algorithmic Programming Summary: The project uses proper data structures to hold the list of rooms, which is then used to build the UI dynamically. - Variable names, function names and argument labels are all logically named. - The list of rooms is not hard coded and is fetched with a CouchbaseLite query result. ```swift class RoomsDBManager: NSObject { func getRoomDocument() -> [Room] { ... return roomArray } ``` - The device list works similarly. - The Room and Devices objects are simple plain Swift objects, like typical Realm objects. - The A/C gets turned on and off according to the temperature. - It does not check the temperature periodically. It just checks temperature once when showing room details ```swift override func viewDidLoad() { super.viewDidLoad() self.setUI() self.roomDetailVM.getTemp(){ (temp) in self.TableView.reloadData() } } ``` ### Object Oriented Programming Summary: The project demonstrates some understanding of object-oriented programming. - Good UI modularity. The `ViewControllers` purely handles ViewController lifecycler. UI codes are in separated extension files `RoomListUIE.siwft` and `RoomDetailsUIE.swift`. TableView data source and delegate implementation are in separated extension files `RoomListTVE.swift` and `RoomDetailsTVE.swift`. - Network requests are implemented in different classes. `RoomAPICalls`, `DeviceAPICalls`, and `WeatherAPICalls`. ### UX Design and Prototyping Summary: simple design, but not easy to see overall controls and status. - The main screen shows the three rooms. ![](https://i.imgur.com/mf72Kmd.png) - Taps on Room, shows the room devices. ![](https://i.imgur.com/9gK8vTE.png) ### Testing, CI/CD, and Site Reliability Summary: no unit test or integration test. ## Assessment Grading This Terminal 1 assessment is a 4-8 hours offline project. It serves as a screen to ensure the candidate is above a base level of competence. Every assessment tests essential skills required for a job. Terminal 1 uses wings to represent the level of a skill. #### Skill Grading Levels Terminal 1 assigns levels to each assessed skill, which could be interpreted as a seniority level. | Level | Icon | Notes | |---|---|---| | 0 | ![skill level 0](https://i.imgur.com/vK28Pqn.png =50x) | No knowledge of the skill, everyone who attempts the challenge gets this level. | | 1 | ![skill level 1](https://i.imgur.com/7MOSoYr.png =50x) | Basic knowledge of the skill, could be awarded via online course completion or certification. Would be the main skill for junior positions. | | 2 | ![skill level 2](https://i.imgur.com/ZqyUDk5.png =50x) | Good knowledge of the skill. Approximately 200-800 hours dedicated directly to the skill mastering or 3-5 years of job experience. Only 10% of people get to this level. | | 3 | ![skill level 3](https://i.imgur.com/1z36KAO.png =50x) | Senior/Lead level with typically 5-10 years of experience. This is a high mark achieved by 3% of people. | #### Skill assessment criteria Terminal 1 uses predefined criteria to qualify candidates for every skill level. A full list of grading criteria could be found in our [library](https://www.tty1.co/skills). Each skill is assessed by categories using A-F grading system, where C is a passing grade. For example, to be awarded level 2 in "API and Service Design", a candidate needs to show the ability to 1) architect scalable solutions, including sync/async responses, web sockets, caching and 2) implement common API protocol in the assignment. ## Problem Statement Mary is excited about controlling her house electronics from her mobile device, and has turned several rooms of her house into an IoT enabled smart home. She has setup a backend infrastructure API here: http://private-1e863-house4591.apiary-mock.com/. (Please visit for the full API list). The API has the following calls: | API Call | Return value | |-|-| | /rooms | JSON format of all rooms and fixtures in the house | /:room/:fixture/on | sets the status of the fixture to "ON" and returns true | | /:room/:fixture/off | sets the status of the fixture to "OFF" and returns true | She would like you to build an iOS or Android application to turn on and off the fixtures. However, she has some expectations for requirements, listed below: ### App Functionality Create a homepage that lists all of the rooms. For each room, create a page that lists all the fixtures and their current state (on/off), as well as the ability to turn each fixture on or off. The **AC fixture** has special requirements. The application needs to ping a weather API periodically for the temperature. If the temperature is above 25°C, then the AC needs to turn on immediately if it is off. If the temperature is below 25°C, then the AC should be turned off if it is on. The AC fixture should also show the temperature from the weather API as well as the fixture's on/off status. | Weather API | URL | |-|-| | MetaWeather API for Hong Kong | (to prevent from being blocked, do not call more than once a minute) https://www.metaweather.com/api/location/2165352/ | To make it easy for you to test, the mock API also has 2 calls that return weather temperatures that turn the AC on and off (you may use them to simulate weather conditions for testing): http://private-1e863-house4591.apiary-mock.com/weather/cold ``` // returns mirrored structure of metaweather consolidated_weather: 0: the_temp: 20 ``` http://private-1e863-house4591.apiary-mock.com/weather/hot ``` // returns mirrored structure of metaweather consolidated_weather: 0: the_temp: 30 ``` #### Persistence Requirements She would like you to locally persist the data for rooms, fixtures and their state within the app. This persistence should allow the app to show the last known state of the house even if the user is offline. #### Performance Requirements She would like the UI to be seamlessly updated instantly without any blocking or lag when a state is confirmed changed. When a request is in flight (that is, request is sent but response not yet received), the user should still be able to navigate to other screens. When navigating to a room page, it should immediately show the fixtures' current state. #### Architecture Requirements She wants you to properly engineer the app and develop a solid architecture to operate these fixtures. You can use MVVM, MVC or any other architecture that you find useful, but must document it in your README. :::info **iOS Specific Instructions** For the UI, you can use either Storyboard, traditional Interface Builder, or even manually create the `UIViewController`s and laying out the `UIView`s, but you must document your choice. ::: :::info **Android Specific Instructions** You may either use multiple `Activity`s, or use a single `Activity` and multiple `Fragment`s, or some other ways of organizing the various screens, but you must document your choice. ::: #### Platform Version Requirements As of July 2018, the app should be a native app and target the following OS/SDK versions: | Platform | Name | Version | | -------- | ----------- | ------- | | Android | `minSdkVersion` | 23 | | Android | `targetSdkVersion` | 27 | | iOS | iOS Deployment Target | iOS 9 | | iOS | Base SDK | iOS 11.4 | ### Mock-API Details and Assumptions For this assessment, we are using a simple mocking API service with no actual state stored on the server. For simplicity, you may assume all fixtures start off as "OFF" when the app is first run, and that no other changes to the fixtures occur unless the app initiates it. The API doesn't care for the state of the fixture, it just sets the state and returns true on success.