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

[#75] [KMM] [Swift] [Integration] As a user, I can see localized text #76

Merged
merged 4 commits into from
Nov 28, 2022
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
[#75] Add Moko for localization
  • Loading branch information
blyscuit committed Nov 23, 2022

Verified

This commit was signed with the committer’s verified signature.
snyk-bot Snyk bot
commit 0643702871c89840832209544b8f2861914da737
2 changes: 1 addition & 1 deletion .github/workflows/ios_review_pull_request.yml
Original file line number Diff line number Diff line change
@@ -26,7 +26,7 @@ jobs:
review_pull_request:
name: Review pull request
runs-on: macOS-latest
timeout-minutes: 30
timeout-minutes: 60
blyscuit marked this conversation as resolved.
Show resolved Hide resolved
steps:
- name: Cancel Previous Runs
uses: styfle/cancel-workflow-action@0.10.0
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@ buildscript {
classpath(Dependency.KOVER)
classpath(Dependency.KOTLIN_SERIALIZATION)
classpath(Dependency.BUILD_KONFIG)
classpath(Dependency.MOKO_RESOURCES_GENERATOR)
}
}

4 changes: 4 additions & 0 deletions buildSrc/src/main/kotlin/appPackage/Dependency.kt
Original file line number Diff line number Diff line change
@@ -40,4 +40,8 @@ object Dependency {
const val KOTEST_FRAMEWORK = "io.kotest:kotest-framework-engine:${Version.KOTEST}"
const val KOTEST_ASSERTIONS = "io.kotest:kotest-assertions-core:${Version.KOTEST}"
const val KOTEST_PROPERTY = "io.kotest:kotest-property:${Version.KOTEST}"

// Resources
const val MOKO_RESOURCES_GENERATOR = "dev.icerock.moko:resources-generator:${Version.MOKO_RESOURCES}"
const val MOKO_RESOURCES = "dev.icerock.moko:resources:${Version.MOKO_RESOURCES}"
}
2 changes: 2 additions & 0 deletions buildSrc/src/main/kotlin/appPackage/Plugin.kt
Original file line number Diff line number Diff line change
@@ -16,4 +16,6 @@ object Plugin {

const val MOCKMP = "org.kodein.mock.mockmp"
const val KSP = "com.google.devtools.ksp"

const val MOKO_RESOURCES = "dev.icerock.mobile.multiplatform-resources"
}
1 change: 1 addition & 0 deletions buildSrc/src/main/kotlin/appPackage/Versions.kt
Original file line number Diff line number Diff line change
@@ -18,4 +18,5 @@ object Version {
const val MOCKMP = "1.6.0"
const val KSP = "1.7.10-1.0.6"
const val KOTEST = "5.5.1"
const val MOKO_RESOURCES = "0.20.1"
}
2 changes: 1 addition & 1 deletion iosApp/Podfile
Original file line number Diff line number Diff line change
@@ -30,7 +30,7 @@ target 'Survey' do

# Development
pod 'SwiftLint'
pod 'Wormholy', :configurations => ['Debug Staging', 'Debug Production']
pod 'Wormholy', :configurations => ['DebugStaging', 'DebugProduction']

# KMM
platform :ios, '14.0'
210 changes: 121 additions & 89 deletions iosApp/Survey.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -23,7 +23,7 @@
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug Staging"
buildConfiguration = "DebugStaging"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
@@ -51,7 +51,7 @@
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug Staging"
buildConfiguration = "DebugStaging"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
@@ -72,7 +72,7 @@
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Debug Staging"
buildConfiguration = "DebugStaging"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
@@ -89,10 +89,10 @@
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug Staging">
buildConfiguration = "DebugStaging">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release Staging"
buildConfiguration = "ReleaseStaging"
minhnimble marked this conversation as resolved.
Show resolved Hide resolved
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
10 changes: 5 additions & 5 deletions iosApp/Survey.xcodeproj/xcshareddata/xcschemes/Survey.xcscheme
Original file line number Diff line number Diff line change
@@ -23,7 +23,7 @@
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug Production"
buildConfiguration = "DebugProduction"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
@@ -51,7 +51,7 @@
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug Production"
buildConfiguration = "DebugProduction"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
@@ -72,7 +72,7 @@
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Debug Production"
buildConfiguration = "DebugProduction"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
@@ -89,10 +89,10 @@
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug Production">
buildConfiguration = "DebugProduction">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release Production"
buildConfiguration = "ReleaseProduction"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
4 changes: 4 additions & 0 deletions iosApp/Survey/Configurations/Plists/Info.plist
Original file line number Diff line number Diff line change
@@ -44,5 +44,9 @@
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>CFBundleLocalizations</key>
<array>
<string>en</string>
</array>
</dict>
</plist>

This file was deleted.

Original file line number Diff line number Diff line change
@@ -77,18 +77,18 @@ struct LoginView: View {
}

var loginField: some View {
TextField(Localize.loginFieldEmail(), text: $email)
TextField(LocalizeId().login_fields_email.localized, text: $email)
blyscuit marked this conversation as resolved.
Show resolved Hide resolved
.keyboardType(.emailAddress)
.primaryTextField()
.accessibility(.login(.emailField))
}

var passwordField: some View {
HStack {
SecureField(Localize.loginFieldPassword(), text: $password)
SecureField(LocalizeId().login_fields_password.localized, text: $password)
.accessibility(.login(.passwordField))
if password.isEmpty {
Button(Localize.loginButtonForgot()) {
Button(LocalizeId().login_button_forgot.localized) {
coordinator.showResetPassword()
}
.overlayButton()
@@ -106,7 +106,7 @@ struct LoginView: View {
coordinator.showHomeLoading()
}
} label: {
Text(Localize.loginButtonLogin())
Text(LocalizeId().login_button_login.localized)
.frame(maxWidth: .infinity)
.primaryButton()
.accessibility(.login(.loginButton))
Original file line number Diff line number Diff line change
@@ -31,7 +31,7 @@ struct ResetPasswordView: View {

Assets.logoWhite.image

Text(Localize.resetPasswordTextInstruction())
Text(LocalizeId().reset_password_text_instruction.localized)
.multilineTextAlignment(.center)

Spacer().frame(maxHeight: 70.0)
@@ -51,15 +51,15 @@ struct ResetPasswordView: View {
}

var emailField: some View {
TextField(Localize.resetPasswordFieldEmail(), text: $email)
TextField(LocalizeId().reset_password_field_email.localized, text: $email)
.keyboardType(.emailAddress)
.primaryTextField()
.accessibility(.resetPassword(.emailField))
}

var resetButton: some View {
Button {} label: {
Text(Localize.resetPasswordButtonReset())
Text(LocalizeId().reset_password_button_reset.localized)
.frame(maxWidth: .infinity)
.primaryButton()
.accessibility(.resetPassword(.resetButton))
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// StringResource+Localized.swift
// Survey
//
// Created by Bliss on 18/10/22.
// Copyright © 2022 Nimble. All rights reserved.
//

import Shared

typealias LocalizeId = MR.strings

extension StringResource {

var localized: String {
blyscuit marked this conversation as resolved.
Show resolved Hide resolved
desc().localized()
}
}
Original file line number Diff line number Diff line change
@@ -8,4 +8,3 @@

typealias Assets = R.image
typealias Fonts = R.font
typealias Localize = R.string.localizable
2 changes: 1 addition & 1 deletion nimble-jsonapi-kotlin
23 changes: 17 additions & 6 deletions shared/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -12,6 +12,7 @@ plugins {
id(Plugin.MOCKMP).version(Version.MOCKMP)
id(Plugin.KSP).version(Version.KSP)
id(Plugin.KOVER)
id(Plugin.MOKO_RESOURCES)
}

version = "1.0"
@@ -30,11 +31,12 @@ kotlin {
podfile = project.file("../iosApp/Podfile")
framework {
baseName = "Shared"
export(Dependency.MOKO_RESOURCES)
}
xcodeConfigurationToNativeBuildType["Debug Staging"] = NativeBuildType.DEBUG
xcodeConfigurationToNativeBuildType["Debug Production"] = NativeBuildType.DEBUG
xcodeConfigurationToNativeBuildType["Release Staging"] = NativeBuildType.RELEASE
xcodeConfigurationToNativeBuildType["Release Production"] = NativeBuildType.RELEASE
xcodeConfigurationToNativeBuildType["DebugStaging"] = NativeBuildType.DEBUG
xcodeConfigurationToNativeBuildType["DebugProduction"] = NativeBuildType.DEBUG
xcodeConfigurationToNativeBuildType["ReleaseStaging"] = NativeBuildType.RELEASE
xcodeConfigurationToNativeBuildType["ReleaseProduction"] = NativeBuildType.RELEASE
}

sourceSets {
@@ -93,6 +95,10 @@ kotlin {
}
}

dependencies {
commonMainApi(Dependency.MOKO_RESOURCES)
}

android {
compileSdk = Android.COMPILE_SDK
sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
@@ -105,7 +111,7 @@ android {
unitTests.all {
if (it.name == "testReleaseUnitTest") {
it.extensions.configure(kotlinx.kover.api.KoverTaskExtension::class) {
isDisabled.set(true)
isDisabled.set(true)
}
}
it.extensions.configure(kotlinx.kover.api.KoverTaskExtension::class) {
@@ -114,7 +120,7 @@ android {
}
}

detekt {
detekt {
source = files(
"./"
)
@@ -208,3 +214,8 @@ kover {
}
}
}

multiplatformResources {
multiplatformResourcesPackage = "co.nimblehq.blisskmmic"
disableStaticFrameworkWarning = true
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package co.nimblehq.blisskmmic.presentation.helpers

import co.nimblehq.blisskmmic.MR
import dev.icerock.moko.resources.AssetResource
import dev.icerock.moko.resources.ResourceContainer
import dev.icerock.moko.resources.StringResource
import dev.icerock.moko.resources.desc.Resource
import dev.icerock.moko.resources.desc.StringDesc

class MokoLocalize {
fun localize(id: String?): StringDesc? {
if (id == MR.strings.common_error.toString()) {
return StringDesc.Resource(MR.strings.common_error)
}
return null
}
minhnimble marked this conversation as resolved.
Show resolved Hide resolved
}
11 changes: 11 additions & 0 deletions shared/src/commonMain/resources/MR/base/strings.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="common_error">An error occurred. Please try again.</string>
<string name="login_fields_email">Email</string>
<string name="login_fields_password">Password</string>
<string name="login_button_login">Log in</string>
<string name="login_button_forgot">Forgot?</string>
<string name="reset_password_field_email">Email</string>
<string name="reset_password_text_instruction">Enter your email to receive instructions for resetting your password.</string>
<string name="reset_password_button_reset">Reset</string>
</resources>
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package co.nimblehq.blisskmmic.presentation.helpers

import co.nimblehq.blisskmmic.MR
import dev.icerock.moko.resources.desc.Resource
import dev.icerock.moko.resources.desc.StringDesc
import io.kotest.matchers.shouldBe
import kotlin.test.Test

class MokoLocalizeTest {

@Test
fun `When calling localize with common_error desc, it returns correct StringDesc`() {
StringDesc.Resource(MR.strings.common_error) shouldBe
MokoLocalize().localize(MR.strings.common_error.toString())
}
blyscuit marked this conversation as resolved.
Show resolved Hide resolved
}
Original file line number Diff line number Diff line change
@@ -5,14 +5,18 @@ import co.nimblehq.blisskmmic.domain.usecase.LogInUseCase
import io.kotest.matchers.shouldBe
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.newSingleThreadContext
import kotlinx.coroutines.test.resetMain
import kotlinx.coroutines.test.runTest
import kotlinx.coroutines.test.setMain
import org.kodein.mock.*
import org.kodein.mock.Fake
import org.kodein.mock.Mock
import org.kodein.mock.tests.TestsWithMocks
import kotlin.test.*
import kotlin.test.AfterTest
import kotlin.test.BeforeTest
import kotlin.test.Test

@ExperimentalCoroutinesApi
class LoginViewModelTest : TestsWithMocks() {