FourthTabViewController.swift 51 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841
  1. //
  2. // SettingTableViewController.swift
  3. // Qmera
  4. //
  5. // Created by Yayan Dwi on 16/09/21.
  6. //
  7. import UIKit
  8. import NotificationBannerSwift
  9. import nuSDKService
  10. import NexilisLite
  11. import Photos
  12. public class FourthTabViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UIScrollViewDelegate, UIGestureRecognizerDelegate {
  13. var language: [[String: String]] = [["Indonesia": "id"],["English": "en"]]
  14. var alert: UIAlertController?
  15. var textFields = [UITextField]()
  16. var switchVibrateMode = UISwitch()
  17. var switchSaveToGallery = UISwitch()
  18. var switchAutoDownload = UISwitch()
  19. @IBOutlet weak var tableView: UITableView!
  20. @IBOutlet weak var backgroundImage: UIImageView!
  21. var notInTab = false
  22. public override func viewDidLoad() {
  23. super.viewDidLoad()
  24. tableView.delegate = self
  25. tableView.dataSource = self
  26. tableView.layoutMargins = .init(top: 0, left: 5, bottom: 0, right: 5)
  27. // tableView.separatorColor = .gray
  28. tableView.separatorStyle = .none
  29. switchVibrateMode.tintColor = .gray
  30. switchSaveToGallery.tintColor = .gray
  31. switchAutoDownload.tintColor = .gray
  32. switchVibrateMode.onTintColor = .mainColor
  33. switchSaveToGallery.onTintColor = .mainColor
  34. switchAutoDownload.onTintColor = .mainColor
  35. let vibrateMode = UserDefaults.standard.bool(forKey: "vibrateMode")
  36. let saveGallery = UserDefaults.standard.bool(forKey: "saveToGallery")
  37. let autoDownload = UserDefaults.standard.bool(forKey: "autoDownload")
  38. if vibrateMode {
  39. switchVibrateMode.setOn(true, animated: false)
  40. }
  41. if saveGallery {
  42. switchSaveToGallery.setOn(true, animated: false)
  43. }
  44. if autoDownload {
  45. switchAutoDownload.setOn(true, animated: false)
  46. }
  47. switchVibrateMode.addTarget(self, action: #selector(vibrateModeSwitch), for: .valueChanged)
  48. switchSaveToGallery.addTarget(self, action: #selector(saveToGallerySwitch), for: .valueChanged)
  49. switchAutoDownload.addTarget(self, action: #selector(autoDownloadSwitch), for: .valueChanged)
  50. let tapGesture = UITapGestureRecognizer(target: self, action: #selector(collapseDocked))
  51. tapGesture.cancelsTouchesInView = false
  52. tapGesture.delegate = self
  53. self.view.addGestureRecognizer(tapGesture)
  54. // navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(didTapCancel))
  55. }
  56. @objc func collapseDocked() {
  57. if ViewController.isExpandButton {
  58. ViewController.expandButton()
  59. }
  60. }
  61. public override func viewWillDisappear(_ animated: Bool) {
  62. if ViewController.isExpandButton {
  63. ViewController.expandButton()
  64. }
  65. }
  66. public override func viewDidAppear(_ animated: Bool) {
  67. DispatchQueue.main.asyncAfter(deadline: .now() + 0.2, execute: {
  68. var viewController = UIApplication.shared.windows.first!.rootViewController
  69. if !(viewController is ViewController) {
  70. viewController = self.parent
  71. }
  72. if ViewController.middleButton.isHidden {
  73. ViewController.isExpandButton = false
  74. if let viewController = viewController as? ViewController {
  75. viewController.tabBar.isHidden = false
  76. ViewController.middleButton.isHidden = false
  77. }
  78. }
  79. })
  80. }
  81. @objc func vibrateModeSwitch() {
  82. UserDefaults.standard.set(switchVibrateMode.isOn, forKey: "vibrateMode")
  83. }
  84. @objc func saveToGallerySwitch() {
  85. if switchSaveToGallery.isOn {
  86. PHPhotoLibrary.requestAuthorization({status in
  87. DispatchQueue.main.async {
  88. if status == .authorized {
  89. UserDefaults.standard.set(self.switchSaveToGallery.isOn, forKey: "saveToGallery")
  90. } else {
  91. self.switchSaveToGallery.setOn(false, animated: true)
  92. }
  93. }
  94. })
  95. } else {
  96. UserDefaults.standard.set(self.switchSaveToGallery.isOn, forKey: "saveToGallery")
  97. }
  98. }
  99. @objc func autoDownloadSwitch() {
  100. UserDefaults.standard.set(switchAutoDownload.isOn, forKey: "autoDownload")
  101. }
  102. func makeMenu(imageSignIn: String = ""){
  103. let isChangeProfile = Utils.getSetProfile()
  104. Database.shared.database?.inTransaction({ fmdb, rollback in
  105. let idMe = UserDefaults.standard.string(forKey: "me") as String?
  106. if let cursorUser = Database.shared.getRecords(fmdb: fmdb, query: "SELECT user_type, image_id FROM BUDDY where f_pin='\(idMe!)'"), cursorUser.next() {
  107. var groupId = ""
  108. if let cursorGroup = Database.shared.getRecords(fmdb: fmdb, query: "SELECT group_id FROM GROUPZ where group_type = 1 AND official = 1"), cursorGroup.next() {
  109. groupId = cursorGroup.string(forColumnIndex: 0) ?? ""
  110. cursorGroup.close()
  111. }
  112. var position = ""
  113. if let cursorIsAdmin = Database.shared.getRecords(fmdb: fmdb, query: "SELECT position FROM GROUPZ_MEMBER where group_id = '\(groupId)' AND f_pin = '\(idMe!)'"), cursorIsAdmin.next() {
  114. position = cursorIsAdmin.string(forColumnIndex: 0) ?? ""
  115. cursorIsAdmin.close()
  116. }
  117. if cursorUser.string(forColumnIndex: 0) == "23" && position == "1" {
  118. Item.menus["Personal"] = [
  119. Item(icon: UIImage(systemName: "person.fill"), title: "Personal Information".localized()),
  120. Item(icon: UIImage(systemName: "textformat.abc"), title: "Change Language".localized()),
  121. Item(icon: UIImage(systemName: "person.crop.rectangle"), title: "Change Admin / Internal Password".localized()),
  122. // Item(icon: UIImage(systemName: "laptopcomputer.and.iphone"), title: "Login to Nexilis Web".localized()),
  123. ]
  124. } else if cursorUser.string(forColumnIndex: 0) == "23" || cursorUser.string(forColumnIndex: 0) == "24" {
  125. Item.menus["Personal"] = [
  126. Item(icon: UIImage(systemName: "person.fill"), title: "Personal Information".localized()),
  127. Item(icon: UIImage(systemName: "textformat.abc"), title: "Change Language".localized()),
  128. // Item(icon: UIImage(systemName: "laptopcomputer.and.iphone"), title: "Login to Nexilis Web".localized()),
  129. ]
  130. } else {
  131. Item.menus["Personal"] = [
  132. Item(icon: UIImage(systemName: "person.fill"), title: "Personal Information".localized()),
  133. // Item(icon: UIImage(systemName: "laptopcomputer.and.iphone"), title: "Login to Nexilis Web".localized()),
  134. Item(icon: UIImage(systemName: "textformat.abc"), title: "Change Language".localized()),
  135. Item(icon: UIImage(systemName: "person.crop.rectangle"), title: "Access Admin / Internal Features".localized()),
  136. ]
  137. }
  138. if !isChangeProfile {
  139. Item.menus["Personal"]?.append(Item(icon: UIImage(systemName: "arrow.up.and.person.rectangle.portrait"), title: "Login".localized()))
  140. } else if isChangeProfile {
  141. Item.menus["Personal"]?.append(Item(icon: UIImage(systemName: "rectangle.portrait.and.arrow.right"), title: "Logout".localized()))
  142. }
  143. let image = cursorUser.string(forColumnIndex: 1)
  144. if image != nil {
  145. if !image!.isEmpty {
  146. do {
  147. let documentDir = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
  148. let file = documentDir.appendingPathComponent(image!)
  149. if FileManager().fileExists(atPath: file.path) {
  150. let image = UIImage(contentsOfFile: file.path)
  151. Item.menus["Personal"]?[0].icon = image?.circleMasked
  152. if !imageSignIn.isEmpty {
  153. var dataImage: [AnyHashable : Any] = [:]
  154. dataImage["name"] = imageSignIn
  155. NotificationCenter.default.post(name: NSNotification.Name(rawValue: "imageFBUpdate"), object: nil, userInfo: dataImage)
  156. }
  157. } else {
  158. Download().start(forKey: image!) { (name, progress) in
  159. guard progress == 100 else {
  160. return
  161. }
  162. DispatchQueue.main.async {
  163. let image = UIImage(contentsOfFile: file.path)
  164. Item.menus["Personal"]?[0].icon = image?.circleMasked
  165. self.tableView.reloadData()
  166. if !imageSignIn.isEmpty {
  167. var dataImage: [AnyHashable : Any] = [:]
  168. dataImage["name"] = imageSignIn
  169. NotificationCenter.default.post(name: NSNotification.Name(rawValue: "imageFBUpdate"), object: nil, userInfo: dataImage)
  170. }
  171. }
  172. }
  173. }
  174. } catch {}
  175. }
  176. }
  177. cursorUser.close()
  178. } else {
  179. Item.menus["Personal"] = [
  180. Item(icon: UIImage(systemName: "person.fill"), title: "Personal Information".localized()),
  181. // Item(icon: UIImage(systemName: "laptopcomputer.and.iphone"), title: "Login to Nexilis Web".localized()),
  182. Item(icon: UIImage(systemName: "textformat.abc"), title: "Change Language".localized()),
  183. Item(icon: UIImage(systemName: "person.crop.rectangle"), title: "Access Admin / Internal Features".localized()),
  184. Item(icon: UIImage(systemName: "arrow.up.and.person.rectangle.portrait"), title: "Login".localized())
  185. ]
  186. if !imageSignIn.isEmpty {
  187. do {
  188. let documentDir = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
  189. let file = documentDir.appendingPathComponent(imageSignIn)
  190. if FileManager().fileExists(atPath: file.path) {
  191. let image = UIImage(contentsOfFile: file.path)
  192. Item.menus["Personal"]?[0].icon = image?.circleMasked
  193. var dataImage: [AnyHashable : Any] = [:]
  194. dataImage["name"] = imageSignIn
  195. NotificationCenter.default.post(name: NSNotification.Name(rawValue: "imageFBUpdate"), object: nil, userInfo: dataImage)
  196. } else {
  197. Download().start(forKey: imageSignIn) { (name, progress) in
  198. guard progress == 100 else {
  199. return
  200. }
  201. DispatchQueue.main.async {
  202. let image = UIImage(contentsOfFile: file.path)
  203. Item.menus["Personal"]?[0].icon = image?.circleMasked
  204. self.tableView.reloadData()
  205. var dataImage: [AnyHashable : Any] = [:]
  206. dataImage["name"] = imageSignIn
  207. NotificationCenter.default.post(name: NSNotification.Name(rawValue: "imageFBUpdate"), object: nil, userInfo: dataImage)
  208. }
  209. }
  210. }
  211. } catch {}
  212. }
  213. }
  214. })
  215. Item.menus["Call"] = [
  216. Item(icon: UIImage(systemName: "message"), title: "Incoming Message(s)".localized()),
  217. Item(icon: UIImage(systemName: "phone"), title: "Incoming Call(s)".localized()),
  218. Item(icon: UIImage(systemName: "iphone.homebutton.radiowaves.left.and.right"), title: "Vibrate Mode".localized()),
  219. Item(icon: UIImage(systemName: "photo.on.rectangle.angled"), title: "Save to Gallery".localized()),
  220. Item(icon: UIImage(systemName: "arrow.down.square"), title: "Auto Download".localized()),
  221. ]
  222. Item.menus["Version"] = [
  223. Item(icon: UIImage(systemName: "gear"), title: "Version".localized()),
  224. Item(icon: UIImage(named: "pb_powered_button", in: Bundle.resourceBundle(for: Nexilis.self), with: nil), title: "Powered by Nexilis".localized()),
  225. ]
  226. }
  227. override public func viewWillAppear(_ animated: Bool) {
  228. backgroundImage.backgroundColor = .white
  229. if notInTab {
  230. self.title = "Settings".localized()
  231. self.navigationController?.navigationBar.topItem?.title = ""
  232. } else {
  233. self.navigationController?.navigationBar.topItem?.title = "Settings".localized()
  234. }
  235. self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.black]
  236. navigationController?.setNavigationBarHidden(false, animated: false)
  237. navigationController?.navigationBar.backgroundColor = .clear
  238. navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
  239. navigationController?.navigationBar.shadowImage = UIImage()
  240. navigationController?.navigationBar.isTranslucent = true
  241. makeMenu()
  242. tableView.reloadData()
  243. }
  244. // MARK: - Table view data source
  245. public func numberOfSections(in tableView: UITableView) -> Int {
  246. return Item.sections.count
  247. }
  248. public func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
  249. return 1
  250. }
  251. public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  252. return Item.menuFor(section: section).count
  253. }
  254. public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  255. let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath)
  256. cell.accessoryType = .none
  257. cell.indentationLevel = 0
  258. var content = cell.defaultContentConfiguration()
  259. content.textProperties.font = UIFont.systemFont(ofSize: 14)
  260. content.secondaryTextProperties.font = UIFont.systemFont(ofSize: 14)
  261. content.secondaryTextProperties.color = .gray
  262. content.prefersSideBySideTextAndSecondaryText = true
  263. let section = Item.sections[indexPath.section]
  264. if let arr = Item.menus[section] {
  265. let menu = arr[indexPath.row]
  266. content.image = menu.icon
  267. content.imageProperties.tintColor = .mainColor
  268. content.imageProperties.maximumSize = CGSize(width: 24, height: 24)
  269. content.text = menu.title
  270. cell.accessoryView = nil
  271. cell.separatorInset = UIEdgeInsets(top: .greatestFiniteMagnitude, left: 0, bottom: 0, right: .greatestFiniteMagnitude)
  272. switch menu.title {
  273. case "Personal Information".localized():
  274. cell.accessoryType = .disclosureIndicator
  275. case "Access Admin / Internal Features".localized():
  276. cell.accessoryType = .disclosureIndicator
  277. case "Login to Nexilis Web".localized():
  278. cell.accessoryType = .disclosureIndicator
  279. case "Login".localized():
  280. cell.accessoryType = .disclosureIndicator
  281. // case "Logout".localized():
  282. case "Change Admin / Internal Password".localized():
  283. cell.accessoryType = .disclosureIndicator
  284. case "Change Language".localized():
  285. cell.accessoryType = .disclosureIndicator
  286. case "Version".localized():
  287. let accessoryButton = UIButton(type: .custom)
  288. accessoryButton.setTitle(UIApplication.appVersion, for: .normal)
  289. accessoryButton.setTitleColor(.black, for: .normal)
  290. accessoryButton.frame = CGRect(x: 0, y: 0, width: 40, height: 40)
  291. accessoryButton.contentMode = .scaleAspectFit
  292. cell.accessoryView = accessoryButton as UIView
  293. case "Vibrate Mode".localized():
  294. cell.accessoryView = switchVibrateMode
  295. case "Save to Gallery".localized():
  296. cell.accessoryView = switchSaveToGallery
  297. case "Auto Download".localized():
  298. cell.accessoryView = switchAutoDownload
  299. default:
  300. content.secondaryText = nil
  301. }
  302. }
  303. cell.contentConfiguration = content
  304. return cell
  305. }
  306. public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
  307. let item = Item.menuFor(section: indexPath.section)[indexPath.row]
  308. if item.title == "Personal Information".localized() {
  309. if(ViewController.checkIsChangePerson()){
  310. let controller = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "profileView") as! ProfileViewController
  311. controller.data = UserDefaults.standard.string(forKey: "me")!
  312. controller.flag = .me
  313. controller.dismissImage = { image, imageName in
  314. var dataImage: [AnyHashable : Any] = [:]
  315. dataImage["name"] = imageName
  316. NotificationCenter.default.post(name: NSNotification.Name(rawValue: "imageFBUpdate"), object: nil, userInfo: dataImage)
  317. self.makeMenu()
  318. self.tableView.reloadData()
  319. }
  320. navigationController?.show(controller, sender: nil)
  321. }
  322. } else if item.title == "Access Admin / Internal Features".localized() || item.title == "Change Admin / Internal Password".localized() {
  323. if(ViewController.checkIsChangePerson()){
  324. if !CheckConnection.isConnectedToNetwork() || API.nGetCLXConnState() == 0 {
  325. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  326. imageView.tintColor = .white
  327. let banner = FloatingNotificationBanner(title: "Check your connection".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
  328. banner.show()
  329. return
  330. }
  331. let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
  332. if(item.title.contains("Change")){
  333. if let action = self.actionChangePassword(for: "admin", title: "Change Admin Password".localized()) {
  334. alertController.addAction(action)
  335. }
  336. if let action = self.actionChangePassword(for: "internal", title: "Change Internal Password".localized()) {
  337. alertController.addAction(action)
  338. }
  339. }
  340. else {
  341. if let action = self.actionLogin(for: "admin", title: "Access Admin Features".localized()) {
  342. alertController.addAction(action)
  343. }
  344. if let action = self.actionLogin(for: "internal", title: "Access Internal Features".localized()) {
  345. alertController.addAction(action)
  346. }
  347. }
  348. alertController.addAction(UIAlertAction(title: "Cancel".localized(), style: .cancel, handler: nil))
  349. self.present(alertController, animated: true)
  350. }
  351. } else if item.title == "Change Language".localized() {
  352. let vc = UIViewController()
  353. vc.preferredContentSize = CGSize(width: UIScreen.main.bounds.width - 10, height: 150)
  354. let pickerView = UIPickerView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width - 10, height: 150))
  355. pickerView.dataSource = self
  356. pickerView.delegate = self
  357. let lang = UserDefaults.standard.string(forKey: "i18n_language")
  358. var index = 1
  359. if lang == "id" {
  360. index = 0
  361. }
  362. pickerView.selectRow(index, inComponent: 0, animated: false)
  363. vc.view.addSubview(pickerView)
  364. pickerView.translatesAutoresizingMaskIntoConstraints = false
  365. pickerView.centerXAnchor.constraint(equalTo: vc.view.centerXAnchor).isActive = true
  366. pickerView.centerYAnchor.constraint(equalTo: vc.view.centerYAnchor).isActive = true
  367. let alert = UIAlertController(title: "Select Language".localized(), message: "", preferredStyle: .actionSheet)
  368. alert.setValue(vc, forKey: "contentViewController")
  369. alert.addAction(UIAlertAction(title: "Cancel".localized(), style: .cancel, handler: { (UIAlertAction) in
  370. }))
  371. alert.addAction(UIAlertAction(title: "Select".localized(), style: .default, handler: { (UIAlertAction) in
  372. let selectedIndex = pickerView.selectedRow(inComponent: 0)
  373. let lang = self.language[selectedIndex].values.first
  374. UserDefaults.standard.set(lang, forKey: "i18n_language")
  375. self.navigationController?.navigationBar.topItem?.title = "Settings".localized();
  376. self.makeMenu()
  377. self.tableView.reloadData()
  378. FirstTabViewController.forceRefresh = true
  379. ThirdTabViewController.forceRefresh = true
  380. }))
  381. self.present(alert, animated: true, completion: nil)
  382. } else if item.title == "Login".localized() {
  383. let controller = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "changeDevice") as! ChangeDeviceViewController
  384. controller.isDismiss = { newThumb in
  385. self.makeMenu(imageSignIn: newThumb)
  386. self.tableView.reloadData()
  387. }
  388. navigationController?.show(controller, sender: nil)
  389. } else if item.title == "Logout".localized() {
  390. let alert = UIAlertController(title: "Logout".localized(), message: "Are you sure want to logout?".localized(), preferredStyle: .alert)
  391. alert.addAction(UIAlertAction(title: "Cancel".localized(), style: UIAlertAction.Style.default, handler: nil))
  392. alert.addAction(UIAlertAction(title: "Yes".localized(), style: .destructive, handler: {(_) in
  393. if !CheckConnection.isConnectedToNetwork() || API.nGetCLXConnState() == 0 {
  394. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  395. imageView.tintColor = .white
  396. let banner = FloatingNotificationBanner(title: "Check your connection".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
  397. banner.show()
  398. return
  399. }
  400. Nexilis.showLoader()
  401. DispatchQueue.global().async {
  402. self.deleteAllRecordDatabase()
  403. Nexilis.destroyAll()
  404. let apiKey = Nexilis.sAPIKey
  405. var id = UIDevice.current.identifierForVendor?.uuidString ?? "UNK-DEVICE"
  406. if let response = Nexilis.writeSync(message: CoreMessage_TMessageBank.getSignUpApi(api: apiKey, p_pin: id), timeout: 30 * 1000) {
  407. id = response.getBody(key: CoreMessage_TMessageKey.F_PIN, default_value: "")
  408. if(!id.isEmpty){
  409. Nexilis.changeUser(f_pin: id)
  410. UserDefaults.standard.setValue(id, forKey: "me")
  411. Utils.setProfile(value: false)
  412. UserDefaults.standard.synchronize()
  413. // pos registration
  414. _ = Nexilis.write(message: CoreMessage_TMessageBank.getPostRegistration(p_pin: id))
  415. DispatchQueue.main.async {
  416. Nexilis.hideLoader()
  417. let imageView = UIImageView(image: UIImage(systemName: "checkmark.circle.fill"))
  418. imageView.tintColor = .white
  419. let banner = FloatingNotificationBanner(title: "Successfully Logout".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .success, colors: nil, iconPosition: .center)
  420. banner.show()
  421. var dataImage: [AnyHashable : Any] = [:]
  422. dataImage["name"] = ""
  423. NotificationCenter.default.post(name: NSNotification.Name(rawValue: "imageFBUpdate"), object: nil, userInfo: dataImage)
  424. self.makeMenu()
  425. self.tableView.reloadData()
  426. }
  427. } else {
  428. Nexilis.hideLoader()
  429. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  430. imageView.tintColor = .white
  431. let banner = FloatingNotificationBanner(title: "Unable to access servers. Try again later".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
  432. banner.show()
  433. }
  434. } else {
  435. DispatchQueue.main.async {
  436. Nexilis.hideLoader()
  437. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  438. imageView.tintColor = .white
  439. let banner = FloatingNotificationBanner(title: "Unable to access servers. Try again later".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
  440. banner.show()
  441. }
  442. }
  443. }
  444. }))
  445. self.present(alert, animated: true, completion: nil)
  446. }
  447. }
  448. private func actionLogin(for type: String, title: String) -> UIAlertAction? {
  449. return UIAlertAction(title: title, style: .default) { _ in
  450. self.alert = UIAlertController(title:"Access Admin Features".localized(), message: nil, preferredStyle: .alert)
  451. if type == "internal" {
  452. self.alert = UIAlertController(title: "Access Internal Features".localized(), message: nil, preferredStyle: .alert)
  453. }
  454. self.textFields.removeAll()
  455. self.alert?.addTextField{ (texfield) in
  456. texfield.placeholder = "Password".localized()
  457. texfield.isSecureTextEntry = true
  458. texfield.addPadding(.right(40))
  459. texfield.addTarget(self, action: #selector(self.alertTextFieldDidChange(_:)), for: UIControl.Event.editingChanged)
  460. let buttonHideUnhide = UIButton()
  461. buttonHideUnhide.tag = 0
  462. texfield.addSubview(buttonHideUnhide)
  463. buttonHideUnhide.anchor(top: texfield.topAnchor, right: texfield.rightAnchor, paddingTop: -7, width: 30, height: 30)
  464. buttonHideUnhide.setImage(UIImage(systemName: "eye.slash.fill"), for: .normal)
  465. buttonHideUnhide.tintColor = .black
  466. buttonHideUnhide.addTarget(self, action: #selector(self.showPassword), for: .touchUpInside)
  467. }
  468. let submitAction = UIAlertAction(title: "Login".localized(), style: .default, handler: { (action) -> Void in
  469. let textField = self.alert?.textFields![0]
  470. if !CheckConnection.isConnectedToNetwork() || API.nGetCLXConnState() == 0 {
  471. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  472. imageView.tintColor = .white
  473. let banner = FloatingNotificationBanner(title: "Check your connection".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
  474. banner.show()
  475. return
  476. }
  477. if type == "admin" {
  478. self.signInAdmin(password: textField!.text!, completion: { result in
  479. if result {
  480. DispatchQueue.main.async {
  481. let imageView = UIImageView(image: UIImage(systemName: "checkmark.circle.fill"))
  482. imageView.tintColor = .white
  483. let banner = FloatingNotificationBanner(title: "Successfully login Admin".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .success, colors: nil, iconPosition: .center)
  484. banner.show()
  485. let itemCP = Item(icon: UIImage(systemName: "person.crop.rectangle"), title: "Change Admin / Internal Password".localized())
  486. Item.menus["Personal"]?[1] = itemCP
  487. self.tableView.reloadData()
  488. }
  489. }
  490. })
  491. } else {
  492. self.signInInternal(password: textField!.text!, completion: { result in
  493. if result {
  494. DispatchQueue.main.async {
  495. let imageView = UIImageView(image: UIImage(systemName: "checkmark.circle.fill"))
  496. imageView.tintColor = .white
  497. let banner = FloatingNotificationBanner(title: "Successfully login Internal Team".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .success, colors: nil, iconPosition: .center)
  498. banner.show()
  499. Item.menus["Personal"]?.remove(at: 1)
  500. self.tableView.reloadData()
  501. }
  502. }
  503. })
  504. }
  505. })
  506. submitAction.isEnabled = false
  507. self.alert?.addAction(submitAction)
  508. self.alert?.addAction(UIAlertAction(title: "Cancel".localized(), style: .cancel, handler: nil))
  509. self.present(self.alert!, animated: true, completion: nil)
  510. }
  511. }
  512. private func actionChangePassword(for type: String, title: String) -> UIAlertAction? {
  513. return UIAlertAction(title: title, style: .default) { _ in
  514. self.alert = UIAlertController(title: "Change Admin Password".localized(), message: nil, preferredStyle: .alert)
  515. if type == "internal" {
  516. self.alert = UIAlertController(title: "Change Internal Password".localized(), message: nil, preferredStyle: .alert)
  517. }
  518. self.textFields.removeAll()
  519. self.alert?.addTextField{ (texfield) in
  520. texfield.placeholder = "Old Password"
  521. texfield.isSecureTextEntry = true
  522. texfield.addPadding(.right(40))
  523. texfield.addTarget(self, action: #selector(self.alertTextFieldDidChange(_:)), for: UIControl.Event.editingChanged)
  524. self.textFields.append(texfield)
  525. let buttonHideUnhide = UIButton()
  526. buttonHideUnhide.tag = 0
  527. texfield.addSubview(buttonHideUnhide)
  528. buttonHideUnhide.anchor(top: texfield.topAnchor, right: texfield.rightAnchor, paddingTop: -7, width: 30, height: 30)
  529. buttonHideUnhide.setImage(UIImage(systemName: "eye.slash.fill"), for: .normal)
  530. buttonHideUnhide.tintColor = .black
  531. buttonHideUnhide.addTarget(self, action: #selector(self.showPassword), for: .touchUpInside)
  532. }
  533. self.alert?.addTextField{ (texfield) in
  534. texfield.placeholder = "New Password"
  535. texfield.isSecureTextEntry = true
  536. texfield.addPadding(.right(40))
  537. texfield.addTarget(self, action: #selector(self.alertTextFieldDidChange(_:)), for: UIControl.Event.editingChanged)
  538. self.textFields.append(texfield)
  539. let buttonHideUnhide = UIButton()
  540. buttonHideUnhide.tag = 1
  541. texfield.addSubview(buttonHideUnhide)
  542. buttonHideUnhide.anchor(top: texfield.topAnchor, right: texfield.rightAnchor, paddingTop: -7, width: 30, height: 30)
  543. buttonHideUnhide.setImage(UIImage(systemName: "eye.slash.fill"), for: .normal)
  544. buttonHideUnhide.tintColor = .black
  545. buttonHideUnhide.addTarget(self, action: #selector(self.showPassword), for: .touchUpInside)
  546. }
  547. let submitAction = UIAlertAction(title: "Change Password".localized(), style: .default, handler: { (action) -> Void in
  548. let textFieldOld = self.alert?.textFields![0]
  549. let textFieldNew = self.alert?.textFields![1]
  550. if !CheckConnection.isConnectedToNetwork() || API.nGetCLXConnState() == 0 {
  551. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  552. imageView.tintColor = .white
  553. let banner = FloatingNotificationBanner(title: "Check your connection".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
  554. banner.show()
  555. return
  556. }
  557. if type == "admin" {
  558. self.changePasswordAdmin(oldPassword: textFieldOld!.text!, newPassword: textFieldNew!.text!, completion: { result in
  559. if result {
  560. DispatchQueue.main.async {
  561. let imageView = UIImageView(image: UIImage(systemName: "checkmark.circle.fill"))
  562. imageView.tintColor = .white
  563. let banner = FloatingNotificationBanner(title: "Admin password changed successfully".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .success, colors: nil, iconPosition: .center)
  564. banner.show()
  565. }
  566. }
  567. })
  568. } else {
  569. self.changePasswordInternal(oldPassword: textFieldOld!.text!, newPassword: textFieldNew!.text!, completion: { result in
  570. if result {
  571. DispatchQueue.main.async {
  572. let imageView = UIImageView(image: UIImage(systemName: "checkmark.circle.fill"))
  573. imageView.tintColor = .white
  574. let banner = FloatingNotificationBanner(title: "Internal password changed successfully".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .success, colors: nil, iconPosition: .center)
  575. banner.show()
  576. }
  577. }
  578. })
  579. }
  580. })
  581. submitAction.isEnabled = false
  582. self.alert?.addAction(submitAction)
  583. self.alert?.addAction(UIAlertAction(title: "Cancel".localized(), style: .cancel, handler: nil))
  584. self.present(self.alert!, animated: true, completion: nil)
  585. }
  586. }
  587. @objc func showPassword(_ sender:UIButton) {
  588. if alert!.textFields![sender.tag].isSecureTextEntry {
  589. alert!.textFields![sender.tag].isSecureTextEntry = false
  590. let buttonImage = alert!.textFields![sender.tag].subviews[0] as! UIButton
  591. buttonImage.setImage(UIImage(systemName: "eye.fill"), for: .normal)
  592. } else {
  593. alert!.textFields![sender.tag].isSecureTextEntry = true
  594. let buttonImage = alert!.textFields![sender.tag].subviews[0] as! UIButton
  595. buttonImage.setImage(UIImage(systemName: "eye.slash.fill"), for: .normal)
  596. }
  597. }
  598. @objc func alertTextFieldDidChange(_ sender: UITextField) {
  599. if(!textFields.isEmpty){
  600. print("text count 0: \(textFields[0].text!.count)")
  601. print("text count 1: \(textFields[1].text!.count)")
  602. alert?.actions[0].isEnabled = textFields[0].text!.count > 0 && textFields[1].text!.count > 0
  603. }
  604. else {
  605. alert?.actions[0].isEnabled = sender.text!.count > 0
  606. }
  607. }
  608. private func signInAdmin(password: String, completion: @escaping (Bool) -> ()) {
  609. DispatchQueue.global().async {
  610. let idMe = UserDefaults.standard.string(forKey: "me") as String?
  611. let p_password = password
  612. let md5Hex = Utils.getMD5(string: p_password).map { String(format: "%02hhx", $0) }.joined()
  613. var result: Bool = false
  614. if let response = Nexilis.writeSync(message: CoreMessage_TMessageBank.getSignInApiAdmin(p_name: idMe!, p_password: md5Hex)) {
  615. if response.isOk() {
  616. result = true
  617. }
  618. DispatchQueue.main.async {
  619. if response.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99") == "11" {
  620. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  621. imageView.tintColor = .white
  622. let banner = FloatingNotificationBanner(title: "Username or password does not match".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .top)
  623. banner.show()
  624. } else if response.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99") == "20" {
  625. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  626. imageView.tintColor = .white
  627. let banner = FloatingNotificationBanner(title: "Invalid password".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .top)
  628. banner.show()
  629. }
  630. }
  631. } else {
  632. DispatchQueue.main.async {
  633. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  634. imageView.tintColor = .white
  635. let banner = FloatingNotificationBanner(title: "Unable to access servers".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .top)
  636. banner.show()
  637. }
  638. }
  639. completion(result)
  640. }
  641. }
  642. private func signInInternal(password: String, completion: @escaping (Bool) -> ()) {
  643. DispatchQueue.global().async {
  644. let idMe = UserDefaults.standard.string(forKey: "me") as String?
  645. let p_password = password
  646. let md5Hex = Utils.getMD5(string: p_password).map { String(format: "%02hhx", $0) }.joined()
  647. var result: Bool = false
  648. if let response = Nexilis.writeSync(message: CoreMessage_TMessageBank.getSignInApiInternal(p_name: idMe!, p_password: md5Hex)) {
  649. if response.isOk() {
  650. result = true
  651. }
  652. DispatchQueue.main.async {
  653. if response.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99") == "11" {
  654. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  655. imageView.tintColor = .white
  656. let banner = FloatingNotificationBanner(title: "Username or password does not match".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .top)
  657. banner.show()
  658. } else if response.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99") == "20" {
  659. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  660. imageView.tintColor = .white
  661. let banner = FloatingNotificationBanner(title: "Invalid password".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .top)
  662. banner.show()
  663. }
  664. }
  665. } else {
  666. DispatchQueue.main.async {
  667. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  668. imageView.tintColor = .white
  669. let banner = FloatingNotificationBanner(title: "Unable to access servers".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .top)
  670. banner.show()
  671. }
  672. }
  673. completion(result)
  674. }
  675. }
  676. private func changePasswordAdmin(oldPassword: String, newPassword: String, completion: @escaping (Bool) -> ()) {
  677. DispatchQueue.global().async {
  678. let idMe = UserDefaults.standard.string(forKey: "me") as String?
  679. let p_password = oldPassword
  680. let n_password = newPassword
  681. let md5Hex = Utils.getMD5(string: p_password).map { String(format: "%02hhx", $0) }.joined()
  682. let md5HexNew = Utils.getMD5(string: n_password).map { String(format: "%02hhx", $0) }.joined()
  683. var result: Bool = false
  684. if let response = Nexilis.writeSync(message: CoreMessage_TMessageBank.getChangePasswordAdmin(p_f_pin: idMe!, pwd_en: md5HexNew, pwd_old: md5Hex)) {
  685. if response.isOk() {
  686. result = true
  687. }
  688. DispatchQueue.main.async {
  689. if response.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99") == "11" {
  690. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  691. imageView.tintColor = .white
  692. let banner = FloatingNotificationBanner(title: "Username or password does not match".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .top)
  693. banner.show()
  694. } else if response.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99") == "20" {
  695. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  696. imageView.tintColor = .white
  697. let banner = FloatingNotificationBanner(title: "Invalid password".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .top)
  698. banner.show()
  699. }
  700. }
  701. } else {
  702. DispatchQueue.main.async {
  703. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  704. imageView.tintColor = .white
  705. let banner = FloatingNotificationBanner(title: "Unable to access servers".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .top)
  706. banner.show()
  707. }
  708. }
  709. completion(result)
  710. }
  711. }
  712. private func changePasswordInternal(oldPassword: String, newPassword: String, completion: @escaping (Bool) -> ()) {
  713. DispatchQueue.global().async {
  714. let idMe = UserDefaults.standard.string(forKey: "me") as String?
  715. let p_password = oldPassword
  716. let n_password = newPassword
  717. let md5Hex = Utils.getMD5(string: p_password).map { String(format: "%02hhx", $0) }.joined()
  718. let md5HexNew = Utils.getMD5(string: n_password).map { String(format: "%02hhx", $0) }.joined()
  719. var result: Bool = false
  720. if let response = Nexilis.writeSync(message: CoreMessage_TMessageBank.getChangePasswordInternal(p_f_pin: idMe!, pwd_en: md5HexNew, pwd_old: md5Hex)) {
  721. if response.isOk() {
  722. result = true
  723. }
  724. DispatchQueue.main.async {
  725. if response.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99") == "11" {
  726. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  727. imageView.tintColor = .white
  728. let banner = FloatingNotificationBanner(title: "Username or password does not match".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .top)
  729. banner.show()
  730. } else if response.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99") == "20" {
  731. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  732. imageView.tintColor = .white
  733. let banner = FloatingNotificationBanner(title: "Invalid password".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .top)
  734. banner.show()
  735. }
  736. }
  737. } else {
  738. DispatchQueue.main.async {
  739. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  740. imageView.tintColor = .white
  741. let banner = FloatingNotificationBanner(title: "Unable to access servers".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .top)
  742. banner.show()
  743. }
  744. }
  745. completion(result)
  746. }
  747. }
  748. }
  749. // MARK: - Item
  750. struct Item: Hashable {
  751. static func == (lhs: Item, rhs: Item) -> Bool {
  752. return lhs.title == rhs.title
  753. }
  754. var icon: UIImage?
  755. var title = ""
  756. static var sections: [String] {
  757. return ["Personal", "Call", "Version"]
  758. }
  759. static var menus: [String: [Item]] = [:]
  760. static func menuFor(section: Int) -> [Item] {
  761. let sec = sections[section]
  762. if let arr = menus[sec] {
  763. return arr
  764. }
  765. return []
  766. }
  767. }
  768. extension FourthTabViewController: UIPickerViewDelegate, UIPickerViewDataSource {
  769. public func numberOfComponents(in pickerView: UIPickerView) -> Int {
  770. return 1
  771. }
  772. public func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
  773. return language.count
  774. }
  775. public func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat {
  776. return 60
  777. }
  778. public func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
  779. let label = UILabel(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width - 10, height: 30))
  780. label.text = (language[row]).keys.first
  781. label.sizeToFit()
  782. return label
  783. }
  784. }