问题
I have this code that I need to make reusable by other apps.
This code shows messages where the localized app's name is present.
So, I have localized strings like this:
"DoYou" = "Do you really want to close $$$?";
"Quit" = "Quit $$$";
"Keep Running" = "Keep $$$ Running";
Where $$$
must be replaced with the localized app's name at run time.
Because I want to learn about property wrappers, I have tried to create this one:
extension String {
func findReplace(_ target: String, withString: String) -> String
{
return self.replacingOccurrences(of: target,
with: withString,
options: NSString.CompareOptions.literal,
range: nil)
}
}
@propertyWrapper
struct AdjustTextWithAppName<String> {
private var value: String?
init(wrappedValue: String?) {
self.value = wrappedValue
}
var wrappedValue: String? {
get { value }
set {
if let localizedAppName = Bundle.main.localizedInfoDictionary?["CFBundleName"] as? String {
let replaced = value.findReplace("$$$", withString: localizedAppName)
}
value = nil
}
}
}
I get this error on the replaced
line:
Value of type String? has no name
findReplace
I have also tried to use this line
let replaced = value!.findReplace("$$$", withString: localizedAppName)
Same error...
The string may contain the app's name more than once. This is why I have that extension to String
.
回答1:
To solve this your property wrapper can't have a genereic type named String because that shadows the built-in type String that your extension belongs to. So change the struct
declaration to not be generic
@propertyWrapper
struct AdjustTextWithAppName {
or name the type to something else
@propertyWrapper
struct AdjustTextWithAppName<T> {
and fix the set
method
set {
guard let str = newValue, let localizedAppName = Bundle.main.localizedInfoDictionary?["CFBundleName"] as? String else {
value = nil
}
value = str.findReplace(target: "$$$", withString: localizedAppName)
}
来源:https://stackoverflow.com/questions/59965636/trying-to-make-a-wrapper-for-a-property-that-should-adjust-a-string