Технически вы можете загружать локализованные строки из собственных фреймворков Apple. Например, чтобы загрузить из UIKit
, вы должны использовать
let bundle = Bundle(for: UIView.self)
let string = bundle.localizedString(forKey: "Cancel", value: nil, table: nil)
Когда текущим языковым стандартом является немецкий, это дает "Abbrechen"
.
Недостатком этого подхода является то, что вы Вы узнаете только, существует ли указанная строка c во фреймворке во время выполнения.
Лучший обходной путь, о котором я могу подумать, - это определить ключи, которые вы используете сами, и постоянно проверять их с помощью модульный тест.
Например, вы можете собрать все ключи системной строки в перечислении с повторяющимся регистром
public enum SystemStringKey: String, CaseIterable {
case cancel = "Cancel"
...
}
и использовать их для загрузки системных строк через расширение String
public extension String {
static var systemStringBundle: Bundle {
return Bundle(for: UIView.self)
}
static func systemString(for key: SystemStringKey) -> String {
return systemStringBundle.localizedString(forKey: key.rawValue, value: nil, table: nil)
}
}
В коде вы можете использовать системные строки, такие как константы
label.text = .systemString(for: .cancel)
Чтобы проверить их дальнейшее существование, вы можете использовать модульный тест, такой как этот
class SystemStringKeyTests: XCTestCase {
func testAllKeysExist() throws {
let path = try XCTUnwrap(String.systemStringBundle.path(forResource: "Localizable", ofType: "strings"))
let dict = try XCTUnwrap(NSDictionary(contentsOfFile: path))
for key in SystemStringKey.allCases {
XCTAssertNotNil(dict[key.rawValue])
}
}
}
Это не на 100% пуленепробиваемый, так как все еще может случиться, что Apple удалит строку в обновлении iOS, а затем любое выпущенное приложение, использующее эту строку, покажет непереведенную строку Engli sh, пока вы не отправите ее обновление самостоятельно.