👨‍💻 Your first awesome Swift Script, Part-2

Omar Labib
3 min readJan 11, 2023

Automate your boring localization stuff with a handy Swift script 🔥

In part 1, we built our kit which we will be using now to serve our purpose.

Next create LocaleManager that will serve us add, modify and delete in the localizable files.

Removing Keys..

Here’s how are we going to remove keys from the localizable files.

enum LocaleManager {
static func tryRemovingKey() {
/// 1
print("What key do you want to remove?".inYellow)

/// 2
guard
let key = readLine(), !key.isEmpty else {
print("Invalid Key".inRed)
return
}

/// 3
for relativeFilePath in Utils.localizableFiles {
var fileContent = Utils.contentOf(file: relativeFilePath)

/// 4
guard fileContent.contains(key: key) else {
print("Key \(key) not found at \(relativeFilePath)".inRed)
continue
}

/// 5
fileContent.removeAll(where: { $0.contains(key.quoted) })

let updatedFileContent = fileContent.joined(separator: "\n")

/// 6
let successfulWrite = Utils.write(content: updatedFileContent, to: relativeFilePath)
if successfulWrite {
print("Successfully deleted Key \(key) at \(relativeFilePath)".inGreen)
}
}
}
}

Here’s what’s happening…

  1. We ask the user what key is he trying to remove.
  2. We receive his input, and make sure it’s valid.
  3. We loop through all the localizable files in the directory, read the content of each file.
  4. Make sure each file contains that key, otherwise we continue to next file.
  5. Then we remove that key -along with the value of course, the whole line- from the file.
  6. Finally we override the file with the updated content.

Adding Keys..

Here’s how are we going to add keys from the localizable files.

extension LocaleManager {
static func tryAddingKey() {
/// 1
print("What key do you want to add?".inYellow)
guard
let key = readLine(), !key.isEmpty else {
print("Invalid Key".inRed)
return
}
var filesWithValues: [String: String] = [:]

/// 2
for relativeFilePath in Utils.localizableFiles {
print("Enter value for \(relativeFilePath)".inYellow)

/// 3
guard
let value = readLine(), !value.isEmpty else {
print("Invalid Value".inRed)
return
}
filesWithValues[relativeFilePath] = value
}

for (relativeFilePath, value) in filesWithValues {
/// 4
var fileContent = Utils.contentOf(file: relativeFilePath)
guard !fileContent.contains(key: key) else {
print("Key \(key) already has value at \(relativeFilePath)".inRed)
continue
}

/// 5
let newKeyValue = "\(key.quoted) = \(value.quoted);"
fileContent.append(newKeyValue)

let updatedFileContent = fileContent.joined(separator: "\n")
let successfulWrite = Utils.write(content: updatedFileContent, to: relativeFilePath)
if successfulWrite {
print("Successfully added Key \(key) at \(relativeFilePath)".inGreen)
}
}
}
}

Here’s what’s happening…

  1. We ask the user what key he wants to add, receive his input, and make sure it’s valid input.
  2. We loop through all the localizable files in the directory.
  3. Asks the user for the value of that key in for that file, validate the input and keep it tied to the corresponding file.
  4. Make sure the files doesn’t already contains that key to avoid duplications.
  5. Append the new key-value pair to each file and override the file content.

Modifying Keys

The same way we can modify existing keys.

extension LocaleManager {
static func tryModifyingKey() {
print("What key do you want to Modify it's value?".inYellow)
guard
let key = readLine(), !key.isEmpty else {
print("Invalid Key".inRed)
return
}
var filesWithValues: [String: String] = [:]

for relativeFilePath in Utils.localizableFiles {
print("Enter value for \(relativeFilePath)".inYellow)

guard
let value = readLine(), !value.isEmpty else {
print("Invalid Value".inRed)
continue
}
filesWithValues[relativeFilePath] = value
}

for (relativeFilePath, value) in filesWithValues {
var fileContent = Utils.contentOf(file: relativeFilePath)
guard fileContent.contains(key: key) else {
print("Key \(key) doesn't have value at \(relativeFilePath)".inRed)
continue
}

let index = fileContent.firstIndex(where: { $0.contains(key.quoted) })

let newKeyValue = "\(key.quoted) = \(value.quoted);"
if let index {
fileContent[index] = newKeyValue
} else {
fileContent.append(newKeyValue)
}

let updatedFileContent = fileContent.joined(separator: "\n")
let successfulWrite = Utils.write(content: updatedFileContent, to: relativeFilePath)
if successfulWrite {
print("Successfully Modified value for Key \(key) at \(relativeFilePath)".inGreen)
}
}
}
}

We basically do the same as adding keys, but we need to swap the old key-value pair for the new pair.

Phew, That was quite a lot. Be be at ease, we’re almost done.

In part 3, we will hook every think together and see this script in action.

--

--