普通のアプリの場合は、NSLocalizedStringにキーを渡すだけで大丈夫なのですが、frameworkを公開する場合、デフォルトだとアプリ側のBundleを参照してしまうので、そちらも正しく指定しなくてはいけません。
情報が少なかったので、その方法を記載しておきます。
やること
普通のアプリと同じように、Localizable.stringsを用意します。
Base.lprojを上手く作ってくれない場合があるかもしれませんが、手動で作ればプロジェクトが読み込んでくれます。

そのままBundleを指定せずに、NSLocalizedStringを呼んでしまうと、Bundle.mainの方を呼んでしまうので、Bundle Identifierから参照するようにします。

上の部分を参照して、
Bundle(identifier: "com.flyingalpaca.Uppsala")
のように取得します。
自分はローカライズの部分までまとめて、extensionにしました。好みでcomputed propertyにしてもいいと思います。
extension String { func localized() -> String { guard let bundle = Bundle(identifier: "com.flyingalpaca.Uppsala") else { return self } return NSLocalizedString(self, tableName: nil, bundle: bundle, comment: self) } }
すると、このような感じで呼べます。
"update_notification_title".localized()
サンプル
実際に使うときは、このようにenumのメソッドでさらにラップして使っています。
public class Dialog { /** いろいろ */ public init() { title = LocalizedStringKeys.notificationTitle.localized() } } fileprivate extension Dialog { enum LocalizedStringKeys: String { case notificationTitle = "update_notification_title" case notificationMessage = "update_notification_message" func localized() -> String { return self.rawValue.localized() } } }