alqindiirsyam 1 år sedan
förälder
incheckning
dd60528e14

+ 1 - 0
appbuilder-ios/AppBuilder/AppBuilder/AppDelegate.swift

@@ -16,6 +16,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
         if PrefsUtil.getCpaasMode() == PrefsUtil.CPAAS_MODE_FLOATING || PrefsUtil.getCpaasMode() == PrefsUtil.CPAAS_MODE_MIX {
             showButton = true
         }
+        Nexilis.isShowForceSignIn = false
         Nexilis.connect(apiKey: "***REPLACE***WITH***YOUR***ACCOUNT***", delegate: self, showButton: showButton, fromMAB: true) //23091CF494A11149F5A8FC8D17FF690DC69AE656F91B86070A11506ED24144F5(BPKH) //38747683290F62E9667A018F490396EAE47BC16ADECD85B7E865C733E6DBD6A2(OneApp)
         registerForPushNotifications()
         return true

+ 3 - 10
appbuilder-ios/AppBuilder/AppBuilder/FourthTabViewController.swift

@@ -591,16 +591,9 @@ public class FourthTabViewController: UIViewController, UITableViewDelegate, UIT
                                     ThirdTabViewController.forceRefresh = true
                                     FirstTabViewController.showModal = false
                                     ThirdTabViewController.showModal = false
-                                })
-                            }
-                            if !Utils.getForceAnonymous() {
-                                DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: {
-                                    var viewController = UIApplication.shared.windows.first!.rootViewController
-                                    if !(viewController is ViewController) {
-                                        viewController = self.parent
-                                    }
-                                    if let viewController = viewController as? ViewController {
-                                        viewController.viewWillAppear(false)
+                                    
+                                    if !Utils.getForceAnonymous() {
+                                        Nexilis.showForceSignIn()
                                     }
                                 })
                             }

+ 4 - 0
appbuilder-ios/AppBuilder/AppBuilder/Info.plist

@@ -28,6 +28,10 @@
 	<true/>
 	<key>NSCameraUsageDescription</key>
 	<string>Video Call, Conference Room, Content Creation and Live Streaming.</string>
+    <key>NSLocationWhenInUseUsageDescription</key>
+    <string>Access Location For Multiple Login.</string>
+    <key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
+    <string>Access Location For Multiple Login.</string>
 	<key>NSContactsUsageDescription</key>
 	<string>Get File Contact from Local Dictionary for Send Message.</string>
 	<key>NSDocumentsFolderUsageDescription</key>

+ 1 - 15
appbuilder-ios/AppBuilder/AppBuilder/ViewController.swift

@@ -592,21 +592,7 @@ class ViewController: UITabBarController, UITabBarControllerDelegate, SettingMAB
             return
         } else {
             if !Utils.getForceAnonymous() && !Utils.getSetProfile() {
-                let controller = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "changeDevice") as! ChangeDeviceViewController
-                controller.forceLogin = true
-                let navigationController = CustomNavigationController(rootViewController: controller)
-                navigationController.navigationBar.tintColor = .white
-                navigationController.navigationBar.barTintColor = self.traitCollection.userInterfaceStyle == .dark ? .blackDarkMode : .mainColor
-                navigationController.navigationBar.isTranslucent = false
-                navigationController.navigationBar.overrideUserInterfaceStyle = .dark
-                navigationController.navigationBar.barStyle = .black
-                let cancelButtonAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font : UIFont.systemFont(ofSize: 16)]
-                UIBarButtonItem.appearance().setTitleTextAttributes(cancelButtonAttributes, for: .normal)
-                let textAttributes = [NSAttributedString.Key.foregroundColor:UIColor.white]
-                navigationController.navigationBar.titleTextAttributes = textAttributes
-                navigationController.modalPresentationStyle = .fullScreen
-                navigationController.modalTransitionStyle = .crossDissolve
-                self.present(navigationController, animated: true)
+                Nexilis.showForceSignIn()
                 return
             }
         }

+ 6 - 3
appbuilder-ios/NexilisLite/NexilisLite/Resource/Palio.storyboard

@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="22505" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="32700.99.1234" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
     <device id="retina6_1" orientation="portrait" appearance="light"/>
     <dependencies>
         <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22504"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22684"/>
         <capability name="Image references" minToolsVersion="12.0"/>
         <capability name="Safe area layout guides" minToolsVersion="9.0"/>
         <capability name="System colors in document resources" minToolsVersion="11.0"/>
@@ -652,6 +652,7 @@
                     <tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="static" style="insetGrouped" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="18" sectionFooterHeight="18" id="keJ-TL-z3p">
                         <rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                         <sections>
                             <tableViewSection id="DZB-i7-3Uu">
                                 <cells>
@@ -724,6 +725,7 @@
                                                     </constraints>
                                                 </view>
                                             </subviews>
+                                            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                             <constraints>
                                                 <constraint firstAttribute="trailingMargin" secondItem="40M-iH-oyA" secondAttribute="trailing" id="2Dq-Mc-H4d"/>
                                                 <constraint firstAttribute="bottom" secondItem="0K5-VL-Mqq" secondAttribute="bottom" id="7fF-SI-jIM"/>
@@ -737,6 +739,7 @@
                                                 <constraint firstAttribute="bottomMargin" secondItem="40M-iH-oyA" secondAttribute="bottom" constant="10" id="r1W-TW-sUP"/>
                                             </constraints>
                                         </tableViewCellContentView>
+                                        <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                     </tableViewCell>
                                 </cells>
                             </tableViewSection>
@@ -2998,7 +3001,7 @@
                             </label>
                         </subviews>
                         <viewLayoutGuide key="safeArea" id="RRi-TQ-BYu"/>
-                        <color key="backgroundColor" systemColor="systemBackgroundColor"/>
+                        <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                         <constraints>
                             <constraint firstItem="OGC-mO-8T0" firstAttribute="top" secondItem="kwq-ci-Qkk" secondAttribute="bottom" constant="10" id="0ZP-Ei-MVh"/>
                             <constraint firstItem="SAR-sw-Oq9" firstAttribute="top" secondItem="OGC-mO-8T0" secondAttribute="bottom" constant="16" id="1bB-K3-4S8"/>

+ 13 - 0
appbuilder-ios/NexilisLite/NexilisLite/Source/CoreMessage_TMessageBank.swift

@@ -2444,4 +2444,17 @@ public class CoreMessage_TMessageBank {
         return tmessage
     }
     
+    public static func getAlertNewSignIn(brand: String, latitude: String, longitude: String ) -> TMessage {
+        let tmessage = TMessage()
+        tmessage.mCode = CoreMessage_TMessageCode.ALERT_NEW_SIGN_IN
+        tmessage.mStatus = CoreMessage_TMessageUtil.getTID()
+        tmessage.mPIN = User.getMyPin() ?? ""
+        tmessage.mBodies[CoreMessage_TMessageKey.F_PIN] = Utils.getLoginMultipleFPin()
+        tmessage.mBodies[CoreMessage_TMessageKey.DEVICE_BRAND] = brand
+        tmessage.mBodies[CoreMessage_TMessageKey.LATITUDE] = latitude
+        tmessage.mBodies[CoreMessage_TMessageKey.LONGITUDE] = longitude
+        tmessage.mBodies[CoreMessage_TMessageKey.LOCAL_TIMESTAMP] = "\(Date().currentTimeMillis())"
+        return tmessage
+    }
+    
 }

+ 6 - 0
appbuilder-ios/NexilisLite/NexilisLite/Source/CoreMessage_TMessageCode.swift

@@ -747,6 +747,8 @@ public class CoreMessage_TMessageCode {
     public static let BACKUP_UPLOADED = "BUU2";
     public static let BACKUP_RESTORED = "BUR2";
     
+    public static let LOGOUT = "LGT";
+    
     public static let FORWARD_MESSAGE = "C2";
     public static let WB_INCOMING = 101;
     public static let WB_OFFHOOK = 102;
@@ -771,4 +773,8 @@ public class CoreMessage_TMessageCode {
     public static let FEATURE_ACCESS_ALL = "FA02";
     
     public static let PAYMENT_NOTIFICATION = "PAY";
+    
+    public static let ALERT_NEW_SIGN_IN = "ANSI";
+
+    public static let SHIELD_SECURITY_VALIDATE_TOKEN = "SSVT";
 }

+ 77 - 1
appbuilder-ios/NexilisLite/NexilisLite/Source/IncomingThread.swift

@@ -189,7 +189,9 @@ class IncomingThread {
             notifyCalling(message: message)
         } else if message.getCode() == CoreMessage_TMessageCode.PAYMENT_NOTIFICATION {
             showTransactionApprovalRequest(message: message)
-        }  else {
+        }  else if message.getCode() == CoreMessage_TMessageCode.LOGOUT {
+            logoutDevice(message: message)
+        } else {
             //print("unprocessed code", message.getCode())
             ack(message: message)
         }
@@ -202,6 +204,79 @@ class IncomingThread {
      *
      */
     
+    private func logoutDevice(message: TMessage) -> Void {
+        if let packetId = message.mBodies[CoreMessage_TMessageKey.PACKET_ID] {
+            _ = Nexilis.responseString(packetId: packetId, message: "00", timeout: 3000)
+        }
+        DispatchQueue.global().async {
+            var viewController = UIApplication.shared.visibleViewController
+            DispatchQueue.main.async {
+                if !CheckConnection.isConnectedToNetwork()  || API.nGetCLXConnState() == 0 {
+                    let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
+                    imageView.tintColor = .white
+                    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)
+                    banner.show()
+                    return
+                }
+                Nexilis.showLoader()
+                let imageView = UIImageView(image: UIImage(systemName: "info.circle"))
+                imageView.tintColor = .white
+                let banner = FloatingNotificationBanner(title: "You have requested Call Center, please wait for response.".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .info, colors: nil, iconPosition: .center)
+                banner.show()
+            }
+            let apiKey = Nexilis.sAPIKey
+            var id = Utils.getConnectionID()
+            if let response = Nexilis.writeSync(message: CoreMessage_TMessageBank.getSignUpApi(api: apiKey, p_pin: id), timeout: 30 * 1000) {
+                id = response.getBody(key: CoreMessage_TMessageKey.F_PIN, default_value: "")
+                if(!id.isEmpty){
+//                            Nexilis.changeUser(f_pin: id)
+                    UserDefaults.standard.setValue(id, forKey: "me")
+                    Utils.setProfile(value: false)
+                    UserDefaults.standard.synchronize()
+                    if Utils.getForceAnonymous() {
+                        viewController?.deleteAllRecordDatabase()
+                        UserDefaults.standard.removeObject(forKey: "device_id")
+                        Nexilis.destroyAll()
+                        _ = Nexilis.write(message: CoreMessage_TMessageBank.getPostRegistration(p_pin: id))
+                    }
+                    DispatchQueue.main.async {
+                        Nexilis.hideLoader(completion: {
+                            if Nexilis.showFB {
+                                Nexilis.floatingButton.removeFromSuperview()
+                                Nexilis.floatingButton = FloatingButton()
+                                let viewController = (UIApplication.shared.windows.first?.rootViewController)!
+                                Nexilis.addFB(viewController: viewController, fromMAB: true)
+                            }
+                            var dataImage: [AnyHashable : Any] = [:]
+                            dataImage["name"] = ""
+                            NotificationCenter.default.post(name: NSNotification.Name(rawValue: "imageFBUpdate"), object: nil, userInfo: dataImage)
+                            NotificationCenter.default.post(name: NSNotification.Name(rawValue: "reloadTabChats"), object: nil, userInfo: nil)
+                        })
+                    }
+                } else {
+                    DispatchQueue.main.async {
+                        Nexilis.hideLoader(completion: {
+                            let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
+                            imageView.tintColor = .white
+                            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)
+                            banner.show()
+                        })
+                    }
+                }
+            } else {
+                DispatchQueue.main.async {
+                    Nexilis.hideLoader(completion: {
+                        let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
+                        imageView.tintColor = .white
+                        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)
+                        banner.show()
+                    })
+                }
+            }
+        }
+        ack(message: message)
+    }
+    
     private func showTransactionApprovalRequest(message: TMessage) -> Void {
         let limit = Utils.getLimitValidTrans()
         let totalPayment = message.getBody(key: CoreMessage_TMessageKey.TOTAL_PAYMENT, default_value: limit)
@@ -221,6 +296,7 @@ class IncomingThread {
                 _ = Nexilis.responseString(packetId: packetId, message: "00", timeout: 3000)
             }
         }
+        ack(message: message)
     }
     
     private func notifyCalling(message: TMessage) -> Void {

+ 23 - 0
appbuilder-ios/NexilisLite/NexilisLite/Source/Nexilis.swift

@@ -59,6 +59,7 @@ public class Nexilis: NSObject {
     public static var floatingButton = FloatingButton()
     
     public static var showButtonFB = false
+    public static var isShowForceSignIn = true
     
     public static var imageCache = NSCache<NSString, UIImage>()
     
@@ -230,6 +231,8 @@ public class Nexilis: NSObject {
                                 cursorData.close()
                             }
                         })
+                    } else if isShowForceSignIn && !Utils.getForceAnonymous() && !Utils.getSetProfile() {
+                        showForceSignIn()
                     }
                     getServiceBank()
                     getPullWorkingArea()
@@ -268,6 +271,8 @@ public class Nexilis: NSObject {
             UIFont.libOverrideInitialize()
         }
         
+        _ = LocationManager()
+        
         //print("MANIA \(UIFont.systemFont(ofSize: 12)) <> \(UIFont.italicSystemFont(ofSize: 12)) <> \(UIFont.boldSystemFont(ofSize: 12))")
     }
     
@@ -524,6 +529,24 @@ public class Nexilis: NSObject {
         })
     }
     
+    public static func showForceSignIn() {
+        let controller = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "changeDevice") as! ChangeDeviceViewController
+        controller.forceLogin = true
+        let navigationController = CustomNavigationController(rootViewController: controller)
+        navigationController.navigationBar.tintColor = .white
+        navigationController.navigationBar.barTintColor = UIApplication.shared.visibleViewController?.traitCollection.userInterfaceStyle == .dark ? .blackDarkMode : .mainColor
+        navigationController.navigationBar.isTranslucent = false
+        navigationController.navigationBar.overrideUserInterfaceStyle = .dark
+        navigationController.navigationBar.barStyle = .black
+        let cancelButtonAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font : UIFont.systemFont(ofSize: 16)]
+        UIBarButtonItem.appearance().setTitleTextAttributes(cancelButtonAttributes, for: .normal)
+        let textAttributes = [NSAttributedString.Key.foregroundColor:UIColor.white]
+        navigationController.navigationBar.titleTextAttributes = textAttributes
+        navigationController.modalPresentationStyle = .fullScreen
+        navigationController.modalTransitionStyle = .crossDissolve
+        UIApplication.shared.visibleViewController?.present(navigationController, animated: true)
+    }
+    
     public static func destroyAll() {
         let onGoingCC = UserDefaults.standard.string(forKey: "onGoingCC") ?? ""
         if !onGoingCC.isEmpty {

+ 400 - 36
appbuilder-ios/NexilisLite/NexilisLite/Source/Utils.swift

@@ -9,6 +9,8 @@
 import Foundation
 import UIKit
 import NotificationBannerSwift
+import nuSDKService
+import CoreLocation
 //import var CommonCrypto.CC_MD5_DIGEST_LENGTH
 //import func CommonCrypto.CC_MD5
 //import typealias CommonCrypto.CC_LONG
@@ -381,6 +383,9 @@ public final class Utils {
     
     public static var inTabChats = false
     
+    public static var longitude = ""
+    public static var latitude = ""
+    
     private static let I_BB = 48   // 0
     private static let I_BBT_1 = 57 // 9
     private static let I_BAT_1 = 65 // A
@@ -623,6 +628,14 @@ public final class Utils {
     public static func getLimitValidTrans() -> String {
         UserDefaults.standard.string(forKey: "pb_set_valid_trans") ?? "100000"
     }
+    
+    public static func setLoginMultipleFPin(value: String) {
+        UserDefaults.standard.set(value, forKey: "pb_login_multiple_f_pin")
+    }
+
+    public static func getLoginMultipleFPin() -> String {
+        UserDefaults.standard.string(forKey: "pb_login_multiple_f_pin") ?? ""
+    }
 }
 public extension UIImage {
     var jpeg: Data? { jpegData(compressionQuality: 1) }  // QUALITY min = 0 / max = 1
@@ -632,46 +645,338 @@ public extension UIImage {
 public extension Data {
     var uiImage: UIImage? { UIImage(data: self) }
 }
-public extension UIDevice {
+public enum ModelIphone : String {
+
+//Simulator
+case simulator     = "simulator/sandbox",
+
+//iPod
+iPod1              = "iPod 1",
+iPod2              = "iPod 2",
+iPod3              = "iPod 3",
+iPod4              = "iPod 4",
+iPod5              = "iPod 5",
+iPod6              = "iPod 6",
+iPod7              = "iPod 7",
+
+//iPad
+iPad2              = "iPad 2",
+iPad3              = "iPad 3",
+iPad4              = "iPad 4",
+iPadAir            = "iPad Air ",
+iPadAir2           = "iPad Air 2",
+iPadAir3           = "iPad Air 3",
+iPadAir4           = "iPad Air 4",
+iPadAir5           = "iPad Air 5",
+iPad5              = "iPad 5", //iPad 2017
+iPad6              = "iPad 6", //iPad 2018
+iPad7              = "iPad 7", //iPad 2019
+iPad8              = "iPad 8", //iPad 2020
+iPad9              = "iPad 9", //iPad 2021
+iPad10             = "iPad 10", //iPad 2022
+
+//iPad Mini
+iPadMini           = "iPad Mini",
+iPadMini2          = "iPad Mini 2",
+iPadMini3          = "iPad Mini 3",
+iPadMini4          = "iPad Mini 4",
+iPadMini5          = "iPad Mini 5",
+iPadMini6          = "iPad Mini 6",
+
+//iPad Pro
+iPadPro9_7         = "iPad Pro 9.7\"",
+iPadPro10_5        = "iPad Pro 10.5\"",
+iPadPro11          = "iPad Pro 11\"",
+iPadPro2_11        = "iPad Pro 11\" 2nd gen",
+iPadPro3_11        = "iPad Pro 11\" 3rd gen",
+iPadPro12_9        = "iPad Pro 12.9\"",
+iPadPro2_12_9      = "iPad Pro 2 12.9\"",
+iPadPro3_12_9      = "iPad Pro 3 12.9\"",
+iPadPro4_12_9      = "iPad Pro 4 12.9\"",
+iPadPro5_12_9      = "iPad Pro 5 12.9\"",
+
+//iPhone
+iPhone4            = "iPhone 4",
+iPhone4S           = "iPhone 4S",
+iPhone5            = "iPhone 5",
+iPhone5S           = "iPhone 5S",
+iPhone5C           = "iPhone 5C",
+iPhone6            = "iPhone 6",
+iPhone6Plus        = "iPhone 6 Plus",
+iPhone6S           = "iPhone 6S",
+iPhone6SPlus       = "iPhone 6S Plus",
+iPhoneSE           = "iPhone SE",
+iPhone7            = "iPhone 7",
+iPhone7Plus        = "iPhone 7 Plus",
+iPhone8            = "iPhone 8",
+iPhone8Plus        = "iPhone 8 Plus",
+iPhoneX            = "iPhone X",
+iPhoneXS           = "iPhone XS",
+iPhoneXSMax        = "iPhone XS Max",
+iPhoneXR           = "iPhone XR",
+iPhone11           = "iPhone 11",
+iPhone11Pro        = "iPhone 11 Pro",
+iPhone11ProMax     = "iPhone 11 Pro Max",
+iPhoneSE2          = "iPhone SE 2nd gen",
+iPhone12Mini       = "iPhone 12 Mini",
+iPhone12           = "iPhone 12",
+iPhone12Pro        = "iPhone 12 Pro",
+iPhone12ProMax     = "iPhone 12 Pro Max",
+iPhone13Mini       = "iPhone 13 Mini",
+iPhone13           = "iPhone 13",
+iPhone13Pro        = "iPhone 13 Pro",
+iPhone13ProMax     = "iPhone 13 Pro Max",
+iPhoneSE3          = "iPhone SE 3nd gen",
+iPhone14           = "iPhone 14",
+iPhone14Plus       = "iPhone 14 Plus",
+iPhone14Pro        = "iPhone 14 Pro",
+iPhone14ProMax     = "iPhone 14 Pro Max",
+iPhone15           = "iPhone 15",
+iPhone15Plus       = "iPhone 15 Plus",
+iPhone15Pro        = "iPhone 15 Pro",
+iPhone15ProMax     = "iPhone 15 Pro Max",
+
+// Apple Watch
+AppleWatch1         = "Apple Watch 1gen",
+AppleWatchS1        = "Apple Watch Series 1",
+AppleWatchS2        = "Apple Watch Series 2",
+AppleWatchS3        = "Apple Watch Series 3",
+AppleWatchS4        = "Apple Watch Series 4",
+AppleWatchS5        = "Apple Watch Series 5",
+AppleWatchSE        = "Apple Watch Special Edition",
+AppleWatchS6        = "Apple Watch Series 6",
+AppleWatchS7        = "Apple Watch Series 7",
+
+//Apple TV
+AppleTV1           = "Apple TV 1gen",
+AppleTV2           = "Apple TV 2gen",
+AppleTV3           = "Apple TV 3gen",
+AppleTV4           = "Apple TV 4gen",
+AppleTV_4K         = "Apple TV 4K",
+AppleTV2_4K        = "Apple TV 4K 2gen",
+AppleTV3_4K        = "Apple TV 4K 3gen",
+
+unrecognized       = "?unrecognized?"
+}
+
+// #-#-#-#-#-#-#-#-#-#-#-#-#
+// MARK: UIDevice extensions
+// #-#-#-#-#-#-#-#-#-#-#-#-#
+
+    public extension UIDevice {
     
-    var modelName: String {
+    var type: ModelIphone {
         var systemInfo = utsname()
         uname(&systemInfo)
-        let machineMirror = Mirror(reflecting: systemInfo.machine)
-        let identifier = machineMirror.children.reduce("") { identifier, element in
-            guard let value = element.value as? Int8, value != 0 else { return identifier }
-            return identifier + String(UnicodeScalar(UInt8(value)))
+        let modelCode = withUnsafePointer(to: &systemInfo.machine) {
+            $0.withMemoryRebound(to: CChar.self, capacity: 1) {
+                ptr in String.init(validatingUTF8: ptr)
+            }
         }
-        
-        switch identifier {
-        case "iPod5,1":                                 return "iPod Touch 5"
-        case "iPod7,1":                                 return "iPod Touch 6"
-        case "iPhone3,1", "iPhone3,2", "iPhone3,3":     return "iPhone 4"
-        case "iPhone4,1":                               return "iPhone 4s"
-        case "iPhone5,1", "iPhone5,2":                  return "iPhone 5"
-        case "iPhone5,3", "iPhone5,4":                  return "iPhone 5c"
-        case "iPhone6,1", "iPhone6,2":                  return "iPhone 5s"
-        case "iPhone7,2":                               return "iPhone 6"
-        case "iPhone7,1":                               return "iPhone 6 Plus"
-        case "iPhone8,1":                               return "iPhone 6s"
-        case "iPhone8,2":                               return "iPhone 6s Plus"
-        case "iPhone9,1", "iPhone9,3":                  return "iPhone 7"
-        case "iPhone9,2", "iPhone9,4":                  return "iPhone 7 Plus"
-        case "iPhone8,4":                               return "iPhone SE"
-        case "iPad2,1", "iPad2,2", "iPad2,3", "iPad2,4":return "iPad 2"
-        case "iPad3,1", "iPad3,2", "iPad3,3":           return "iPad 3"
-        case "iPad3,4", "iPad3,5", "iPad3,6":           return "iPad 4"
-        case "iPad4,1", "iPad4,2", "iPad4,3":           return "iPad Air"
-        case "iPad5,3", "iPad5,4":                      return "iPad Air 2"
-        case "iPad2,5", "iPad2,6", "iPad2,7":           return "iPad Mini"
-        case "iPad4,4", "iPad4,5", "iPad4,6":           return "iPad Mini 2"
-        case "iPad4,7", "iPad4,8", "iPad4,9":           return "iPad Mini 3"
-        case "iPad5,1", "iPad5,2":                      return "iPad Mini 4"
-        case "iPad6,3", "iPad6,4", "iPad6,7", "iPad6,8":return "iPad Pro"
-        case "AppleTV5,3":                              return "Apple TV"
-        case "i386", "x86_64":                          return "Simulator"
-        default:                                        return identifier
+    
+        let modelMap : [String: ModelIphone] = [
+    
+            //Simulator
+            "i386"      : .simulator,
+            "x86_64"    : .simulator,
+    
+            //iPod
+            "iPod1,1"   : .iPod1,
+            "iPod2,1"   : .iPod2,
+            "iPod3,1"   : .iPod3,
+            "iPod4,1"   : .iPod4,
+            "iPod5,1"   : .iPod5,
+            "iPod7,1"   : .iPod6,
+            "iPod9,1"   : .iPod7,
+    
+            //iPad
+            "iPad2,1"   : .iPad2,
+            "iPad2,2"   : .iPad2,
+            "iPad2,3"   : .iPad2,
+            "iPad2,4"   : .iPad2,
+            "iPad3,1"   : .iPad3,
+            "iPad3,2"   : .iPad3,
+            "iPad3,3"   : .iPad3,
+            "iPad3,4"   : .iPad4,
+            "iPad3,5"   : .iPad4,
+            "iPad3,6"   : .iPad4,
+            "iPad6,11"  : .iPad5, //iPad 2017
+            "iPad6,12"  : .iPad5,
+            "iPad7,5"   : .iPad6, //iPad 2018
+            "iPad7,6"   : .iPad6,
+            "iPad7,11"  : .iPad7, //iPad 2019
+            "iPad7,12"  : .iPad7,
+            "iPad11,6"  : .iPad8, //iPad 2020
+            "iPad11,7"  : .iPad8,
+            "iPad12,1"  : .iPad9, //iPad 2021
+            "iPad12,2"  : .iPad9,
+            "iPad13,18" : .iPad10,
+            "iPad13,19" : .iPad10,
+    
+            //iPad Mini
+            "iPad2,5"   : .iPadMini,
+            "iPad2,6"   : .iPadMini,
+            "iPad2,7"   : .iPadMini,
+            "iPad4,4"   : .iPadMini2,
+            "iPad4,5"   : .iPadMini2,
+            "iPad4,6"   : .iPadMini2,
+            "iPad4,7"   : .iPadMini3,
+            "iPad4,8"   : .iPadMini3,
+            "iPad4,9"   : .iPadMini3,
+            "iPad5,1"   : .iPadMini4,
+            "iPad5,2"   : .iPadMini4,
+            "iPad11,1"  : .iPadMini5,
+            "iPad11,2"  : .iPadMini5,
+            "iPad14,1"  : .iPadMini6,
+            "iPad14,2"  : .iPadMini6,
+    
+            //iPad Pro
+            "iPad6,3"   : .iPadPro9_7,
+            "iPad6,4"   : .iPadPro9_7,
+            "iPad7,3"   : .iPadPro10_5,
+            "iPad7,4"   : .iPadPro10_5,
+            "iPad6,7"   : .iPadPro12_9,
+            "iPad6,8"   : .iPadPro12_9,
+            "iPad7,1"   : .iPadPro2_12_9,
+            "iPad7,2"   : .iPadPro2_12_9,
+            "iPad8,1"   : .iPadPro11,
+            "iPad8,2"   : .iPadPro11,
+            "iPad8,3"   : .iPadPro11,
+            "iPad8,4"   : .iPadPro11,
+            "iPad8,9"   : .iPadPro2_11,
+            "iPad8,10"  : .iPadPro2_11,
+            "iPad13,4"  : .iPadPro3_11,
+            "iPad13,5"  : .iPadPro3_11,
+            "iPad13,6"  : .iPadPro3_11,
+            "iPad13,7"  : .iPadPro3_11,
+            "iPad8,5"   : .iPadPro3_12_9,
+            "iPad8,6"   : .iPadPro3_12_9,
+            "iPad8,7"   : .iPadPro3_12_9,
+            "iPad8,8"   : .iPadPro3_12_9,
+            "iPad8,11"  : .iPadPro4_12_9,
+            "iPad8,12"  : .iPadPro4_12_9,
+            "iPad13,8"  : .iPadPro5_12_9,
+            "iPad13,9"  : .iPadPro5_12_9,
+            "iPad13,10" : .iPadPro5_12_9,
+            "iPad13,11" : .iPadPro5_12_9,
+    
+            //iPad Air
+            "iPad4,1"   : .iPadAir,
+            "iPad4,2"   : .iPadAir,
+            "iPad4,3"   : .iPadAir,
+            "iPad5,3"   : .iPadAir2,
+            "iPad5,4"   : .iPadAir2,
+            "iPad11,3"  : .iPadAir3,
+            "iPad11,4"  : .iPadAir3,
+            "iPad13,1"  : .iPadAir4,
+            "iPad13,2"  : .iPadAir4,
+            "iPad13,16" : .iPadAir5,
+            "iPad13,17" : .iPadAir5,
+    
+            //iPhone
+            "iPhone3,1" : .iPhone4,
+            "iPhone3,2" : .iPhone4,
+            "iPhone3,3" : .iPhone4,
+            "iPhone4,1" : .iPhone4S,
+            "iPhone5,1" : .iPhone5,
+            "iPhone5,2" : .iPhone5,
+            "iPhone5,3" : .iPhone5C,
+            "iPhone5,4" : .iPhone5C,
+            "iPhone6,1" : .iPhone5S,
+            "iPhone6,2" : .iPhone5S,
+            "iPhone7,1" : .iPhone6Plus,
+            "iPhone7,2" : .iPhone6,
+            "iPhone8,1" : .iPhone6S,
+            "iPhone8,2" : .iPhone6SPlus,
+            "iPhone8,4" : .iPhoneSE,
+            "iPhone9,1" : .iPhone7,
+            "iPhone9,3" : .iPhone7,
+            "iPhone9,2" : .iPhone7Plus,
+            "iPhone9,4" : .iPhone7Plus,
+            "iPhone10,1" : .iPhone8,
+            "iPhone10,4" : .iPhone8,
+            "iPhone10,2" : .iPhone8Plus,
+            "iPhone10,5" : .iPhone8Plus,
+            "iPhone10,3" : .iPhoneX,
+            "iPhone10,6" : .iPhoneX,
+            "iPhone11,2" : .iPhoneXS,
+            "iPhone11,4" : .iPhoneXSMax,
+            "iPhone11,6" : .iPhoneXSMax,
+            "iPhone11,8" : .iPhoneXR,
+            "iPhone12,1" : .iPhone11,
+            "iPhone12,3" : .iPhone11Pro,
+            "iPhone12,5" : .iPhone11ProMax,
+            "iPhone12,8" : .iPhoneSE2,
+            "iPhone13,1" : .iPhone12Mini,
+            "iPhone13,2" : .iPhone12,
+            "iPhone13,3" : .iPhone12Pro,
+            "iPhone13,4" : .iPhone12ProMax,
+            "iPhone14,4" : .iPhone13Mini,
+            "iPhone14,5" : .iPhone13,
+            "iPhone14,2" : .iPhone13Pro,
+            "iPhone14,3" : .iPhone13ProMax,
+            "iPhone14,6" : .iPhoneSE3,
+            "iPhone14,7" : .iPhone14,
+            "iPhone14,8" : .iPhone14Plus,
+            "iPhone15,2" : .iPhone14Pro,
+            "iPhone15,3" : .iPhone14ProMax,
+            "iPhone15,4" : .iPhone15,
+            "iPhone15,5" : .iPhone15Plus,
+            "iPhone16,1" : .iPhone15Pro,
+            "iPhone16,2" : .iPhone15ProMax,
+            
+            // Apple Watch
+            "Watch1,1" : .AppleWatch1,
+            "Watch1,2" : .AppleWatch1,
+            "Watch2,6" : .AppleWatchS1,
+            "Watch2,7" : .AppleWatchS1,
+            "Watch2,3" : .AppleWatchS2,
+            "Watch2,4" : .AppleWatchS2,
+            "Watch3,1" : .AppleWatchS3,
+            "Watch3,2" : .AppleWatchS3,
+            "Watch3,3" : .AppleWatchS3,
+            "Watch3,4" : .AppleWatchS3,
+            "Watch4,1" : .AppleWatchS4,
+            "Watch4,2" : .AppleWatchS4,
+            "Watch4,3" : .AppleWatchS4,
+            "Watch4,4" : .AppleWatchS4,
+            "Watch5,1" : .AppleWatchS5,
+            "Watch5,2" : .AppleWatchS5,
+            "Watch5,3" : .AppleWatchS5,
+            "Watch5,4" : .AppleWatchS5,
+            "Watch5,9" : .AppleWatchSE,
+            "Watch5,10" : .AppleWatchSE,
+            "Watch5,11" : .AppleWatchSE,
+            "Watch5,12" : .AppleWatchSE,
+            "Watch6,1" : .AppleWatchS6,
+            "Watch6,2" : .AppleWatchS6,
+            "Watch6,3" : .AppleWatchS6,
+            "Watch6,4" : .AppleWatchS6,
+            "Watch6,6" : .AppleWatchS7,
+            "Watch6,7" : .AppleWatchS7,
+            "Watch6,8" : .AppleWatchS7,
+            "Watch6,9" : .AppleWatchS7,
+    
+            //Apple TV
+            "AppleTV1,1" : .AppleTV1,
+            "AppleTV2,1" : .AppleTV2,
+            "AppleTV3,1" : .AppleTV3,
+            "AppleTV3,2" : .AppleTV3,
+            "AppleTV5,3" : .AppleTV4,
+            "AppleTV6,2" : .AppleTV_4K,
+            "AppleTV11,1" : .AppleTV2_4K,
+            "AppleTV14,1" : .AppleTV3_4K
+        ]
+    
+        guard let mcode = modelCode, let map = String(validatingUTF8: mcode), let model = modelMap[map] else { return ModelIphone.unrecognized }
+        if model == .simulator {
+            if let simModelCode = ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] {
+                if let simMap = String(validatingUTF8: simModelCode), let simModel = modelMap[simMap] {
+                    return simModel
+                }
+            }
         }
+        return model
     }
 }
 
@@ -781,7 +1086,33 @@ public class DialogUnableAccess: UIViewController {
     
     @objc func tryAgainTapped() {
         print("tryAgainTapped")
-        self.dismiss(animated: true)
+        Nexilis.showLoader()
+        if !CheckConnection.isConnectedToNetwork()  || API.nGetCLXConnState() == 0 {
+            let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
+            imageView.tintColor = .white
+            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)
+            banner.show()
+            return
+        }
+        if let response = Nexilis.writeSync(message: CoreMessage_TMessageBank.getAlertNewSignIn(brand: "\(UIDevice().type)", latitude: Utils.latitude, longitude: Utils.longitude), timeout: 30 * 1000) {
+            if response.isOk() {
+                Nexilis.hideLoader(completion: {
+                    self.dismiss(animated: true) {
+                        let dialog = DialogVerifyYou()
+                        dialog.modalTransitionStyle = .crossDissolve
+                        dialog.modalPresentationStyle = .overCurrentContext
+                        UIApplication.shared.visibleViewController?.present(dialog, animated: true)
+                    }
+                })
+            } else {
+                Nexilis.hideLoader(completion: {
+                    let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
+                    imageView.tintColor = .white
+                    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)
+                    banner.show()
+                })
+            }
+        }
     }
     
     @objc func cancelTapped() {
@@ -1423,3 +1754,36 @@ public class ValidationTransactionLimit: UIViewController, UITextFieldDelegate {
         return formattedString
     }
 }
+
+class LocationManager: NSObject, CLLocationManagerDelegate {
+    private var locationManager = CLLocationManager()
+
+    override init() {
+        super.init()
+
+        self.locationManager.delegate = self
+        self.locationManager.requestWhenInUseAuthorization()
+        self.locationManager.startUpdatingLocation()
+        
+        if let location = locationManager.location {
+            let latitude = location.coordinate.latitude
+            let longitude = location.coordinate.longitude
+            Utils.latitude = "\(latitude)"
+            Utils.longitude = "\(longitude)"
+        }
+    }
+
+    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
+        print("didUpdateLocations")
+        if let location = locations.last {
+            let latitude = location.coordinate.latitude
+            let longitude = location.coordinate.longitude
+            Utils.latitude = "\(latitude)"
+            Utils.longitude = "\(longitude)"
+        }
+    }
+
+    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
+        print("Failed to find user's location: \(error.localizedDescription)")
+    }
+}

+ 6 - 6
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Call/QmeraAudioConference.swift

@@ -279,12 +279,12 @@ class QmeraAudioConference: UIViewController {
     @objc func didSpeaker(sender: Any?) {
         isSpeaker = !isSpeaker
         speaker.isSelected = isSpeaker
-        do {
-            if "iPhone 6" == UIDevice.current.modelName {
-                try AVAudioSession.sharedInstance().overrideOutputAudioPort(isSpeaker ? .speaker : .none)
-            }
-        } catch {
-        }
+//        do {
+//            if "iPhone 6" == "\(UIDevice().type)" {
+//                try AVAudioSession.sharedInstance().overrideOutputAudioPort(isSpeaker ? .speaker : .none)
+//            }
+//        } catch {
+//        }
     }
     
     @objc func didInvite(sender: Any?) {

+ 1 - 1
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Control/ProfileViewController.swift

@@ -196,7 +196,7 @@ public class ProfileViewController: UITableViewController {
         profile.isUserInteractionEnabled = true
         profile.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(profileTapped)))
         
-        self.view.backgroundColor = self.traitCollection.userInterfaceStyle == .dark ? .black : .white
+//        self.view.backgroundColor = self.traitCollection.userInterfaceStyle == .dark ? .black : .white
         
         if fromRootViewController {
             navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(didTapExit(sender:)))

+ 4 - 0
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Control/SettingTableViewController.swift

@@ -498,6 +498,10 @@ public class SettingTableViewController: UITableViewController, UIGestureRecogni
                                     NotificationCenter.default.post(name: NSNotification.Name(rawValue: "reloadTabChats"), object: nil, userInfo: nil)
                                     self.makeMenu()
                                     self.tableView.reloadData()
+                                    
+                                    if !Utils.getForceAnonymous() {
+                                        Nexilis.showForceSignIn()
+                                    }
                                 })
                             }
                         } else {

+ 1 - 1
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Control/SignUpSignIn.swift

@@ -22,7 +22,7 @@ public class SignUpSignIn: UIViewController {
     public override func viewDidLoad() {
         super.viewDidLoad()
 
-        self.view.backgroundColor = self.traitCollection.userInterfaceStyle == .dark ? .black : .white
+//        self.view.backgroundColor = self.traitCollection.userInterfaceStyle == .dark ? .black : .white
 
         self.title = "Sign-Up/Sign-In".localized()
         descSignUpSignIn.text = "Please enter your nickname or email address and your password".localized()