Server Switching
There are multiple servers that are supported in this demo app and to change the server we need to change the server configuration files and also exit the app in order to make the change visible. You can add the code below to change the server and exit the app.
In the app you have to perform these steps to change your current server.
- Open the app. If you are a new user then on the activation screen on the right top corner you see a menu icon.
Tap on the icon and you see a list of menu items there. Select About.
Now you can see an about-us screen. There is a button Select Asset
After pressing the button you finally come to the Switch server screen where you can select any one of these servers.
In ChangeServerVC class you can see the code that we have added for server switching. Inside tableview delegate method didSelectRowAt.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
DispatchQueue.main.async {
Utilities.showAlertWithCancelAction("Switch server".localized(), message: "\("Are you sure, You want to switch to".localized()) \(self.dataSource[indexPath.row].server) server?".localized(), style: .alert, actionTitles: ["Confirm"], showCancel: true, self, action: { (action) in
if indexPath.row == 0{
self.storageManager?.saveAnyObject("", forKey: Constant.Key.kAssetsPath)
}else {
self.storageManager?.saveAnyObject("\(self.dataSource[indexPath.row].assets)", forKey: Constant.Key.kAssetsPath)
}
self.selectedAsset.text = "Assets in use:- \(self.dataSource[indexPath.row].assets)"
// Restart the master controller with new environment
triggerRestartWithAllParameters()
}, cancelAction: { (cancel) in})
}
}
Now we have two restart events, one is the "normal" restart that you are using for logout purpose, but here, we use a restart event with all the parameters that are passed in the StartEvent. So now you do not have to forcefully close the application and restart the application to use changed environment in your application.
Notes:
After switching the environment from x to y and if you have some user in your application registered in the x environment and in the y environment you will get the user of x also in start/restart event result and if you want to perform login with the user from x environment then you will get a Runtime error or sometimes this user is deleted by MC itself. But if you receive RuntimeError and you are not able to perform a login or to add a user then first delete the user of the x environment and then continue with activation in the y environment.
public func triggerRestartWithAllParameters(){
// mc_config model
let scpConfiguration = globalConst.scpConfiguration
// Get trusted_certs certificate file content
guard let certChain = Utilities.getSSLCertificate(fileName: scpConfiguration?.scp?.trustedSslServerCerts?.first ?? "") else {
return
}
// Create ssms configuration
guard let smsConfiguration = Utilities.getSMSConfiguration() else {
return
}
//Get mc_config file path
guard let scpFilePath = AssetsHelper.getScpConfigFilepath() else {
return
}
//Get mc_config file content
guard let scpConfigJsonString = JsonHelper.getDictionaryFrom(filePath: scpFilePath)?.toJSONString() else {return}
//Create restart event
let restartEvent = KSMRestartEventEx(ssmsAppConfiguration: smsConfiguration, mcConfig: scpConfigJsonString, certificateChain: certChain)
masterControllerAdapter.sendEvent2MasterController(restartEvent){ event in
// Handle post event
}
}
Here we can save the current server assets path in UserDefaults or you can save this information in keychain or any local DB.
class UserDefaultsManager:PersistentStorageManagerProtocol {
static let sharedInstance:UserDefaultsManager = {
let sharedInstance = UserDefaultsManager()
return sharedInstance
}()
// private init to disallow init() from outside
private init(){}
func getObjectForKey(_ key: String) -> Any? {
return standard()?.object(forKey: key)
}
func saveAnyObject(_ object: Any, forKey key: String) {
standard()?.setValue(object, forKey: key)
standard()?.synchronize()
}
func deleteObject(forKey key: String) {
standard()?.removeObject(forKey: key)
standard()?.synchronize()
}
func standard() -> UserDefaults? {
return UserDefaults.standard
}
}
Flow Chart For Receiving Events:
The below image shows receiving an event from the master controller and forwarding it to the registered view controller