Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No longer works since the swizzling removal. #46

Closed
eldare opened this issue May 7, 2020 · 4 comments
Closed

No longer works since the swizzling removal. #46

eldare opened this issue May 7, 2020 · 4 comments

Comments

@eldare
Copy link

eldare commented May 7, 2020

I've upgraded from v1.1.3 to v1.2.1, and it stopped working.
LanguageManager.shared.setLanguage(language:) no longer has the same affect.

I went over the commits and noticed v1.1.4 had a change to the swizzling part:
f98e6ee add new comments, remove the swizzling for the bundle
I then tested with v1.1.4, and it doesn't work either.

Do I need to do something new to make it work again, since the swizzle removal?

I don't use StoryBoards and Nibs, everything is done programmatically.
After calling setLanguage(language:) the rootViewController is reloaded as part of my app's architecture.

Thank you.

@eldare eldare changed the title Latest versions stopped working No longer works since the swizzling removal. May 7, 2020
@Abedalkareem
Copy link
Owner

Abedalkareem commented May 7, 2020

Hi,
What exactly stopped working? are you using .localiz()?

if you can also explain what stopped working exactly. like the strings now are not getting localized? or something else?

@eldare
Copy link
Author

eldare commented May 7, 2020

Thank you for the quick response.

Yes, the strings stopped being localized.
And I actually just realised how to resolve it, after reading this issue: #27
Everything is working again.

I've added the code you provided:

public extension String {
  func localiz(comment: String = "") -> String {
    guard let bundle = Bundle.main.path(forResource: LanguageManager.shared.currentLanguage.rawValue, ofType: "lproj") else {
      return NSLocalizedString(self, comment: comment)
    }

    let langBundle = Bundle(path: bundle)
    return NSLocalizedString(self, tableName: nil, bundle: langBundle!, comment: comment)
  }
}

And then changed the Swiftgen template we're using to call the localiz() method:
(unrelated to your lib, I just think it might help someone in the future)

extension Text {
  private static func tr(_ table: String, _ key: String, _ args: CVarArg...) -> String {
    // let format = NSLocalizedString(key, tableName: table, bundle: Bundle(for: BundleToken.self), comment: "")
    let format = key.localiz()
    return String(format: format, locale: Locale.current, arguments: args)
  }
}

@Abedalkareem
If I may suggest, it should be explicitly explained in the README.md, that localiz() needs to be called from v1.1.4+, due to the swizzle removal.
While I'm against swizzling in general, I think cases like these are a good example of when it's ok to swizzle. Too bad you had to remove it.

Also, can you please explain how LanguageManager can function properly without swizzling when it comes to Storyboards and Nibs?

Thanks again.

@eldare eldare closed this as completed May 13, 2020
@Abedalkareem
Copy link
Owner

Hi Eldare,
Sorry for the inconvenience, so actually still I kept swizzling to localize the storyboard and XIB part. as there are no other solutions to do localization for them. so what I'm doing I'm replacing the implementation of awakeFromNib with this:

 @objc func swizzledAwakeFromNib() {
    swizzledAwakeFromNib()

    switch self {
    case let txtf as UITextField:
      txtf.text = txtf.text?.localiz()
      txtf.placeholder = txtf.placeholder?.localiz()
    case let lbl as UILabel:
      lbl.text = lbl.text?.localiz()
    case let tabbar as UITabBar:
      tabbar.items?.forEach({ $0.title = $0.title?.localiz() })
    case let btn as UIButton:
      btn.setTitle(btn.title(for: .normal)?.localiz(), for: .normal)
    case let sgmnt as UISegmentedControl:
      (0 ..< sgmnt.numberOfSegments).forEach { sgmnt.setTitle(sgmnt.titleForSegment(at: $0)?.localiz(), forSegmentAt: $0) }
    case let txtv as UITextView:
      txtv.text = txtv.text?.localiz()
    default:
      break
    }
  }

to localize the text.

Thank you again and sorry for the delay I just so your comment.

@ryanrizzo
Copy link

Hi @Abedalkareem,

I think there may be a better solution than swizzling. You could just override awakeFromNib() like this:

extension UIView {
    open override func awakeFromNib() {
        super.awakeFromNib()
        switch self {
        case let textField as UITextField:
            textField.text = textField.text?.localize()
            textField.placeholder = textField.placeholder?.localize()
        case let label as UILabel:
            label.text = label.text?.localize()
        case let tabBar as UITabBar:
            tabBar.items?.forEach({ $0.title = $0.title?.localize() })
        case let button as UIButton:
            button.setTitle(button.title(for: .normal)?.localize(), for: .normal)
        case let segment as UISegmentedControl:
            (0 ..< segment.numberOfSegments).forEach { segment.setTitle(segment.titleForSegment(at: $0)?.localize(), forSegmentAt: $0) }
        case let textView as UITextView:
            textView.text = textView.text?.localize()
        default:
            break
        }
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants