icerockdev / moko-resources

Resources access for mobile (android & ios) Kotlin Multiplatform development
https://moko.icerock.dev/
Apache License 2.0
1.05k stars 118 forks source link

SwiftUI extensions for easier integration #519

Open darronschall opened 1 year ago

darronschall commented 1 year ago

Hello!

I've been using moko-resources, and made some SwiftUI extensions that make integration easier. I added one of these to the README in #486, but have since added a few more.

import shared

extension StringResource {
    func localized() -> String {
        return desc().localized()
    }
}

extension Image {
    init(resourceKey: KeyPath<MR.images, shared.ImageResource>) {
        self.init(uiImage: MR.images()[keyPath: resourceKey].toUIImage()!)
    }
}

extension Text {
    init(resourceKey: KeyPath<MR.strings, StringResource>) {
        self.init(MR.strings()[keyPath: resourceKey].localized())
    }
}

extension Button where Label == Text {
    init(resourceKey: KeyPath<MR.strings, StringResource>, action: @escaping () -> Void) {
        self.init(MR.strings()[keyPath: resourceKey].localized(), action: action)
    }

    init(resourceKey: KeyPath<MR.strings, StringResource>, role: ButtonRole?, action: @escaping () -> Void) {
        self.init(MR.strings()[keyPath: resourceKey].localized(), role: role, action: action)
    }
}

These extensions make integration with SwiftUI easy, e.g.:

Image(resourceKey: \.logo)
Button(resourceKey: \.menu__logout, role: .destructive) {
    viewModel.logout()
}
Text(resourceKey: \.welcome__body)

It might be nice to incorporate these into moko-resources for other projects using SwiftUI.

FelixFalkovsky commented 1 year ago

Will it work with this Canvas ?

FelixFalkovsky commented 1 year ago
import SwiftUI
import shared
import RswiftResources

extension Text {
    init(
        resourceKey: KeyPath<MR.strings, ResourcesStringResource>,
        bundle: KeyPath<MR.strings, ResourcesStringResource>
    ) {
        self.init(
            LocalizedStringKey(MR.strings()[keyPath: resourceKey].resourceId),
            bundle: MR.strings()[keyPath: resourceKey].bundle
        )
    }
}
Text(resourceKey: \.menu_broadcast, bundle: \.menu_broadcast)