Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Override global function in Swift [duplicate]

To provide a fallback language for NSLocalizedString, I'm using this #undef and #define in Objective-C:

#undef NSLocalizedString
#define NSLocalizedString(key, comment) @"NSLocalizedString has been replaced";

This works perfectly well if called from Objective-C, but if called from Swift, the new definition of NSLocalizedString is ignored. (bridging header is configured correctly and works)

Is this possible in Swift, and if so, how?


Note: the real example is here on Github, also see SO answer here

like image 998
Dan Rosenstark Avatar asked Nov 22 '22 04:11

Dan Rosenstark


2 Answers

You can do this for NSObject subclasses like this

extension NSObject {
    func NSLocalizedString(key: String, comment: String) -> String {
        return "yes we have localized an NSObject"
    }
}

What about AnyObject? In this case, you would have to be aware of and conform to the FallbackLanguage protocol in your AnyObject subclass

protocol FallbackLanguage: class {}

// add default implementations
extension FallbackLanguage {
    func NSLocalizedString(key: String, comment: String) -> String {
        return "yes we have localized AnyObject via FallbackLanguage protocol"
    }
}

Notes

  • These two solutions can both be in your project without any issues.
  • If you're calling NSLocalizedString outside of a class instance, you're out of luck.
like image 124
Dan Rosenstark Avatar answered Feb 27 '23 03:02

Dan Rosenstark


You will have to do a global function... the other options will cause all sort of problems, such as retrain cycles, or classes classes witch do not inherit from NSObject(that is only subset of the problems) - this will not work at all. yes global function usually are big no! but that is the only way to "override" global function. , Here is a code I use in production, we had few thousands of string, at some point we had to make our app dynamically localized - and this is what we did.

// Global functions for lagacy code
func NSLocalizedString(_ key: String, comment: String) -> String {
    return key.localized()
}

func NSLocalizedStringInTable(key: String, tableName: String ) -> String {
    return key.localized(using: tableName)
}
like image 42
Alex Avatar answered Feb 27 '23 05:02

Alex