diff --git a/TraccarClient.xcodeproj/project.pbxproj b/TraccarClient.xcodeproj/project.pbxproj index d996ba8c30062a9dd3d420a5d9928fdd8a052a5f..027bfbe6c4d2103e0e5878b836c00384a9603877 100644 --- a/TraccarClient.xcodeproj/project.pbxproj +++ b/TraccarClient.xcodeproj/project.pbxproj @@ -15,6 +15,8 @@ 530080392AF15CE000A05E04 /* TransactionsViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 530080372AF15CE000A05E04 /* TransactionsViewController.xib */; }; 5300803D2AF1803100A05E04 /* TransactionTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5300803B2AF1803100A05E04 /* TransactionTableViewCell.swift */; }; 5300803E2AF1803100A05E04 /* TransactionTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5300803C2AF1803100A05E04 /* TransactionTableViewCell.xib */; }; + 5300F2C22AF3BC4E003F2C5F /* FirebaseAnalytics in Frameworks */ = {isa = PBXBuildFile; productRef = 5300F2C12AF3BC4E003F2C5F /* FirebaseAnalytics */; }; + 5300F2C42AF3BC4E003F2C5F /* FirebaseMessaging in Frameworks */ = {isa = PBXBuildFile; productRef = 5300F2C32AF3BC4E003F2C5F /* FirebaseMessaging */; }; 53157EC32AEE3FF9003C9B6A /* API+Auth.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53157EC22AEE3FF9003C9B6A /* API+Auth.swift */; }; 53157EC62AEE4076003C9B6A /* UserModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53157EC52AEE4076003C9B6A /* UserModel.swift */; }; 53157EC82AEE4D6E003C9B6A /* SignInModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53157EC72AEE4D6E003C9B6A /* SignInModel.swift */; }; @@ -107,6 +109,9 @@ 53EBC6072AF1A43900601AA7 /* SettingsSwitchTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 53EBC6052AF1A43900601AA7 /* SettingsSwitchTableViewCell.xib */; }; 53EBC60B2AF1A5C200601AA7 /* SettingsSegmentTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53EBC6092AF1A5C200601AA7 /* SettingsSegmentTableViewCell.swift */; }; 53EBC60C2AF1A5C200601AA7 /* SettingsSegmentTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 53EBC60A2AF1A5C200601AA7 /* SettingsSegmentTableViewCell.xib */; }; + 53EBC6102AF3960800601AA7 /* SettingsLogoutTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53EBC60E2AF3960800601AA7 /* SettingsLogoutTableViewCell.swift */; }; + 53EBC6112AF3960800601AA7 /* SettingsLogoutTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 53EBC60F2AF3960800601AA7 /* SettingsLogoutTableViewCell.xib */; }; + 53EBC6132AF3A1D100601AA7 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 53EBC6122AF3A1D100601AA7 /* GoogleService-Info.plist */; }; 53F10AE22AF05C57004D0529 /* KNNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53F10AE12AF05C57004D0529 /* KNNavigationController.swift */; }; 53F10AE42AF05E68004D0529 /* AuthenticationStep.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53F10AE32AF05E68004D0529 /* AuthenticationStep.swift */; }; 53F10AE62AF05E97004D0529 /* AuthenticationCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53F10AE52AF05E97004D0529 /* AuthenticationCoordinator.swift */; }; @@ -125,8 +130,6 @@ 5E716A2B1F63A60800A2DBC3 /* ProtocolFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E716A2A1F63A60800A2DBC3 /* ProtocolFormatter.swift */; }; 5E716A2E1F63A7A200A2DBC3 /* ProtocolFormatterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E716A2D1F63A7A200A2DBC3 /* ProtocolFormatterTests.swift */; }; 5E716A301F63A9F600A2DBC3 /* RequestManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E716A2F1F63A9F600A2DBC3 /* RequestManagerTests.swift */; }; - 5EE3CA342998948F002C86E4 /* FirebaseAnalytics in Frameworks */ = {isa = PBXBuildFile; productRef = 5EE3CA332998948F002C86E4 /* FirebaseAnalytics */; }; - 5EE3CA362998948F002C86E4 /* FirebaseCrashlytics in Frameworks */ = {isa = PBXBuildFile; productRef = 5EE3CA352998948F002C86E4 /* FirebaseCrashlytics */; }; 5EE3CA39299894B9002C86E4 /* InAppSettingsKit in Frameworks */ = {isa = PBXBuildFile; productRef = 5EE3CA38299894B9002C86E4 /* InAppSettingsKit */; }; CB4197931F674A3E008F301C /* DatabaseHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB4197921F674A3E008F301C /* DatabaseHelper.swift */; }; CB4197951F675518008F301C /* CoreDataTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB4197941F675518008F301C /* CoreDataTests.swift */; }; @@ -272,6 +275,9 @@ 53EBC6052AF1A43900601AA7 /* SettingsSwitchTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = SettingsSwitchTableViewCell.xib; sourceTree = "<group>"; }; 53EBC6092AF1A5C200601AA7 /* SettingsSegmentTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsSegmentTableViewCell.swift; sourceTree = "<group>"; }; 53EBC60A2AF1A5C200601AA7 /* SettingsSegmentTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = SettingsSegmentTableViewCell.xib; sourceTree = "<group>"; }; + 53EBC60E2AF3960800601AA7 /* SettingsLogoutTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsLogoutTableViewCell.swift; sourceTree = "<group>"; }; + 53EBC60F2AF3960800601AA7 /* SettingsLogoutTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = SettingsLogoutTableViewCell.xib; sourceTree = "<group>"; }; + 53EBC6122AF3A1D100601AA7 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; }; 53F10AE12AF05C57004D0529 /* KNNavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KNNavigationController.swift; sourceTree = "<group>"; }; 53F10AE32AF05E68004D0529 /* AuthenticationStep.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationStep.swift; sourceTree = "<group>"; }; 53F10AE52AF05E97004D0529 /* AuthenticationCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationCoordinator.swift; sourceTree = "<group>"; }; @@ -351,14 +357,14 @@ files = ( CBDEEB8A1B8EB6A4006BC126 /* SystemConfiguration.framework in Frameworks */, 53D62E432AEFA4DC00C80BAC /* Lottie in Frameworks */, + 5300F2C42AF3BC4E003F2C5F /* FirebaseMessaging in Frameworks */, 5326839F2AE9489C00A364C0 /* Reachability in Frameworks */, CBCE82EF1B8D253600A7318B /* CoreData.framework in Frameworks */, - 5EE3CA342998948F002C86E4 /* FirebaseAnalytics in Frameworks */, + 5300F2C22AF3BC4E003F2C5F /* FirebaseAnalytics in Frameworks */, CEDB048717ED50C1000E7EDF /* CoreLocation.framework in Frameworks */, CED4879917DB1DF4007FCF57 /* MessageUI.framework in Frameworks */, 532683812AE923DE00A364C0 /* Alamofire in Frameworks */, CED4871C17DB1BF6007FCF57 /* UIKit.framework in Frameworks */, - 5EE3CA362998948F002C86E4 /* FirebaseCrashlytics in Frameworks */, 532683C82AEA631800A364C0 /* IQKeyboardManagerSwift in Frameworks */, 5EE3CA39299894B9002C86E4 /* InAppSettingsKit in Frameworks */, CED4871E17DB1BF6007FCF57 /* Foundation.framework in Frameworks */, @@ -660,6 +666,7 @@ 53EBC5FB2AF199E200601AA7 /* Cells */ = { isa = PBXGroup; children = ( + 53EBC60D2AF395EA00601AA7 /* SettingsLogoutTableViewCell */, 53EBC6082AF1A5A800601AA7 /* SettingsSegmentTableViewCell */, 53EBC6032AF1A41C00601AA7 /* SettingsSwitchTableViewCell */, 53EBC6022AF1A41000601AA7 /* SettingsTextTableViewCell */, @@ -694,6 +701,15 @@ path = SettingsSegmentTableViewCell; sourceTree = "<group>"; }; + 53EBC60D2AF395EA00601AA7 /* SettingsLogoutTableViewCell */ = { + isa = PBXGroup; + children = ( + 53EBC60E2AF3960800601AA7 /* SettingsLogoutTableViewCell.swift */, + 53EBC60F2AF3960800601AA7 /* SettingsLogoutTableViewCell.xib */, + ); + path = SettingsLogoutTableViewCell; + sourceTree = "<group>"; + }; 53F10AF12AF0F267004D0529 /* MainViewController */ = { isa = PBXGroup; children = ( @@ -765,6 +781,7 @@ CED4872217DB1BF6007FCF57 /* Supporting Files */ = { isa = PBXGroup; children = ( + 53EBC6122AF3A1D100601AA7 /* GoogleService-Info.plist */, 5326833E2AE91A6200A364C0 /* Fonts */, CED4872317DB1BF6007FCF57 /* TraccarClient-Info.plist */, 5370B46F2AEFB8A900AE08CC /* splash.json */, @@ -814,13 +831,13 @@ ); name = TraccarClient; packageProductDependencies = ( - 5EE3CA332998948F002C86E4 /* FirebaseAnalytics */, - 5EE3CA352998948F002C86E4 /* FirebaseCrashlytics */, 5EE3CA38299894B9002C86E4 /* InAppSettingsKit */, 532683802AE923DE00A364C0 /* Alamofire */, 5326839E2AE9489C00A364C0 /* Reachability */, 532683C72AEA631800A364C0 /* IQKeyboardManagerSwift */, 53D62E422AEFA4DC00C80BAC /* Lottie */, + 5300F2C12AF3BC4E003F2C5F /* FirebaseAnalytics */, + 5300F2C32AF3BC4E003F2C5F /* FirebaseMessaging */, ); productName = TraccarClient; productReference = CED4871817DB1BF6007FCF57 /* TraccarClient.app */; @@ -885,12 +902,12 @@ ); mainGroup = CED4870F17DB1BF6007FCF57; packageReferences = ( - 5EE3CA322998948F002C86E4 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */, 5EE3CA37299894B9002C86E4 /* XCRemoteSwiftPackageReference "InAppSettingsKit" */, 5326837F2AE923DE00A364C0 /* XCRemoteSwiftPackageReference "Alamofire" */, 5326839D2AE9489C00A364C0 /* XCRemoteSwiftPackageReference "Reachability" */, 532683C62AEA631800A364C0 /* XCRemoteSwiftPackageReference "IQKeyboardManager" */, 53D62E412AEFA4DC00C80BAC /* XCRemoteSwiftPackageReference "lottie-ios" */, + 5300F2C02AF3BC4E003F2C5F /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */, ); productRefGroup = CED4871917DB1BF6007FCF57 /* Products */; projectDirPath = ""; @@ -935,6 +952,7 @@ 53554AE32AED1B480018BAEE /* KNButtonView.xib in Resources */, 5300803E2AF1803100A05E04 /* TransactionTableViewCell.xib in Resources */, 532683542AE91A6F00A364C0 /* Montserrat-LightItalic.ttf in Resources */, + 53EBC6112AF3960800601AA7 /* SettingsLogoutTableViewCell.xib in Resources */, 53F10AF52AF0F306004D0529 /* ConnectViewController.xib in Resources */, 5300802F2AF149D400A05E04 /* SettingsViewController.xib in Resources */, 5326835C2AE91A6F00A364C0 /* Montserrat-ThinItalic.ttf in Resources */, @@ -947,6 +965,7 @@ 5370B4702AEFB8A900AE08CC /* splash.json in Resources */, 532683512AE91A6F00A364C0 /* Montserrat-ExtraLightItalic.ttf in Resources */, 530080392AF15CE000A05E04 /* TransactionsViewController.xib in Resources */, + 53EBC6132AF3A1D100601AA7 /* GoogleService-Info.plist in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -996,6 +1015,7 @@ 532683B52AE98FB600A364C0 /* UIString.swift in Sources */, 5326839C2AE9482300A364C0 /* Network+Error.swift in Sources */, 532683AF2AE94C2F00A364C0 /* NSLayoutConstraints.swift in Sources */, + 53EBC6102AF3960800601AA7 /* SettingsLogoutTableViewCell.swift in Sources */, 53EBC6062AF1A43900601AA7 /* SettingsSwitchTableViewCell.swift in Sources */, CB7ED0821F661B4F00A33FCF /* PositionProvider.swift in Sources */, 5300803D2AF1803100A05E04 /* TransactionTableViewCell.swift in Sources */, @@ -1206,8 +1226,7 @@ ); MARKETING_VERSION = 7.0; OTHER_SWIFT_FLAGS = "-D FIREBASE"; - PRODUCT_BUNDLE_IDENTIFIER = "org.traccar.client.$(PRODUCT_NAME:rfc1034identifier)"; - "PRODUCT_BUNDLE_IDENTIFIER[sdk=iphoneos*]" = org.traccar.client.TraccarClien; + PRODUCT_BUNDLE_IDENTIFIER = com.nmo.ai.teamss; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; SWIFT_OBJC_BRIDGING_HEADER = ""; @@ -1376,8 +1395,7 @@ "@executable_path/Frameworks", ); MARKETING_VERSION = 7.0; - PRODUCT_BUNDLE_IDENTIFIER = "org.traccar.client.$(PRODUCT_NAME:rfc1034identifier)"; - "PRODUCT_BUNDLE_IDENTIFIER[sdk=iphoneos*]" = org.traccar.client.TraccarClien; + PRODUCT_BUNDLE_IDENTIFIER = com.nmo.ai.teamss; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; SWIFT_OBJC_BRIDGING_HEADER = ""; @@ -1409,8 +1427,7 @@ "@executable_path/Frameworks", ); MARKETING_VERSION = 7.0; - PRODUCT_BUNDLE_IDENTIFIER = "org.traccar.client.$(PRODUCT_NAME:rfc1034identifier)"; - "PRODUCT_BUNDLE_IDENTIFIER[sdk=iphoneos*]" = org.traccar.client.TraccarClien; + PRODUCT_BUNDLE_IDENTIFIER = com.nmo.ai.teamss; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; SWIFT_OBJC_BRIDGING_HEADER = ""; @@ -1535,6 +1552,14 @@ /* End XCConfigurationList section */ /* Begin XCRemoteSwiftPackageReference section */ + 5300F2C02AF3BC4E003F2C5F /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/firebase/firebase-ios-sdk"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 10.17.0; + }; + }; 5326837F2AE923DE00A364C0 /* XCRemoteSwiftPackageReference "Alamofire" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/Alamofire/Alamofire"; @@ -1567,14 +1592,6 @@ minimumVersion = 4.3.3; }; }; - 5EE3CA322998948F002C86E4 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/firebase/firebase-ios-sdk"; - requirement = { - kind = upToNextMajorVersion; - minimumVersion = 9.0.0; - }; - }; 5EE3CA37299894B9002C86E4 /* XCRemoteSwiftPackageReference "InAppSettingsKit" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/futuretap/InAppSettingsKit.git"; @@ -1586,6 +1603,16 @@ /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ + 5300F2C12AF3BC4E003F2C5F /* FirebaseAnalytics */ = { + isa = XCSwiftPackageProductDependency; + package = 5300F2C02AF3BC4E003F2C5F /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; + productName = FirebaseAnalytics; + }; + 5300F2C32AF3BC4E003F2C5F /* FirebaseMessaging */ = { + isa = XCSwiftPackageProductDependency; + package = 5300F2C02AF3BC4E003F2C5F /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; + productName = FirebaseMessaging; + }; 532683802AE923DE00A364C0 /* Alamofire */ = { isa = XCSwiftPackageProductDependency; package = 5326837F2AE923DE00A364C0 /* XCRemoteSwiftPackageReference "Alamofire" */; @@ -1606,16 +1633,6 @@ package = 53D62E412AEFA4DC00C80BAC /* XCRemoteSwiftPackageReference "lottie-ios" */; productName = Lottie; }; - 5EE3CA332998948F002C86E4 /* FirebaseAnalytics */ = { - isa = XCSwiftPackageProductDependency; - package = 5EE3CA322998948F002C86E4 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; - productName = FirebaseAnalytics; - }; - 5EE3CA352998948F002C86E4 /* FirebaseCrashlytics */ = { - isa = XCSwiftPackageProductDependency; - package = 5EE3CA322998948F002C86E4 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */; - productName = FirebaseCrashlytics; - }; 5EE3CA38299894B9002C86E4 /* InAppSettingsKit */ = { isa = XCSwiftPackageProductDependency; package = 5EE3CA37299894B9002C86E4 /* XCRemoteSwiftPackageReference "InAppSettingsKit" */; diff --git a/TraccarClient.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/TraccarClient.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index de2080aad6f15279f3c40bb73218914b4af8ec6a..d2550115851bda2d9d3f8b44bedc7b5b2a73e7bb 100644 --- a/TraccarClient.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/TraccarClient.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,12 +1,12 @@ { "pins" : [ { - "identity" : "abseil-cpp-swiftpm", + "identity" : "abseil-cpp-binary", "kind" : "remoteSourceControl", - "location" : "https://github.com/firebase/abseil-cpp-SwiftPM.git", + "location" : "https://github.com/google/abseil-cpp-binary.git", "state" : { - "revision" : "583de9bd60f66b40e78d08599cc92036c2e7e4e1", - "version" : "0.20220203.2" + "revision" : "bfc0b6f81adc06ce5121eb23f628473638d67c5c", + "version" : "1.2022062300.0" } }, { @@ -18,22 +18,13 @@ "version" : "5.8.0" } }, - { - "identity" : "boringssl-swiftpm", - "kind" : "remoteSourceControl", - "location" : "https://github.com/firebase/boringssl-SwiftPM.git", - "state" : { - "revision" : "dd3eda2b05a3f459fc3073695ad1b28659066eab", - "version" : "0.9.1" - } - }, { "identity" : "firebase-ios-sdk", "kind" : "remoteSourceControl", "location" : "https://github.com/firebase/firebase-ios-sdk", "state" : { - "revision" : "7e80c25b51c2ffa238879b07fbfc5baa54bb3050", - "version" : "9.6.0" + "revision" : "8872dbd7d947acf757abab933da10e83c1842280", + "version" : "10.17.0" } }, { @@ -41,8 +32,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/google/GoogleAppMeasurement.git", "state" : { - "revision" : "c1cfde8067668027b23a42c29d11c246152fe046", - "version" : "9.6.0" + "revision" : "6b332152355c372ace9966d8ee76ed191f97025e", + "version" : "10.17.0" } }, { @@ -59,17 +50,17 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/google/GoogleUtilities.git", "state" : { - "revision" : "c38ce365d77b04a9a300c31061c5227589e5597b", - "version" : "7.11.5" + "revision" : "1cd556b33550982ec17f80e358253d905e756f0f", + "version" : "7.11.6" } }, { - "identity" : "grpc-ios", + "identity" : "grpc-binary", "kind" : "remoteSourceControl", - "location" : "https://github.com/grpc/grpc-ios.git", + "location" : "https://github.com/google/grpc-binary.git", "state" : { - "revision" : "8440b914756e0d26d4f4d054a1c1581daedfc5b6", - "version" : "1.44.3-grpc" + "revision" : "a673bc2937fbe886dd1f99c401b01b6d977a9c98", + "version" : "1.49.1" } }, { @@ -77,8 +68,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/google/gtm-session-fetcher.git", "state" : { - "revision" : "5ccda3981422a84186387dbb763ba739178b529c", - "version" : "2.3.0" + "revision" : "d415594121c9e8a4f9d79cecee0965cf35e74dbd", + "version" : "3.1.1" } }, { @@ -90,6 +81,15 @@ "revision" : "08ab93cd15759eed534b821c2ea789d97a0fdca0" } }, + { + "identity" : "interop-ios-for-google-sdks", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/interop-ios-for-google-sdks.git", + "state" : { + "revision" : "2d12673670417654f08f5f90fdd62926dc3a2648", + "version" : "100.0.0" + } + }, { "identity" : "iqkeyboardmanager", "kind" : "remoteSourceControl", @@ -149,8 +149,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-protobuf.git", "state" : { - "revision" : "3c54ab05249f59f2c6641dd2920b8358ea9ed127", - "version" : "1.24.0" + "revision" : "07f7f26ded8df9645c072f220378879c4642e063", + "version" : "1.25.1" } } ], diff --git a/TraccarClient.xcodeproj/project.xcworkspace/xcuserdata/g.makhoul.xcuserdatad/UserInterfaceState.xcuserstate b/TraccarClient.xcodeproj/project.xcworkspace/xcuserdata/g.makhoul.xcuserdatad/UserInterfaceState.xcuserstate index ee97d722ff20244397ecf1f17416f4ff3694b060..a001ccfb39779730bf745416ba61e9bc44c765bd 100644 Binary files a/TraccarClient.xcodeproj/project.xcworkspace/xcuserdata/g.makhoul.xcuserdatad/UserInterfaceState.xcuserstate and b/TraccarClient.xcodeproj/project.xcworkspace/xcuserdata/g.makhoul.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/TraccarClient/API+Auth.swift b/TraccarClient/API+Auth.swift index 8e4c37669b071003684b36e1dfe9516e961c87a4..cbde6380c2de110258be39bb1346bf8cc321bc6a 100644 --- a/TraccarClient/API+Auth.swift +++ b/TraccarClient/API+Auth.swift @@ -19,5 +19,15 @@ extension NetworkRequest { completion(result) } } + func logout(_ completion: @escaping ResultClosure) { + request(endpoint: endpoint(.logout), method: .post) { result in + if result.success { + SignInModel.clearUserFromUserDefaults() + UserModel.clearUserFromUserDefaults() + DeviceModel.clearUserFromUserDefaults() + } + completion(result) + } + } } diff --git a/TraccarClient/AppDelegate.swift b/TraccarClient/AppDelegate.swift index af26439fcba58b7889408db9a1405e5556e05579..faff30640639480a9538a915f879801829b3d5af 100644 --- a/TraccarClient/AppDelegate.swift +++ b/TraccarClient/AppDelegate.swift @@ -16,7 +16,8 @@ import UIKit import CoreData -import Firebase +import FirebaseMessaging +import FirebaseCore import IQKeyboardManagerSwift @UIApplicationMain @@ -30,15 +31,25 @@ class AppDelegate: UIResponder, UIApplicationDelegate, PositionProviderDelegate var trackingController: TrackingController? var positionProvider: PositionProvider? + let gcmMessageIDKey = "gcm.Message_ID" static var instance: AppDelegate { return UIApplication.shared.delegate as! AppDelegate } func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]?) -> Bool { -#if FIREBASE FirebaseApp.configure() -#endif + + UNUserNotificationCenter.current().delegate = self + + let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound] + UNUserNotificationCenter.current().requestAuthorization( + options: authOptions, + completionHandler: { _, _ in } + ) + + application.registerForRemoteNotifications() + IQKeyboardManager.shared.enable = true IQKeyboardManager.shared.shouldResignOnTouchOutside = true IQKeyboardManager.shared.previousNextDisplayMode = .alwaysShow @@ -54,6 +65,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate, PositionProviderDelegate registerDefaultsFromSettingsBundle() + Messaging.messaging().delegate = self + migrateLegacyDefaults() let modelUrl = Bundle.main.url(forResource: "TraccarClient", withExtension: "momd") @@ -200,3 +213,71 @@ class AppDelegate: UIResponder, UIApplicationDelegate, PositionProviderDelegate } } +// MARK: - UNUserNotificationCenterDelegate +extension AppDelegate: UNUserNotificationCenterDelegate { + // Receive displayed notifications for iOS 10 devices. + func userNotificationCenter(_ center: UNUserNotificationCenter, + willPresent notification: UNNotification) async + -> UNNotificationPresentationOptions { + let userInfo = notification.request.content.userInfo + + // With swizzling disabled you must let Messaging know about the message, for Analytics + // Messaging.messaging().appDidReceiveMessage(userInfo) + + // ... + + // Print full message. + print(userInfo) + + // Change this to your preferred presentation option + return [[.alert, .sound]] + } + + func userNotificationCenter(_ center: UNUserNotificationCenter, + didReceive response: UNNotificationResponse) async { + let userInfo = response.notification.request.content.userInfo + + // ... + + // With swizzling disabled you must let Messaging know about the message, for Analytics + // Messaging.messaging().appDidReceiveMessage(userInfo) + + // Print full message. + print(userInfo) + } + func application(_ application: UIApplication, + didReceiveRemoteNotification userInfo: [AnyHashable: Any]) async + -> UIBackgroundFetchResult { + // If you are receiving a notification message while your app is in the background, + // this callback will not be fired till the user taps on the notification launching the application. + // TODO: Handle data of notification + + // With swizzling disabled you must let Messaging know about the message, for Analytics + // Messaging.messaging().appDidReceiveMessage(userInfo) + + // Print message ID. + if let messageID = userInfo[gcmMessageIDKey] { + print("Message ID: \(messageID)") + } + + // Print full message. + print(userInfo) + + return UIBackgroundFetchResult.newData + } + +} + +// MARK: - MessagingDelegate +extension AppDelegate: MessagingDelegate { + func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) { + print("Firebase registration token: \(String(describing: fcmToken))") + + let dataDict: [String: String] = ["token": fcmToken ?? ""] + NotificationCenter.default.post( + name: Notification.Name("FCMToken"), + object: nil, + userInfo: dataDict + ) + } +} diff --git a/TraccarClient/GoogleService-Info.plist b/TraccarClient/GoogleService-Info.plist new file mode 100644 index 0000000000000000000000000000000000000000..03227aada837c33da3318334f010409c5d6fb6f1 --- /dev/null +++ b/TraccarClient/GoogleService-Info.plist @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>API_KEY</key> + <string>AIzaSyCwlmc957R6tpX0vrbVFgKWfmrFytU2foI</string> + <key>GCM_SENDER_ID</key> + <string>139516981582</string> + <key>PLIST_VERSION</key> + <string>1</string> + <key>BUNDLE_ID</key> + <string>com.nmo.ai.teams</string> + <key>PROJECT_ID</key> + <string>nmo-teams</string> + <key>STORAGE_BUCKET</key> + <string>nmo-teams.appspot.com</string> + <key>IS_ADS_ENABLED</key> + <false></false> + <key>IS_ANALYTICS_ENABLED</key> + <false></false> + <key>IS_APPINVITE_ENABLED</key> + <true></true> + <key>IS_GCM_ENABLED</key> + <true></true> + <key>IS_SIGNIN_ENABLED</key> + <true></true> + <key>GOOGLE_APP_ID</key> + <string>1:139516981582:ios:eb22608153a000308e6e1f</string> +</dict> +</plist> \ No newline at end of file diff --git a/TraccarClient/Network+Endpoint.swift b/TraccarClient/Network+Endpoint.swift index 2d58c0088d5a758297f96c06c5d1156b37a28f4e..1eea81fec26d6b27c6617208aec77910b0de485c 100644 --- a/TraccarClient/Network+Endpoint.swift +++ b/TraccarClient/Network+Endpoint.swift @@ -30,6 +30,7 @@ enum Endpoint: String, CaseIterable { case all case signin = "fleet-login" + case logout = "logout" // /////////////// // get endpoint with resource diff --git a/TraccarClient/NetworkRequest.swift b/TraccarClient/NetworkRequest.swift index 7af57e642a26344968ae698b7f5629f4f4f1b99a..71c25164c50daf5b0dcfbe4c9bc2781427aafce8 100644 --- a/TraccarClient/NetworkRequest.swift +++ b/TraccarClient/NetworkRequest.swift @@ -30,8 +30,8 @@ final class NetworkRequest: NSObject { // MARK: - HTTP Headers var headers : HTTPHeaders { var _headers: HTTPHeaders = [:] - - _headers["Caontent-Type"] = "application/json" + _headers["Content-Type"] = "application/json" + _headers["Accept"] = "application/json" _headers["Accept-Language"] = "en" _headers["X-App-Client"] = "ios" _headers["x-Company"] = "\(UserDefaults.standard.string(forKey: "xcompany") ?? "")" diff --git a/TraccarClient/SettingsViewController/Cells/SettingsLogoutTableViewCell/SettingsLogoutTableViewCell.swift b/TraccarClient/SettingsViewController/Cells/SettingsLogoutTableViewCell/SettingsLogoutTableViewCell.swift new file mode 100644 index 0000000000000000000000000000000000000000..5ef3f513786f93c64b514d2b0d6c74bbe8c043b2 --- /dev/null +++ b/TraccarClient/SettingsViewController/Cells/SettingsLogoutTableViewCell/SettingsLogoutTableViewCell.swift @@ -0,0 +1,34 @@ +// +// SettingsLogoutTableViewCell.swift +// TraccarClient +// +// Created by George Makhoul on 02/11/2023. +// Copyright © 2023 Traccar. All rights reserved. +// + +import UIKit +protocol SettingsLogoutTableViewCellDelegate { + func logout() +} + +class SettingsLogoutTableViewCell: KNTableViewCell { + // MARK: - Outlets + @IBOutlet weak var titleLabel: UILabel! + + // MARK: - Properties + var delegate: SettingsLogoutTableViewCellDelegate? + + // MARK: - LifeCycle + override func awakeFromNib() { + super.awakeFromNib() + titleLabel.set(text: "", color: .main, font: .semibold(16)) + } + + @IBAction func logoutTapped(_ sender: UIButton) { + delegate?.logout() + } + + func set(title: String) { + titleLabel.set(text: title) + } +} diff --git a/TraccarClient/SettingsViewController/Cells/SettingsLogoutTableViewCell/SettingsLogoutTableViewCell.xib b/TraccarClient/SettingsViewController/Cells/SettingsLogoutTableViewCell/SettingsLogoutTableViewCell.xib new file mode 100644 index 0000000000000000000000000000000000000000..55b982c505889ea8ac7fc63c6fa87106dabe6a23 --- /dev/null +++ b/TraccarClient/SettingsViewController/Cells/SettingsLogoutTableViewCell/SettingsLogoutTableViewCell.xib @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="UTF-8"?> +<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="22155" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES"> + <device id="retina6_12" orientation="portrait" appearance="light"/> + <dependencies> + <deployment identifier="iOS"/> + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22131"/> + <capability name="Safe area layout guides" minToolsVersion="9.0"/> + <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> + </dependencies> + <objects> + <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/> + <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/> + <tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" rowHeight="51" id="KGk-i7-Jjw" customClass="SettingsLogoutTableViewCell" customModule="TraccarClient" customModuleProvider="target"> + <rect key="frame" x="0.0" y="0.0" width="356" height="51"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> + <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM"> + <rect key="frame" x="0.0" y="0.0" width="356" height="51"/> + <autoresizingMask key="autoresizingMask"/> + <subviews> + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="qgN-Rg-e6W"> + <rect key="frame" x="16" y="12" width="324" height="27"/> + <fontDescription key="fontDescription" type="system" pointSize="17"/> + <nil key="textColor"/> + <nil key="highlightedColor"/> + </label> + <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="dbK-zb-xEj"> + <rect key="frame" x="0.0" y="0.0" width="356" height="51"/> + <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/> + <connections> + <action selector="logoutTapped:" destination="KGk-i7-Jjw" eventType="touchUpInside" id="fQZ-53-6gm"/> + </connections> + </button> + </subviews> + <constraints> + <constraint firstItem="qgN-Rg-e6W" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" constant="12" id="2FF-OV-d4W"/> + <constraint firstItem="qgN-Rg-e6W" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="16" id="REK-JA-tCK"/> + <constraint firstItem="dbK-zb-xEj" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" id="RZd-uO-PNS"/> + <constraint firstAttribute="trailing" secondItem="qgN-Rg-e6W" secondAttribute="trailing" constant="16" id="a8S-Fs-n0R"/> + <constraint firstItem="dbK-zb-xEj" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" id="ihi-jr-XmB"/> + <constraint firstAttribute="trailing" secondItem="dbK-zb-xEj" secondAttribute="trailing" id="kHe-Qf-aGN"/> + <constraint firstAttribute="bottom" secondItem="qgN-Rg-e6W" secondAttribute="bottom" constant="12" id="sip-vP-MpV"/> + <constraint firstAttribute="bottom" secondItem="dbK-zb-xEj" secondAttribute="bottom" id="ska-SV-G3f"/> + </constraints> + </tableViewCellContentView> + <viewLayoutGuide key="safeArea" id="njF-e1-oar"/> + <connections> + <outlet property="titleLabel" destination="qgN-Rg-e6W" id="hys-mj-Sbt"/> + </connections> + <point key="canvasLocation" x="166.41221374045801" y="22.183098591549296"/> + </tableViewCell> + </objects> +</document> diff --git a/TraccarClient/SettingsViewController/Cells/SettingsSegmentTableViewCell/SettingsSegmentTableViewCell.swift b/TraccarClient/SettingsViewController/Cells/SettingsSegmentTableViewCell/SettingsSegmentTableViewCell.swift index 1bf43f3017eb5fcbe027e990761f685ea27d0163..6b819297d4eb464059e8d9d2b29fc3cae8d60144 100644 --- a/TraccarClient/SettingsViewController/Cells/SettingsSegmentTableViewCell/SettingsSegmentTableViewCell.swift +++ b/TraccarClient/SettingsViewController/Cells/SettingsSegmentTableViewCell/SettingsSegmentTableViewCell.swift @@ -8,7 +8,7 @@ import UIKit protocol SettingsSegmentTableViewCellDelegate { - func didUpdateSegment(value: String) + func didUpdateSegment(model: DefaultsModel) } class SettingsSegmentTableViewCell: KNTableViewCell { @@ -40,16 +40,18 @@ class SettingsSegmentTableViewCell: KNTableViewCell { @objc private func segmentChanged(_ sender: UISegmentedControl) { switch sender.selectedSegmentIndex { case 0: - defaults.set("low", forKey: model?.key ?? "") + model?.value = "low" + case 1: - defaults.set("medium", forKey: model?.key ?? "") + model?.value = "medium" + case 2: - defaults.set("high", forKey: model?.key ?? "") + model?.value = "high" default: - defaults.set("medium", forKey: model?.key ?? "") + model?.value = "medium" } - delegate?.didUpdateSegment(value: model?.title ?? "") + delegate?.didUpdateSegment(model: model ?? DefaultsModel()) } func set(defaultValue: DefaultsModel, index: Int) { diff --git a/TraccarClient/SettingsViewController/Cells/SettingsSwitchTableViewCell/SettingsSwitchTableViewCell.swift b/TraccarClient/SettingsViewController/Cells/SettingsSwitchTableViewCell/SettingsSwitchTableViewCell.swift index 1bda577b7be890515e17e0a9bf4632fab5515ec1..cffd216f8b91c20efd71bd40a346f8495da9bd67 100644 --- a/TraccarClient/SettingsViewController/Cells/SettingsSwitchTableViewCell/SettingsSwitchTableViewCell.swift +++ b/TraccarClient/SettingsViewController/Cells/SettingsSwitchTableViewCell/SettingsSwitchTableViewCell.swift @@ -9,7 +9,7 @@ import UIKit protocol SettingsSwitchTableViewCellDelegate { - func didUpdateSwitch(value: String) + func didUpdateSwitch(model: DefaultsModel) } class SettingsSwitchTableViewCell: KNTableViewCell { @@ -35,8 +35,8 @@ class SettingsSwitchTableViewCell: KNTableViewCell { } @objc private func switchChanged(_ sender: UISwitch) { - defaults.set(sender.isOn, forKey: model?.key ?? "") - delegate?.didUpdateSwitch(value: model?.title ?? "") + model?.value = sender.isOn + delegate?.didUpdateSwitch(model: model ?? DefaultsModel()) } func set(defaultValue: DefaultsModel, index: Int) { diff --git a/TraccarClient/SettingsViewController/Cells/SettingsTextTableViewCell/SettingsTextTableViewCell.swift b/TraccarClient/SettingsViewController/Cells/SettingsTextTableViewCell/SettingsTextTableViewCell.swift index c4cb0770e6995d95dfbbcfb5f31a59b2987af01c..0d568bd8c41c8a412f6de5558fbb9363ea2046ea 100644 --- a/TraccarClient/SettingsViewController/Cells/SettingsTextTableViewCell/SettingsTextTableViewCell.swift +++ b/TraccarClient/SettingsViewController/Cells/SettingsTextTableViewCell/SettingsTextTableViewCell.swift @@ -8,7 +8,7 @@ import UIKit protocol SettingsTextTableViewCellDelegate { - func didUpdateText(value: String) + func didUpdateText(model: DefaultsModel) } class SettingsTextTableViewCell: KNTableViewCell { @@ -34,7 +34,7 @@ class SettingsTextTableViewCell: KNTableViewCell { valueField.textAlignment = .center valueField.textColor = .black valueField.font = .semibold(16) - valueField.delegate = self + valueField.addTarget(self, action: #selector(textChanged), for: .editingChanged) } func set(defaultValue: DefaultsModel, index: Int) { @@ -45,11 +45,8 @@ class SettingsTextTableViewCell: KNTableViewCell { valueField.text = defaultValue.value as? String ?? "" valueField.keyboardType = defaultValue.keyboardType } -} - -extension SettingsTextTableViewCell: UITextFieldDelegate { - func textFieldDidEndEditing(_ textField: UITextField) { - defaults.set(textField.text, forKey: model?.key ?? "") - delegate?.didUpdateText(value: model?.title ?? "") + @objc func textChanged(_ sender: UITextField) { + model?.value = sender.text + delegate?.didUpdateText(model: model ?? DefaultsModel()) } } diff --git a/TraccarClient/SettingsViewController/DefaultsModel.swift b/TraccarClient/SettingsViewController/DefaultsModel.swift index 90fc57fca7eae20bfdf9a6f3c5db48c4f0ff250e..57e302fa6bd3199708c09234759a7ea070a5f337 100644 --- a/TraccarClient/SettingsViewController/DefaultsModel.swift +++ b/TraccarClient/SettingsViewController/DefaultsModel.swift @@ -14,21 +14,16 @@ struct DefaultsModel { var value: Any? var key: String = "" var keyboardType: UIKeyboardType = .default - var type: Types - init(title: String, value: Any, keyboardType: UIKeyboardType, type: Types, key: String) { + init() { + + } + + init(title: String, value: Any, keyboardType: UIKeyboardType, key: String) { self.title = title self.value = value self.keyboardType = keyboardType - self.type = type self.key = key } } - -enum Types: String { - case integer - case double - case boolean - case string -} diff --git a/TraccarClient/SettingsViewController/SettingsViewController.swift b/TraccarClient/SettingsViewController/SettingsViewController.swift index a3e7415a96b9721fd9c38694936c45be094d9fb1..794db6c710e48a47d6c6b16642e20cb63fea18bc 100644 --- a/TraccarClient/SettingsViewController/SettingsViewController.swift +++ b/TraccarClient/SettingsViewController/SettingsViewController.swift @@ -15,11 +15,31 @@ final class SettingsViewController: KNViewController { @IBOutlet weak var tableView: UITableView! // MARK: - Properties - private var textDefaults: [DefaultsModel] = [DefaultsModel(title: "Frequency", value: UserDefaults.standard.string(forKey: "frequency_preference") ?? "", keyboardType: .numberPad, type: .integer, key: "frequency_preference"), - DefaultsModel(title: "Distance", value: UserDefaults.standard.string(forKey: "distance_preference") ?? "", keyboardType: .numberPad, type: .double, key: "distance_preference"), - DefaultsModel(title: "Angle", value: UserDefaults.standard.string(forKey: "angle_preference") ?? "", keyboardType: .numberPad, type: .double, key: "angle_preference")] - private var switchDefaults: [DefaultsModel] = [DefaultsModel(title: "Offline buffering", value: UserDefaults.standard.bool(forKey: "buffer_preference") , keyboardType: .default, type: .boolean, key: "buffer_preference")] - private var multiChoicesDefaults: [DefaultsModel] = [DefaultsModel(title: "Accuracy", value: UserDefaults.standard.string(forKey: "accuracy_preference") ?? "", keyboardType: .default, type: .string, key: "accuracy_preference")] + private var textDefaults: [DefaultsModel] = [DefaultsModel(title: "Frequency", + value: UserDefaults.standard.string(forKey: "frequency_preference") ?? "", + keyboardType: .numberPad, + key: "frequency_preference"), + + DefaultsModel(title: "Distance", + value: UserDefaults.standard.string(forKey: "distance_preference") ?? "", + keyboardType: .numberPad, + key: "distance_preference"), + + DefaultsModel(title: "Angle", + value: UserDefaults.standard.string(forKey: "angle_preference") ?? "", + keyboardType: .numberPad, + key: "angle_preference")] + + private var switchDefaults: [DefaultsModel] = [DefaultsModel(title: "Offline buffering", + value: UserDefaults.standard.bool(forKey: "buffer_preference") , + keyboardType: .default, + key: "buffer_preference")] + + private var multiChoicesDefaults: [DefaultsModel] = [DefaultsModel(title: "Accuracy", + value: UserDefaults.standard.string(forKey: "accuracy_preference") ?? "", + keyboardType: .default, + key: "accuracy_preference")] + var trackingController: TrackingController? @@ -37,7 +57,8 @@ final class SettingsViewController: KNViewController { tableView.register(cells: [SettingsTextTableViewCell.self, SettingsSwitchTableViewCell.self, - SettingsSegmentTableViewCell.self]) + SettingsSegmentTableViewCell.self, + SettingsLogoutTableViewCell.self]) tableView.allowsSelection = false tableView.separatorStyle = .none @@ -45,19 +66,55 @@ final class SettingsViewController: KNViewController { } extension SettingsViewController: CustomHeaderViewDelegate { func rightButtonTapped(action: RightButtonAction) { - print("") + view.endEditing(true) + alert(confirm: "Yes", destructive: "No", message: "Are you sure you want to change settings?") { + for item in self.textDefaults { + UserDefaults.standard.setValue(item.value, forKey: item.key) + } + for item in self.switchDefaults { + UserDefaults.standard.setValue(item.value, forKey: item.key) + } + for item in self.multiChoicesDefaults { + UserDefaults.standard.setValue(item.value, forKey: item.key) + } + if AppDelegate.instance.trackingController != nil { + AppDelegate.instance.trackingController = TrackingController() + AppDelegate.instance.trackingController?.start() + } + self.dismiss(animated: true) + self.navigationController?.popViewController(animated: true) + } } func leftButtonTapped(action: LeftButtonAction) { self.navigationController?.popViewController(animated: true) } + + func logoutRequest() { + let spinner = spin() + api.logout { result in + spinner.stop() + if result.success { + if let navigation = self.navigationController { + UserModel.clearUserFromUserDefaults() + DeviceModel.clearUserFromUserDefaults() + SignInModel.clearUserFromUserDefaults() + let coordinator = AuthenticationCoordinator(navigationController: navigation) + coordinator.step = .signin + coordinator.start() + } + } else { + ok(result) + } + } + } } // MARK: - UITableViewDelegate extension SettingsViewController: UITableViewDelegate, UITableViewDataSource { func numberOfSections(in tableView: UITableView) -> Int { - 3 + 4 } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { @@ -68,6 +125,8 @@ extension SettingsViewController: UITableViewDelegate, UITableViewDataSource { return multiChoicesDefaults.count case 2: return switchDefaults.count + case 3: + return 1 default: return 0 } @@ -93,6 +152,12 @@ extension SettingsViewController: UITableViewDelegate, UITableViewDataSource { cell.delegate = self return cell } + if indexPath.section == 3 { + let cell = tableView.dequeue(withCell: SettingsLogoutTableViewCell.self) + cell.set(title: "Logout") + cell.delegate = self + return cell + } return UITableViewCell() } @@ -105,27 +170,37 @@ extension SettingsViewController: UITableViewDelegate, UITableViewDataSource { extension SettingsViewController: SettingsTextTableViewCellDelegate, SettingsSwitchTableViewCellDelegate, SettingsSegmentTableViewCellDelegate { - func didUpdateText(value: String) { - DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { - TransactionsViewController.addMessage(NSLocalizedString("\(value) changed", comment: "")) - AppDelegate.instance.trackingController = TrackingController() - AppDelegate.instance.trackingController?.start() + func didUpdateText(model: DefaultsModel) { + for (index, item) in textDefaults.enumerated() { + if item.key == model.key { + textDefaults[index].value = model.value + } } } - func didUpdateSwitch(value: String) { - DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { - TransactionsViewController.addMessage(NSLocalizedString("\(value) changed", comment: "")) - AppDelegate.instance.trackingController = TrackingController() - AppDelegate.instance.trackingController?.start() + func didUpdateSwitch(model: DefaultsModel) { + for (index, item) in switchDefaults.enumerated() { + if item.key == model.key { + switchDefaults[index].value = model.value + } } } - func didUpdateSegment(value: String) { - DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { - TransactionsViewController.addMessage(NSLocalizedString("\(value) changed", comment: "")) - AppDelegate.instance.trackingController = TrackingController() - AppDelegate.instance.trackingController?.start() + func didUpdateSegment(model: DefaultsModel) { + for (index, item) in multiChoicesDefaults.enumerated() { + if item.key == model.key { + multiChoicesDefaults[index].value = model.value + } + } + } +} + +// MARK: - SettingsLogoutTableViewCellDelegate +extension SettingsViewController: SettingsLogoutTableViewCellDelegate { + func logout() { + alert(confirm: "Yes", destructive: "No", message: "Are you sure you want to logout?") { + self.dismiss(animated: true) + self.logoutRequest() } } } diff --git a/TraccarClient/SignInModel.swift b/TraccarClient/SignInModel.swift index e074497c99d399f7f44153ef90b3fc1012b7e6af..ae926c5b32e669c4b62c0750ad3497d65f5b265f 100644 --- a/TraccarClient/SignInModel.swift +++ b/TraccarClient/SignInModel.swift @@ -54,9 +54,6 @@ final class SignInModel: KNObject { class func clearUserFromUserDefaults() { let ud = UserDefaults.standard - ud.removeObject(forKey: Keys.User.access_token) -// ud.removeObject(forKey: Keys.User.user) -// ud.removeObject(forKey: Keys.User.device) } } diff --git a/TraccarClient/TraccarClient-Info.plist b/TraccarClient/TraccarClient-Info.plist index 9cb61f399dc13d0f48af83bfdb6e33f4a001f5c2..cf7480a3207f6c03084238c6704774f81d48fc7c 100644 --- a/TraccarClient/TraccarClient-Info.plist +++ b/TraccarClient/TraccarClient-Info.plist @@ -22,8 +22,6 @@ <string>????</string> <key>CFBundleVersion</key> <string>$(CURRENT_PROJECT_VERSION)</string> - <key>UILaunchStoryboardName</key> - <string>LaunchScreen</string> <key>LSRequiresIPhoneOS</key> <true/> <key>NSAppTransportSecurity</key> @@ -81,8 +79,13 @@ </array> <key>UIBackgroundModes</key> <array> + <string>fetch</string> <string>location</string> + <string>processing</string> + <string>remote-notification</string> </array> + <key>UILaunchStoryboardName</key> + <string>LaunchScreen</string> <key>UIMainStoryboardFile</key> <string>MainStoryboard</string> <key>UIMainStoryboardFile~ipad</key> diff --git a/TraccarClient/TransactionsViewController/TransactionsViewController.swift b/TraccarClient/TransactionsViewController/TransactionsViewController.swift index 8a7afc473866c3dffb0496846fb4cadbbde13a31..d48846e91822b9d567fc4ec13de1c8db3bd8894b 100644 --- a/TraccarClient/TransactionsViewController/TransactionsViewController.swift +++ b/TraccarClient/TransactionsViewController/TransactionsViewController.swift @@ -11,6 +11,7 @@ import UIKit class TransactionsViewController: KNViewController { // MARK: - Outlets @IBOutlet weak var customHeaderView: CustomHeaderView! + @IBOutlet weak var noDataFoundLabel: UILabel! @IBOutlet weak var tableView: UITableView! // MARK: - Properties @@ -22,10 +23,13 @@ class TransactionsViewController: KNViewController { // MARK: - LifeCycle override func viewDidLoad() { super.viewDidLoad() + noDataFoundLabel.set(text: "No Transactions to display yet", color: .main, font: .semibold(16)) + customHeaderView.set(type: .status, delegate: self) setupTableView() } + private func setupTableView() { tableView.delegate = self tableView.dataSource = self @@ -58,6 +62,11 @@ class TransactionsViewController: KNViewController { transactionViewController?.tableView.reloadData() } + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + noDataFoundLabel.isHidden = !TransactionsViewController.messages.isEmpty + } + override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) TransactionsViewController.transactionViewController = self diff --git a/TraccarClient/TransactionsViewController/TransactionsViewController.xib b/TraccarClient/TransactionsViewController/TransactionsViewController.xib index 8f5c31f2fdf18aef12e6d2e9d299a2bf7381e3a6..d50e2e77fe0735718838494e4ed3b3762db8fa47 100644 --- a/TraccarClient/TransactionsViewController/TransactionsViewController.xib +++ b/TraccarClient/TransactionsViewController/TransactionsViewController.xib @@ -12,6 +12,7 @@ <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="TransactionsViewController" customModule="TraccarClient" customModuleProvider="target"> <connections> <outlet property="customHeaderView" destination="0s1-YY-Zyj" id="omR-dw-Dw1"/> + <outlet property="noDataFoundLabel" destination="LuB-kQ-hLt" id="XuI-eW-vNd"/> <outlet property="tableView" destination="tpi-c2-WlY" id="Eim-oG-hC1"/> <outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/> </connections> @@ -28,14 +29,22 @@ <constraint firstAttribute="height" constant="95" id="bvg-rB-2r1"/> </constraints> </view> + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="LuB-kQ-hLt"> + <rect key="frame" x="196.66666666666666" y="426" width="0.0" height="0.0"/> + <fontDescription key="fontDescription" type="system" pointSize="17"/> + <nil key="textColor"/> + <nil key="highlightedColor"/> + </label> <tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="-1" estimatedSectionHeaderHeight="-1" sectionFooterHeight="-1" estimatedSectionFooterHeight="-1" translatesAutoresizingMaskIntoConstraints="NO" id="tpi-c2-WlY"> <rect key="frame" x="0.0" y="115" width="393" height="737"/> - <color key="backgroundColor" systemColor="systemBackgroundColor"/> + <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> </tableView> </subviews> <viewLayoutGuide key="safeArea" id="fnl-2z-Ty3"/> <color key="backgroundColor" systemColor="systemBackgroundColor"/> <constraints> + <constraint firstItem="LuB-kQ-hLt" firstAttribute="centerY" secondItem="i5M-Pr-FkT" secondAttribute="centerY" id="62l-ws-Q0j"/> + <constraint firstItem="LuB-kQ-hLt" firstAttribute="centerX" secondItem="i5M-Pr-FkT" secondAttribute="centerX" id="EnL-QN-SQ1"/> <constraint firstItem="0s1-YY-Zyj" firstAttribute="top" secondItem="i5M-Pr-FkT" secondAttribute="top" id="FqS-OM-KRi"/> <constraint firstItem="0s1-YY-Zyj" firstAttribute="leading" secondItem="fnl-2z-Ty3" secondAttribute="leading" id="G2l-9t-DmM"/> <constraint firstAttribute="bottom" secondItem="tpi-c2-WlY" secondAttribute="bottom" id="M4B-aE-R7O"/> diff --git a/TraccarClient/UserModel.swift b/TraccarClient/UserModel.swift index 13ff2f940e03fb456e9a11cb578384c512584373..47cc527aac2186bbeb812e0fa91e7fd05b1f2bbf 100644 --- a/TraccarClient/UserModel.swift +++ b/TraccarClient/UserModel.swift @@ -96,7 +96,6 @@ final class UserModel: KNObject { ud.removeObject(forKey: Keys.User.lastName) ud.removeObject(forKey: Keys.User.email) ud.removeObject(forKey: Keys.User.avatar) -// ud.removeObject(forKey: Keys.User.cover) ud.removeObject(forKey: Keys.User.designation_id) } }