Skip to content

Commit

Permalink
Merge branch 'version/2.0_bug_fix' into 'master'
Browse files Browse the repository at this point in the history
iOS RainMaker App v2.0.1.

See merge request app-frameworks/esp-rainmaker-ios!7
  • Loading branch information
shahpiyushv committed Jun 12, 2020
2 parents 56f5a40 + dfa0b96 commit d41c6a5
Show file tree
Hide file tree
Showing 23 changed files with 266 additions and 573 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1 @@
ESPRainMaker/Pods
ESPRainMaker/Pods
65 changes: 40 additions & 25 deletions ESPRainMaker/ESPRainMaker.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

30 changes: 20 additions & 10 deletions ESPRainMaker/ESPRainMaker/AWSCognito/DeviceAssociation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,19 @@ import ESPProvision
import Foundation
import SwiftProtobuf

enum AssociationError: Error {
case runtimeError(String)

var description: String {
switch self {
case let .runtimeError(message):
return message
}
}
}

protocol DeviceAssociationProtocol {
func deviceAssociationFinishedWith(success: Bool, nodeID: String?)
func deviceAssociationFinishedWith(success: Bool, nodeID: String?, error: AssociationError?)
}

class DeviceAssociation {
Expand Down Expand Up @@ -51,16 +62,16 @@ class DeviceAssociation {
if let data = payloadData {
device.sendData(path: Constants.associationPath, data: data) { response, error in
guard error == nil, response != nil else {
self.delegate?.deviceAssociationFinishedWith(success: false, nodeID: nil)
self.delegate?.deviceAssociationFinishedWith(success: false, nodeID: nil, error: AssociationError.runtimeError(error!.localizedDescription))
return
}
self.processResponse(responseData: response!)
}
} else {
delegate?.deviceAssociationFinishedWith(success: false, nodeID: nil)
delegate?.deviceAssociationFinishedWith(success: false, nodeID: nil, error: AssociationError.runtimeError("Unable to fetch request payload."))
}
} catch {
delegate?.deviceAssociationFinishedWith(success: false, nodeID: nil)
delegate?.deviceAssociationFinishedWith(success: false, nodeID: nil, error: AssociationError.runtimeError("Unable to fetch request payload."))
}
}

Expand All @@ -70,16 +81,15 @@ class DeviceAssociation {
/// - Parameters:
/// - responseData: Response recieved from device after sending mapping payload
func processResponse(responseData: Data) {
let decryptedResponse = (device.securityLayer.decrypt(data: responseData))!
do {
let response = try Rainmaker_RMakerConfigPayload(serializedData: decryptedResponse)
let response = try Rainmaker_RMakerConfigPayload(serializedData: responseData)
if response.respSetUserMapping.status == .success {
delegate?.deviceAssociationFinishedWith(success: true, nodeID: response.respSetUserMapping.nodeID)
delegate?.deviceAssociationFinishedWith(success: true, nodeID: response.respSetUserMapping.nodeID, error: nil)
} else {
delegate?.deviceAssociationFinishedWith(success: false, nodeID: nil)
delegate?.deviceAssociationFinishedWith(success: false, nodeID: nil, error: AssociationError.runtimeError("User node mapping failed."))
}
} catch {
delegate?.deviceAssociationFinishedWith(success: false, nodeID: nil)
delegate?.deviceAssociationFinishedWith(success: false, nodeID: nil, error: AssociationError.runtimeError(error.localizedDescription))
}
}

Expand All @@ -93,6 +103,6 @@ class DeviceAssociation {
var payload = Rainmaker_RMakerConfigPayload()
payload.msg = Rainmaker_RMakerConfigMsgType.typeCmdSetUserMapping
payload.cmdSetUserMapping = configRequest
return try device.securityLayer.encrypt(data: payload.serializedData())
return try payload.serializedData()
}
}
51 changes: 36 additions & 15 deletions ESPRainMaker/ESPRainMaker/Base.lproj/Login.storyboard

Large diffs are not rendered by default.

123 changes: 61 additions & 62 deletions ESPRainMaker/ESPRainMaker/Base.lproj/Main.storyboard

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions ESPRainMaker/ESPRainMaker/ESPRainMaker-Bridging-Header.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@

#import <CommonCrypto/CommonDigest.h>
#import "AESDecryptor.h"
#import "GitVersion.h"
24 changes: 24 additions & 0 deletions ESPRainMaker/ESPRainMaker/Interface/DocumentViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,38 @@ import WebKit
class DocumentViewController: UIViewController {
var documentLink: String!
@IBOutlet var webView: WKWebView!
@IBOutlet var backButton: UIButton!

override func viewDidLoad() {
super.viewDidLoad()
webView.navigationDelegate = self
webView.load(URLRequest(url: URL(string: documentLink)!))
// Do any additional setup after loading the view.
}

@IBAction func backButtonPressed(_: Any) {
webView.goBack()
}

@IBAction func closeWebView(_: Any) {
dismiss(animated: true, completion: nil)
}
}

extension DocumentViewController: WKNavigationDelegate {
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
if navigationAction.navigationType == .linkActivated {
guard let url = navigationAction.request.url else { return }
webView.load(URLRequest(url: url))
}
decisionHandler(.allow)
}

func webView(_ webView: WKWebView, didFinish _: WKNavigation!) {
if webView.canGoBack {
backButton.isHidden = false
} else {
backButton.isHidden = true
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ class ClaimViewController: UIViewController {
case let .failedToConnect(error):
DispatchQueue.main.async {
let action = UIAlertAction(title: "Retry", style: .default, handler: nil)
self.showAlert(error: error.description, action: action)
self.showAlert(error: error.description + "\nCheck if POP is correct.", action: action)
}
default:
DispatchQueue.main.async {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,10 @@ class ProvisionViewController: UIViewController {
device.scanWifiList { wifiList, _ in
DispatchQueue.main.async {
self.tableView.isHidden = false
self.headerView.isHidden = false
Utility.hideLoader(view: self.view)
if wifiList != nil {
self.wifiDetailList = wifiList!
if let list = wifiList {
self.wifiDetailList = list.sorted { $0.rssi > $1.rssi }
}
self.tableView.reloadData()
}
Expand Down Expand Up @@ -333,16 +334,23 @@ extension ProvisionViewController: UITableViewDataSource {
}

extension ProvisionViewController: DeviceAssociationProtocol {
func deviceAssociationFinishedWith(success: Bool, nodeID: String?) {
func deviceAssociationFinishedWith(success: Bool, nodeID: String?, error: AssociationError?) {
User.shared.currentAssociationInfo!.associationInfoDelievered = success
DispatchQueue.main.async {
Utility.hideLoader(view: self.view)
}
if success {
if let deviceSecret = nodeID {
User.shared.currentAssociationInfo!.nodeID = deviceSecret
if success {
if let deviceSecret = nodeID {
User.shared.currentAssociationInfo!.nodeID = deviceSecret
}
self.showStatusScreen()
} else {
let alertController = UIAlertController(title: "Error", message: error?.description, preferredStyle: .alert)
let action = UIAlertAction(title: "Ok", style: .default) { _ in
self.navigationController?.popToRootViewController(animated: false)
}
alertController.addAction(action)
self.present(alertController, animated: true, completion: nil)
}
showStatusScreen()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,20 @@ class SuccessViewController: UIViewController {
espDevice.provision(ssid: ssid, passPhrase: passphrase) { status in
switch status {
case .success:
self.step2applyConfigurations()
self.step3SendRequestToAddDevice()
case let .failure(error):
self.step1FailedWithMessage(message: error.description)
switch error {
case .configurationError:
self.step1FailedWithMessage(message: "Failed to apply network configuration to device")
case .sessionError:
self.step1FailedWithMessage(message: "Session is not established")
case .wifiStatusDisconnected:
self.step3SendRequestToAddDevice()
default:
self.step2FailedWithMessage(error: error)
}
case .configApplied:
self.step2applyConfigurations()
}
}
}
Expand All @@ -81,19 +92,20 @@ class SuccessViewController: UIViewController {
self.step2Image.isHidden = true
self.step2Indicator.isHidden = false
self.step2Indicator.startAnimating()
self.step2Indicator.stopAnimating()
self.step2Image.image = UIImage(named: "checkbox_checked")
self.step2Image.isHidden = false
self.step3SendRequestToAddDevice()
}
}

private func step3SendRequestToAddDevice() {
step3Image.isHidden = true
step3Indicator.isHidden = false
step3Indicator.startAnimating()
count = 5
sendRequestToAddDevice()
DispatchQueue.main.async {
self.step2Indicator.stopAnimating()
self.step2Image.image = UIImage(named: "checkbox_checked")
self.step2Image.isHidden = false
self.step3Image.isHidden = true
self.step3Indicator.isHidden = false
self.step3Indicator.startAnimating()
self.count = 5
self.sendRequestToAddDevice()
}
}

private func step4ConfirmNodeAssociation(requestID: String) {
Expand Down Expand Up @@ -150,12 +162,21 @@ class SuccessViewController: UIViewController {
}
}

func step2FailedWithMessage(message: String) {
func step2FailedWithMessage(error: ESPProvisionError) {
DispatchQueue.main.async {
self.step2Indicator.stopAnimating()
self.step2Image.image = UIImage(named: "error_icon")
self.step2Image.isHidden = false
self.step2ErrorLabel.text = message
var errorMessage = ""
switch error {
case .wifiStatusUnknownError, .wifiStatusDisconnected, .wifiStatusNetworkNotFound, .wifiStatusAuthenticationError:
errorMessage = error.description
case .wifiStatusError:
errorMessage = "Unable to fetch Wi-Fi state."
default:
errorMessage = "Unknown error."
}
self.step2ErrorLabel.text = errorMessage
self.step2ErrorLabel.isHidden = false
self.provisionFinsihedWithStatus(message: "Reset your board to factory defaults and retry.")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class SettingsPageViewController: UIViewController {

emailLabel.text = User.shared.userInfo.email
NotificationCenter.default.addObserver(self, selector: #selector(updateUIView), name: Notification.Name(Constants.uiViewUpdateNotification), object: nil)
appVersionLabel.text = "App Version - v" + Constants.appVersion
appVersionLabel.text = "App Version - v" + Constants.appVersion + " (\(GIT_SHA_VERSION))"
}

override func viewDidLayoutSubviews() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ class SignInViewController: UIViewController, AWSCognitoAuthDelegate {
@IBOutlet var checkBox: UIButton!
@IBOutlet var signInTopSpace: NSLayoutConstraint!
@IBOutlet var signUpTopView: NSLayoutConstraint!
@IBOutlet var signInButton: PrimaryButton!
@IBOutlet var username: UITextField!
@IBOutlet var signUpButton: PrimaryButton!
@IBOutlet var password: UITextField!
@IBOutlet var topView: UIView!
@IBOutlet var signUpView: UIView!
Expand All @@ -36,6 +38,7 @@ class SignInViewController: UIViewController, AWSCognitoAuthDelegate {
@IBOutlet var githubLoginButton: UIButton!
@IBOutlet var googleLoginButton: UIButton!
@IBOutlet var appleLoginButton: UIButton!
@IBOutlet var appVersionLabel: UILabel!
// let passwordButtonRightView = UIButton(frame: CGRect(x: 0, y: 0, width: 22.0, height: 16.0))

var pool: AWSCognitoIdentityUserPool?
Expand Down Expand Up @@ -80,7 +83,6 @@ class SignInViewController: UIViewController, AWSCognitoAuthDelegate {
googleLoginButton.layer.shadowOpacity = 0.5
googleLoginButton.layer.masksToBounds = false

// appleLoginButton.layer.backgroundColor = UIColor.lightGray.cgColor
appleLoginButton.layer.shadowColor = UIColor.lightGray.cgColor
appleLoginButton.layer.shadowOffset = CGSize(width: 0.5, height: 1.0)
appleLoginButton.layer.shadowRadius = 0.5
Expand Down Expand Up @@ -142,6 +144,7 @@ class SignInViewController: UIViewController, AWSCognitoAuthDelegate {
// Fallback on earlier versions
}
segmentControl.addUnderlineForSelectedSegment()
appVersionLabel.text = "App Version - v" + Constants.appVersion + " (\(GIT_SHA_VERSION))"
}

override func viewDidLayoutSubviews() {
Expand Down Expand Up @@ -253,6 +256,7 @@ class SignInViewController: UIViewController, AWSCognitoAuthDelegate {

@IBAction func signInPressed(_: AnyObject) {
dismissKeyboard()
signInButton.isEnabled = false
if Utility.isConnected(view: view) {
guard let usernameValue = username.text, !usernameValue.isEmpty, let password = password.text, !password.isEmpty else {
let alertController = UIAlertController(title: "Missing information",
Expand All @@ -261,6 +265,7 @@ class SignInViewController: UIViewController, AWSCognitoAuthDelegate {
let retryAction = UIAlertAction(title: "Retry", style: .default, handler: nil)
alertController.addAction(retryAction)
present(alertController, animated: true, completion: nil)
signInButton.isEnabled = true
return
}
signIn(username: usernameValue, password: password)
Expand Down Expand Up @@ -320,6 +325,7 @@ class SignInViewController: UIViewController, AWSCognitoAuthDelegate {
present(alertController, animated: true, completion: nil)
return
}
signUpButton.isEnabled = false
Utility.showLoader(message: "", view: view)

var attributes = [AWSCognitoIdentityUserAttributeType]()
Expand All @@ -336,6 +342,7 @@ class SignInViewController: UIViewController, AWSCognitoAuthDelegate {
guard let strongSelf = self else { return nil }
DispatchQueue.main.async {
Utility.hideLoader(view: strongSelf.view)
strongSelf.signUpButton.isEnabled = true
if let error = task.error as NSError? {
let alertController = UIAlertController(title: error.userInfo["__type"] as? String,
message: error.userInfo["message"] as? String,
Expand Down Expand Up @@ -471,6 +478,7 @@ extension SignInViewController: AWSCognitoIdentityPasswordAuthentication {
public func didCompleteStepWithError(_ error: Error?) {
DispatchQueue.main.async {
Utility.hideLoader(view: self.view)
self.signInButton.isEnabled = true
if let error = error as NSError? {
if error.code == 33 {
self.resendConfirmationCode()
Expand Down
29 changes: 1 addition & 28 deletions ESPRainMaker/ESPRainMaker/Models/Attribute.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,39 +18,12 @@

import Foundation

class Attribute: Equatable {
class Attribute {
var name: String?
var value: Any?

static func == (lhs: Attribute, rhs: Attribute) -> Bool {
let lhsValue = lhs.value as? String
let rhsValue = rhs.value as? String
return lhsValue == rhsValue && lhs.name == rhs.name
}
}

class Param: Attribute {
static func == (lhs: Param, rhs: Param) -> Bool {
if lhs.name == rhs.name {
if lhs.dataType == rhs.dataType {
if lhs.dataType?.lowercased() == "int" {
let lhsValue = lhs.value as? Int
let rhsValue = rhs.value as? Int
return lhsValue == rhsValue
} else if lhs.dataType?.lowercased() == "float" {
let lhsValue = lhs.value as? Float
let rhsValue = rhs.value as? Float
return lhsValue == rhsValue
} else {
let lhsValue = lhs.value as? String
let rhsValue = rhs.value as? String
return lhsValue == rhsValue
}
}
}
return false
}

var uiType: String?
var properties: [String]?
var bounds: [String: Any]?
Expand Down
6 changes: 1 addition & 5 deletions ESPRainMaker/ESPRainMaker/Models/Device.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,7 @@

import Foundation

class Device: Equatable {
static func == (lhs: Device, rhs: Device) -> Bool {
return lhs.attributes == rhs.attributes && lhs.params == rhs.params && lhs.name == rhs.name
}

class Device {
var name: String?
var type: String?
var attributes: [Attribute]?
Expand Down
10 changes: 10 additions & 0 deletions ESPRainMaker/ESPRainMaker/Resources/GitVersion.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//
// GitVersion.h


#ifndef GitVersion_h
#define GitVersion_h

#define GIT_SHA_VERSION @""

#endif
Loading

0 comments on commit d41c6a5

Please sign in to comment.