How to use the #undef directive in swift 2.3

I want to override or override NSLocalizedString in swift 2.3, and I learn a lot about it, and finally I found a way in Objective-C to do this, as shown below.

 #undef NSLocalizedString #define NSLocalizedString(key,_comment) your_function_name 

I want to quickly implement this functionality. I know only NSLocalizedString is a macro in NSBundle.h for Objective C. So we can override it.but for quick we cannot achieve this. I just want to override or override the NSLocalizedString function for swift. Please help me sort out this. Any help would be appreciated.

+5
source share
3 answers

#undef is a C preprocessor directive and Swift does not support any preprocessor directives , including the complex #define macro used for NSLocalizedString . In fact, it is imported as:

 /// Returns a localized string, using the main bundle if one is not specified. public func NSLocalizedString(_ key: String, tableName: String? = default, bundle: Bundle = default, value: String = default, comment: String) -> String 

However, you can easily accomplish the intended behavior by simply writing your own implementation, which should automatically be used instead. For example :

 public func NSLocalizedString(_ key: String, tableName: String? = nil, bundle: Bundle = Bundle.main, value: String = "", comment: String) -> String { // Do your magic here! return "test" } 

But please do not do this. Would be better just create another function. Otherwise, it is not clear if your function is being used, or you can get: error: ambiguous use of 'NSLocalizedString(_:tableName:bundle:value:comment:)' if you need to change the signature, even if you just want to do something- then optional.

0
source

NSLocalicedString is a global method in Swift.

A global function cannot be redefined, but it can be redefined. To override a method, simply declare a new version. The selected function will be based on scale. For instance:

 func NSLocalizedString(_ key: String, tableName: String? = nil, bundle: Bundle = Bundle.main, value: String = "", comment: String) -> String { return "redefined version in the project" } class Test { func NSLocalizedString(_ key: String, tableName: String? = nil, bundle: Bundle = Bundle.main, value: String = "", comment: String) -> String { return "redefined version in Test" } func getLocalizedString() -> String{ return NSLocalizedString("test", comment: "t") } } class Test2 { func NSLocalizedString(_ key: String, tableName: String? = nil, bundle: Bundle = Bundle.main, value: String = "", comment: String) -> String { return "redefined version in Test2" } func getLocalizedString() -> String{ return NSLocalizedString("test", comment: "t") } } NSLocalizedString("test", comment: "t") //will return "redefined version in the project" Test().getLocalizedString() //will return "redefined version in Test" Test2().getLocalizedString() //will return "redefined version in Test2" 
0
source

Found this one , it will be useful for you to use NSLocalizedString in the side classes. tested it on fast 4 with the following settings

 extension NSObject { func NSLocalizedString(_ key: String, comment: String) -> String { return "My custom localization" } static func NSLocalizedString(_ key: String, comment: String) -> String { return "My custom localization" } } class ViewController: UIViewController { @IBOutlet weak var myLabel: UILabel! override func viewDidLoad() { super.viewDidLoad() myLabel.text = NSLocalizedString("mystring",comment:"") } } 

should work the same for swift 2.3 (without underscore before the key parameter)

Update

This requires a workaround when working with closure, because swift will expect you to use NSLocalizedString with self so self.NSLocalizedString("mystring",comment:"") . The workaround in this scenario is to assign the let / var outside the closure.

Example:

  // Doesn't work self.present(anotherVc, animated: true) { [weak self] in self?.myLabel.text = NSLocalizedString("mystring", comment: "") // compiler will throw an error } // Does work let string = NSLocalizedString("mystring", comment: "") self.present(anotherVc, animated: true) { [weak self] in self?.myLabel.text = string } 

For property initializers, the compiler will use a static function, so it is important to set them as

Example:

 class MyClass: NSObject { // This let let myStr = NSLocalizedString("mystring",comment:"") } extension NSObject { func NSLocalizedString(_ key: String, comment: String) -> String { return "My custom localization" } // Uses the static method static func NSLocalizedString(_ key: String, comment: String) -> String { return "My custom localization" } } 
0
source

Source: https://habr.com/ru/post/1273047/


All Articles