From acfa763ae87dcb066d09d607e47573ac9c661941 Mon Sep 17 00:00:00 2001 From: Abdulmalek Zain Date: Thu, 4 Jul 2024 21:27:44 +0400 Subject: [PATCH 1/3] Integrate Siri shortcuts to enable/disable gps tracking --- Intents.intentdefinition | 97 ++++++++++++++++++++++++ TraccarClient.xcodeproj/project.pbxproj | 21 +++++ TraccarClient/AppDelegate.swift | 1 + TraccarClient/StartTrackingIntent.swift | 20 +++++ TraccarClient/StopTrackingIntent.swift | 20 +++++ TraccarClient/TraccarClient.entitlements | 8 ++ 6 files changed, 167 insertions(+) create mode 100644 Intents.intentdefinition create mode 100644 TraccarClient/StartTrackingIntent.swift create mode 100644 TraccarClient/StopTrackingIntent.swift create mode 100644 TraccarClient/TraccarClient.entitlements diff --git a/Intents.intentdefinition b/Intents.intentdefinition new file mode 100644 index 0000000..b2679e9 --- /dev/null +++ b/Intents.intentdefinition @@ -0,0 +1,97 @@ + + + + + INEnums + + INIntentDefinitionModelVersion + 1.2 + INIntentDefinitionNamespace + 1AigIl + INIntentDefinitionSystemVersion + 23F79 + INIntentDefinitionToolsBuildVersion + 15F31d + INIntentDefinitionToolsVersion + 15.4 + INIntents + + + INIntentCategory + generic + INIntentConfigurable + + INIntentDescription + starts tracking with gps + INIntentDescriptionID + 8atNz2 + INIntentEligibleForWidgets + + INIntentManagedParameterCombinations + + + + INIntentParameterCombinationSupportsBackgroundExecution + + INIntentParameterCombinationUpdatesLinked + + + + INIntentName + StartTrackingService + INIntentParameterCombinations + + + + INIntentParameterCombinationIsPrimary + + INIntentParameterCombinationSupportsBackgroundExecution + + + + INIntentResponse + + INIntentResponseCodes + + + INIntentResponseCodeConciseFormatString + yes + INIntentResponseCodeConciseFormatStringID + ZxxgPH + INIntentResponseCodeFormatString + yay + INIntentResponseCodeFormatStringID + 5l9bCc + INIntentResponseCodeName + success + INIntentResponseCodeSuccess + + + + INIntentResponseCodeConciseFormatString + no + INIntentResponseCodeConciseFormatStringID + fwaOIl + INIntentResponseCodeFormatString + nay + INIntentResponseCodeFormatStringID + ziguoJ + INIntentResponseCodeName + failure + + + + INIntentTitle + Start Tracking Service + INIntentTitleID + kVcJ5o + INIntentType + Custom + INIntentVerb + Do + + + INTypes + + + diff --git a/TraccarClient.xcodeproj/project.pbxproj b/TraccarClient.xcodeproj/project.pbxproj index f1739f4..237cb9c 100644 --- a/TraccarClient.xcodeproj/project.pbxproj +++ b/TraccarClient.xcodeproj/project.pbxproj @@ -7,6 +7,8 @@ objects = { /* Begin PBXBuildFile section */ + 58FB0E542C35E708001D55B6 /* StartTrackingIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58FB0E532C35E708001D55B6 /* StartTrackingIntent.swift */; }; + 58FB0E562C35E90A001D55B6 /* StopTrackingIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58FB0E552C35E90A001D55B6 /* StopTrackingIntent.swift */; }; 5E394EBE28A9CC7600396F33 /* BatteryStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E394EBD28A9CC7600396F33 /* BatteryStatus.swift */; }; 5E716A271F63A0B100A2DBC3 /* DistanceCalculator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E716A261F63A0B100A2DBC3 /* DistanceCalculator.swift */; }; 5E716A291F63A45A00A2DBC3 /* RequestManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E716A281F63A45A00A2DBC3 /* RequestManager.swift */; }; @@ -65,6 +67,9 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 58FB0E4F2C35DF7F001D55B6 /* TraccarClient.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = TraccarClient.entitlements; sourceTree = ""; }; + 58FB0E532C35E708001D55B6 /* StartTrackingIntent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StartTrackingIntent.swift; sourceTree = ""; }; + 58FB0E552C35E90A001D55B6 /* StopTrackingIntent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StopTrackingIntent.swift; sourceTree = ""; }; 5E394EBD28A9CC7600396F33 /* BatteryStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BatteryStatus.swift; sourceTree = ""; }; 5E716A261F63A0B100A2DBC3 /* DistanceCalculator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DistanceCalculator.swift; sourceTree = ""; }; 5E716A281F63A45A00A2DBC3 /* RequestManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RequestManager.swift; sourceTree = ""; }; @@ -154,6 +159,15 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 58FB0E522C35E6DE001D55B6 /* Intents */ = { + isa = PBXGroup; + children = ( + 58FB0E532C35E708001D55B6 /* StartTrackingIntent.swift */, + 58FB0E552C35E90A001D55B6 /* StopTrackingIntent.swift */, + ); + name = Intents; + sourceTree = ""; + }; CED4870F17DB1BF6007FCF57 = { isa = PBXGroup; children = ( @@ -190,6 +204,8 @@ CED4872117DB1BF6007FCF57 /* TraccarClient */ = { isa = PBXGroup; children = ( + 58FB0E522C35E6DE001D55B6 /* Intents */, + 58FB0E4F2C35DF7F001D55B6 /* TraccarClient.entitlements */, CE5899C71B115C9100ED70D2 /* Images.xcassets */, CED4873317DB1BF6007FCF57 /* MainStoryboard.storyboard */, CEF643241B919FFA00195CEA /* LaunchScreen.xib */, @@ -389,10 +405,12 @@ files = ( CB7ED0801F6602CD00A33FCF /* Position.swift in Sources */, CBAA0F7F1F68E807008BBBBE /* MainViewController.swift in Sources */, + 58FB0E562C35E90A001D55B6 /* StopTrackingIntent.swift in Sources */, CB7ED0821F661B4F00A33FCF /* PositionProvider.swift in Sources */, CB4197991F67724F008F301C /* NetworkManager.swift in Sources */, CB7ED0841F662BAF00A33FCF /* AppDelegate.swift in Sources */, 5E394EBE28A9CC7600396F33 /* BatteryStatus.swift in Sources */, + 58FB0E542C35E708001D55B6 /* StartTrackingIntent.swift in Sources */, 5E716A2B1F63A60800A2DBC3 /* ProtocolFormatter.swift in Sources */, CBCE82F21B8D265800A7318B /* TraccarClient.xcdatamodeld in Sources */, CBAA0F7D1F68E14C008BBBBE /* StatusViewController.swift in Sources */, @@ -522,6 +540,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = TraccarClient/TraccarClient.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; @@ -692,6 +711,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = TraccarClient/TraccarClient.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CURRENT_PROJECT_VERSION = 59; @@ -723,6 +743,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = TraccarClient/TraccarClient.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; diff --git a/TraccarClient/AppDelegate.swift b/TraccarClient/AppDelegate.swift index 732da69..4f198ba 100644 --- a/TraccarClient/AppDelegate.swift +++ b/TraccarClient/AppDelegate.swift @@ -17,6 +17,7 @@ import UIKit import CoreData import Firebase +import IntentsUI @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate, PositionProviderDelegate { diff --git a/TraccarClient/StartTrackingIntent.swift b/TraccarClient/StartTrackingIntent.swift new file mode 100644 index 0000000..62fd782 --- /dev/null +++ b/TraccarClient/StartTrackingIntent.swift @@ -0,0 +1,20 @@ +import AppIntents +import SwiftUI + +@available(iOS 16, *) +struct StartTrackingIntent: AppIntent { + + static let title: LocalizedStringResource = "Start Tracking Service" + + func perform() async throws -> some IntentResult & ProvidesDialog { + var trackingController: TrackingController? + let userDefaults = UserDefaults.standard + if !userDefaults.bool(forKey: "service_status_preference") { + userDefaults.setValue(true, forKey: "service_status_preference") + await StatusViewController.addMessage(NSLocalizedString("Tracking Service created", comment: "")) + trackingController = TrackingController() + trackingController?.start() + } + return .result(dialog: "Tracking Service Started") + } +} diff --git a/TraccarClient/StopTrackingIntent.swift b/TraccarClient/StopTrackingIntent.swift new file mode 100644 index 0000000..dc65026 --- /dev/null +++ b/TraccarClient/StopTrackingIntent.swift @@ -0,0 +1,20 @@ +import AppIntents +import SwiftUI + +@available(iOS 16, *) +struct StopTrackingIntent: AppIntent { + + static let title: LocalizedStringResource = "Stop Tracking Service" + + func perform() async throws -> some IntentResult & ProvidesDialog { + var trackingController: TrackingController? + let userDefaults = UserDefaults.standard + if userDefaults.bool(forKey: "service_status_preference") { + userDefaults.setValue(false, forKey: "service_status_preference") + await StatusViewController.addMessage(NSLocalizedString("Tracking Service destroyed", comment: "")) + trackingController?.stop() + trackingController = nil + } + return .result(dialog: "Tracking Service Stopped") + } +} diff --git a/TraccarClient/TraccarClient.entitlements b/TraccarClient/TraccarClient.entitlements new file mode 100644 index 0000000..21d95c4 --- /dev/null +++ b/TraccarClient/TraccarClient.entitlements @@ -0,0 +1,8 @@ + + + + + com.apple.developer.siri + + + From 3ae2dd797c7741f440090fa9479d83b69c0c3eb3 Mon Sep 17 00:00:00 2001 From: Abdulmalek Zain Date: Fri, 28 Feb 2025 20:43:20 +0400 Subject: [PATCH 2/3] - reuse existing localized strings for intent messages; -add stop tracking intent description; --- Intents.intentdefinition | 76 ++++++++++++++++++++++++- TraccarClient/StartTrackingIntent.swift | 4 +- TraccarClient/StopTrackingIntent.swift | 4 +- 3 files changed, 79 insertions(+), 5 deletions(-) diff --git a/Intents.intentdefinition b/Intents.intentdefinition index b2679e9..e917775 100644 --- a/Intents.intentdefinition +++ b/Intents.intentdefinition @@ -22,7 +22,7 @@ INIntentConfigurable INIntentDescription - starts tracking with gps + Starts Tracking Service INIntentDescriptionID 8atNz2 INIntentEligibleForWidgets @@ -90,6 +90,80 @@ INIntentVerb Do + + INIntentCategory + generic + INIntentConfigurable + + INIntentDescription + Stops Tracking Service + INIntentDescriptionID + StpTr2 + INIntentEligibleForWidgets + + INIntentManagedParameterCombinations + + + + INIntentParameterCombinationSupportsBackgroundExecution + + INIntentParameterCombinationUpdatesLinked + + + + INIntentName + StopTrackingService + INIntentParameterCombinations + + + + INIntentParameterCombinationIsPrimary + + INIntentParameterCombinationSupportsBackgroundExecution + + + + INIntentResponse + + INIntentResponseCodes + + + INIntentResponseCodeConciseFormatString + yes + INIntentResponseCodeConciseFormatStringID + StpOKh + INIntentResponseCodeFormatString + yay + INIntentResponseCodeFormatStringID + StpYay + INIntentResponseCodeName + success + INIntentResponseCodeSuccess + + + + INIntentResponseCodeConciseFormatString + no + INIntentResponseCodeConciseFormatStringID + StpNOl + INIntentResponseCodeFormatString + nay + INIntentResponseCodeFormatStringID + StpNay + INIntentResponseCodeName + failure + + + + INIntentTitle + Stop Tracking Service + INIntentTitleID + StpTtl + INIntentType + Custom + INIntentVerb + Do + INTypes diff --git a/TraccarClient/StartTrackingIntent.swift b/TraccarClient/StartTrackingIntent.swift index 62fd782..86b7f38 100644 --- a/TraccarClient/StartTrackingIntent.swift +++ b/TraccarClient/StartTrackingIntent.swift @@ -11,10 +11,10 @@ struct StartTrackingIntent: AppIntent { let userDefaults = UserDefaults.standard if !userDefaults.bool(forKey: "service_status_preference") { userDefaults.setValue(true, forKey: "service_status_preference") - await StatusViewController.addMessage(NSLocalizedString("Tracking Service created", comment: "")) + await StatusViewController.addMessage(NSLocalizedString("Service created", comment: "")) trackingController = TrackingController() trackingController?.start() } - return .result(dialog: "Tracking Service Started") + return .result(dialog: .init(stringLiteral: NSLocalizedString("Service created", comment: ""))) } } diff --git a/TraccarClient/StopTrackingIntent.swift b/TraccarClient/StopTrackingIntent.swift index dc65026..fc15ecd 100644 --- a/TraccarClient/StopTrackingIntent.swift +++ b/TraccarClient/StopTrackingIntent.swift @@ -11,10 +11,10 @@ struct StopTrackingIntent: AppIntent { let userDefaults = UserDefaults.standard if userDefaults.bool(forKey: "service_status_preference") { userDefaults.setValue(false, forKey: "service_status_preference") - await StatusViewController.addMessage(NSLocalizedString("Tracking Service destroyed", comment: "")) + await StatusViewController.addMessage(NSLocalizedString("Service destroyed", comment: "")) trackingController?.stop() trackingController = nil } - return .result(dialog: "Tracking Service Stopped") + return .result(dialog: .init(stringLiteral: NSLocalizedString("Service destroyed", comment: ""))) } } From c8296e08727b24da073f9683edd50ddf0b11212f Mon Sep 17 00:00:00 2001 From: Abdulmalek Zain Date: Fri, 28 Feb 2025 21:00:06 +0400 Subject: [PATCH 3/3] localize intent titles --- TraccarClient/Base.lproj/Localizable.strings | 2 ++ TraccarClient/StartTrackingIntent.swift | 2 +- TraccarClient/StopTrackingIntent.swift | 2 +- TraccarClient/de.lproj/Localizable.strings | 2 ++ TraccarClient/es.lproj/Localizable.strings | 2 ++ TraccarClient/fr.lproj/Localizable.strings | 2 ++ TraccarClient/it.lproj/Localizable.strings | 2 ++ TraccarClient/ja.lproj/Localizable.strings | 2 ++ TraccarClient/ko.lproj/Localizable.strings | 2 ++ TraccarClient/nl.lproj/Localizable.strings | 2 ++ TraccarClient/pl.lproj/Localizable.strings | 2 ++ TraccarClient/pt-BR.lproj/Localizable.strings | 2 ++ TraccarClient/pt.lproj/Localizable.strings | 2 ++ TraccarClient/ru.lproj/Localizable.strings | 2 ++ TraccarClient/zh.lproj/Localizable.strings | 2 ++ 15 files changed, 28 insertions(+), 2 deletions(-) diff --git a/TraccarClient/Base.lproj/Localizable.strings b/TraccarClient/Base.lproj/Localizable.strings index 92a31cc..33e614f 100644 --- a/TraccarClient/Base.lproj/Localizable.strings +++ b/TraccarClient/Base.lproj/Localizable.strings @@ -7,3 +7,5 @@ "Invalid server address" = "Invalid server address"; "Invalid server port" = "Invalid server port"; "Invalid frequency value" = "Invalid frequency value"; +"Stop Tracking Service" = "Stop Tracking Service"; +"Start Tracking Service" = "Start Tracking Service"; diff --git a/TraccarClient/StartTrackingIntent.swift b/TraccarClient/StartTrackingIntent.swift index 86b7f38..b1cca9e 100644 --- a/TraccarClient/StartTrackingIntent.swift +++ b/TraccarClient/StartTrackingIntent.swift @@ -4,7 +4,7 @@ import SwiftUI @available(iOS 16, *) struct StartTrackingIntent: AppIntent { - static let title: LocalizedStringResource = "Start Tracking Service" + static let title: LocalizedStringResource = LocalizedStringResource("Start Tracking Service", comment: "Title for start tracking intent") func perform() async throws -> some IntentResult & ProvidesDialog { var trackingController: TrackingController? diff --git a/TraccarClient/StopTrackingIntent.swift b/TraccarClient/StopTrackingIntent.swift index fc15ecd..7c27de4 100644 --- a/TraccarClient/StopTrackingIntent.swift +++ b/TraccarClient/StopTrackingIntent.swift @@ -4,7 +4,7 @@ import SwiftUI @available(iOS 16, *) struct StopTrackingIntent: AppIntent { - static let title: LocalizedStringResource = "Stop Tracking Service" + static let title: LocalizedStringResource = LocalizedStringResource("Stop Tracking Service", comment: "Title for stop tracking intent") func perform() async throws -> some IntentResult & ProvidesDialog { var trackingController: TrackingController? diff --git a/TraccarClient/de.lproj/Localizable.strings b/TraccarClient/de.lproj/Localizable.strings index 7838aa5..fee99e3 100644 --- a/TraccarClient/de.lproj/Localizable.strings +++ b/TraccarClient/de.lproj/Localizable.strings @@ -7,3 +7,5 @@ "Invalid server address" = "Invalid server address"; "Invalid server port" = "Invalid server port"; "Invalid frequency value" = "Invalid frequency value"; +"Stop Tracking Service" = "Stop Tracking Service"; +"Start Tracking Service" = "Start Tracking Service"; diff --git a/TraccarClient/es.lproj/Localizable.strings b/TraccarClient/es.lproj/Localizable.strings index ca7946d..c42a2a8 100644 --- a/TraccarClient/es.lproj/Localizable.strings +++ b/TraccarClient/es.lproj/Localizable.strings @@ -7,3 +7,5 @@ "Invalid server address" = "Invalid server address"; "Invalid server port" = "Invalid server port"; "Invalid frequency value" = "Invalid frequency value"; +"Stop Tracking Service" = "Stop Tracking Service"; +"Start Tracking Service" = "Start Tracking Service"; diff --git a/TraccarClient/fr.lproj/Localizable.strings b/TraccarClient/fr.lproj/Localizable.strings index 7785509..a4ce50c 100644 --- a/TraccarClient/fr.lproj/Localizable.strings +++ b/TraccarClient/fr.lproj/Localizable.strings @@ -7,3 +7,5 @@ "Invalid server address" = "Invalid server address"; "Invalid server port" = "Invalid server port"; "Invalid frequency value" = "Invalid frequency value"; +"Stop Tracking Service" = "Stop Tracking Service"; +"Start Tracking Service" = "Start Tracking Service"; diff --git a/TraccarClient/it.lproj/Localizable.strings b/TraccarClient/it.lproj/Localizable.strings index f564adb..0bc0a7b 100644 --- a/TraccarClient/it.lproj/Localizable.strings +++ b/TraccarClient/it.lproj/Localizable.strings @@ -7,3 +7,5 @@ "Invalid server address" = "Invalid server address"; "Invalid server port" = "Invalid server port"; "Invalid frequency value" = "Invalid frequency value"; +"Stop Tracking Service" = "Stop Tracking Service"; +"Start Tracking Service" = "Start Tracking Service"; diff --git a/TraccarClient/ja.lproj/Localizable.strings b/TraccarClient/ja.lproj/Localizable.strings index 085c411..d563bc3 100644 --- a/TraccarClient/ja.lproj/Localizable.strings +++ b/TraccarClient/ja.lproj/Localizable.strings @@ -7,3 +7,5 @@ "Invalid server address" = "Invalid server address"; "Invalid server port" = "Invalid server port"; "Invalid frequency value" = "Invalid frequency value"; +"Stop Tracking Service" = "Stop Tracking Service"; +"Start Tracking Service" = "Start Tracking Service"; diff --git a/TraccarClient/ko.lproj/Localizable.strings b/TraccarClient/ko.lproj/Localizable.strings index d323218..a2ec6e2 100644 --- a/TraccarClient/ko.lproj/Localizable.strings +++ b/TraccarClient/ko.lproj/Localizable.strings @@ -7,3 +7,5 @@ "Invalid server address" = "Invalid server address"; "Invalid server port" = "Invalid server port"; "Invalid frequency value" = "Invalid frequency value"; +"Stop Tracking Service" = "Stop Tracking Service"; +"Start Tracking Service" = "Start Tracking Service"; diff --git a/TraccarClient/nl.lproj/Localizable.strings b/TraccarClient/nl.lproj/Localizable.strings index 81fa125..3962c4e 100644 --- a/TraccarClient/nl.lproj/Localizable.strings +++ b/TraccarClient/nl.lproj/Localizable.strings @@ -7,3 +7,5 @@ "Invalid server address" = "Invalid server address"; "Invalid server port" = "Invalid server port"; "Invalid frequency value" = "Invalid frequency value"; +"Stop Tracking Service" = "Stop Tracking Service"; +"Start Tracking Service" = "Start Tracking Service"; diff --git a/TraccarClient/pl.lproj/Localizable.strings b/TraccarClient/pl.lproj/Localizable.strings index fee3d1e..c95c06f 100644 --- a/TraccarClient/pl.lproj/Localizable.strings +++ b/TraccarClient/pl.lproj/Localizable.strings @@ -7,3 +7,5 @@ "Invalid server address" = "Invalid server address"; "Invalid server port" = "Invalid server port"; "Invalid frequency value" = "Invalid frequency value"; +"Stop Tracking Service" = "Stop Tracking Service"; +"Start Tracking Service" = "Start Tracking Service"; diff --git a/TraccarClient/pt-BR.lproj/Localizable.strings b/TraccarClient/pt-BR.lproj/Localizable.strings index 10c227e..735ff01 100644 --- a/TraccarClient/pt-BR.lproj/Localizable.strings +++ b/TraccarClient/pt-BR.lproj/Localizable.strings @@ -7,3 +7,5 @@ "Invalid server address" = "Invalid server address"; "Invalid server port" = "Invalid server port"; "Invalid frequency value" = "Invalid frequency value"; +"Stop Tracking Service" = "Stop Tracking Service"; +"Start Tracking Service" = "Start Tracking Service"; diff --git a/TraccarClient/pt.lproj/Localizable.strings b/TraccarClient/pt.lproj/Localizable.strings index 10c227e..735ff01 100644 --- a/TraccarClient/pt.lproj/Localizable.strings +++ b/TraccarClient/pt.lproj/Localizable.strings @@ -7,3 +7,5 @@ "Invalid server address" = "Invalid server address"; "Invalid server port" = "Invalid server port"; "Invalid frequency value" = "Invalid frequency value"; +"Stop Tracking Service" = "Stop Tracking Service"; +"Start Tracking Service" = "Start Tracking Service"; diff --git a/TraccarClient/ru.lproj/Localizable.strings b/TraccarClient/ru.lproj/Localizable.strings index 79fa773..e1b95e8 100644 --- a/TraccarClient/ru.lproj/Localizable.strings +++ b/TraccarClient/ru.lproj/Localizable.strings @@ -7,3 +7,5 @@ "Invalid server address" = "Invalid server address"; "Invalid server port" = "Invalid server port"; "Invalid frequency value" = "Invalid frequency value"; +"Stop Tracking Service" = "Stop Tracking Service"; +"Start Tracking Service" = "Start Tracking Service"; diff --git a/TraccarClient/zh.lproj/Localizable.strings b/TraccarClient/zh.lproj/Localizable.strings index a424ae1..55569a2 100644 --- a/TraccarClient/zh.lproj/Localizable.strings +++ b/TraccarClient/zh.lproj/Localizable.strings @@ -7,3 +7,5 @@ "Invalid server address" = "Invalid server address"; "Invalid server port" = "Invalid server port"; "Invalid frequency value" = "Invalid frequency value"; +"Stop Tracking Service" = "Stop Tracking Service"; +"Start Tracking Service" = "Start Tracking Service";