Преобразование вашего Android-приложения для работы на iOS – учебник
Здесь вы можете узнать, как сделать ваше существующее Android-приложение кроссплатформенным, чтобы оно работало как на Android, так и на iOS. Вы сможете написать код и протестировать его для Android и iOS всего один раз, в одном месте.
В этом учебнике используется пример Android-приложения с одним экраном для ввода имени пользователя и пароля. Данные учетных данных проверяются и сохраняются в базе данных оперативной памяти.
Если вы не знакомы с Kotlin Multiplatform Mobile, вы можете сначала узнать, как создать и настроить кроссплатформенное мобильное приложение с нуля.
Подготовка среды разработки
-
Установите Android Studio 4.2 или Android Studio 2020.3.1 Canary 8 или выше и другие инструменты для кроссплатформенной мобильной разработки на macOS.
В Android Studio создайте новый проект из системы контроля версий:
https://github.com/Kotlin/kmm-integration-sample.-
Переключитесь на представление Проект.
Сделайте ваш код кроссплатформенным
Чтобы ваше приложение работало на iOS, сначала сделайте ваш код кроссплатформенным, а затем используйте этот код в новом приложении для iOS.
Чтобы сделать ваш код кроссплатформенным:
Определите, какой код сделать кроссплатформенным
Определите, какой код вашего Android-приложения лучше всего использовать совместно для iOS, а какой оставить нативным. Простое правило: используйте то, что вы хотите повторно использовать как можно чаще. Бизнес-логика часто одинакова как для Android, так и для iOS, поэтому она отлично подходит для повторного использования.
В вашем примере Android-приложения бизнес-логика хранится в пакете com.jetbrains.simplelogin.androidapp.data. Ваше будущее приложение для iOS будет использовать ту же логику, поэтому вам также следует сделать её кроссплатформенной.
Создайте общий модуль для кроссплатформенного кода
Кроссплатформенный код, используемый как для iOS, так и для Android, хранится в общем модуле. Kotlin Multiplatform предоставляет специальный мастер для создания таких модулей.
В вашем Android-проекте создайте общий модуль Kotlin Multiplatform для вашего кроссплатформенного кода. Позже вы подключите его к вашему существующему Android-приложению и вашему будущему приложению для iOS.
В Android Studio нажмите Файл | Создать | Новый модуль.
-
В списке шаблонов выберите Kotlin Multiplatform Shared Module, введите имя модуля
shared, и выберите Regular framework в списке параметров распространения фреймворка iOS.
Это необходимо для подключения общего модуля к приложению iOS. Нажмите Готово.
Мастер создаст общий модуль Kotlin Multiplatform, обновит файлы конфигурации и создаст файлы с классами, демонстрирующими преимущества Kotlin Multiplatform. Вы можете узнать больше о структуре проекта.
Добавьте зависимость от общего модуля к вашему Android-приложению
Чтобы использовать кроссплатформенный код в вашем Android-приложении, подключите к нему общий модуль, переместите туда код бизнес-логики и сделайте этот код кроссплатформенным.
Убедитесь, что
compileSdkVersionиminSdkVersionвbuild.gradle.ktsмодуляsharedсовпадают с теми, которые находятся вbuild.gradleвашего Android-приложения в модулеapp.
Если они отличаются, обновите их вbuild.gradle.ktsобщего модуля. В противном случае вы столкнетесь с ошибкой компиляции.-
Добавьте зависимость от общего модуля к
build.gradleвашего Android-приложения.dependencies { implementation project(':shared') } -
Синхронизируйте файлы Gradle, нажав Синхронизировать сейчас в предупреждении.
-
Чтобы убедиться, что общий модуль успешно подключен к вашему приложению, выведите результат функции
greeting()в лог, обновив методonCreate()классаLoginActivity.override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) Log.i("Login Activity", "Hello from shared module: " + (Greeting().greeting())) } -
Найдите
Helloв логе, и вы найдете приветствие из общего модуля.
Сделайте бизнес-логику кроссплатформенной
Теперь вы можете извлечь код бизнес-логики в общий модуль Kotlin Multiplatform и сделать его независимым от платформы. Это необходимо для повторного использования кода как для Android, так и для iOS.
-
Переместите код бизнес-логики
com.jetbrains.simplelogin.androidapp.dataиз директорииappв пакетcom.jetbrains.simplelogin.sharedв директорииshared/src/commonMain. Вы можете перетащить пакет или рефакторить его, перемещая все из одной директории в другую. -
Когда Android Studio спросит, что вы хотите сделать, выберите переместить пакет, а затем подтвердите рефакторинг.
-
Проигнорируйте все предупреждения о коде, зависящем от платформы, и нажмите Продолжить.
Удалите специфичный для Android код, заменив его кроссплатформенным кодом Kotlin или подключившись к специфичным для Android API, используя
expectиactualобъявления. См. следующие разделы для подробностей.
Замените специфичный для Android код кроссплатформенным кодом
Чтобы ваш код хорошо работал как на Android, так и на iOS, замените все зависимости JVM на зависимости Kotlin везде, где это возможно.
-
В функции
login()классаLoginDataSource, заменитеIOException, который недоступен в Kotlin, наRuntimeException.// Before return Result.Error(IOException("Error logging in", e))//After return Result.Error(RuntimeException("Error logging in", e)) -
Для проверки электронной почты замените класс
Patternsиз пакетаandroid.utilsна регулярное выражение Kotlin, соответствующее шаблону в классеLoginDataValidator.// Before private fun isEmailValid(email: String) = Patterns.EMAIL_ADDRESS.matcher(email).matches()
// After private fun isEmailValid(email: String) = emailRegex.matches(email) companion object { private val emailRegex = ("[a-zA-Z0-9\\+\\.\\_\\%\\-\\+]{1,256}" + "\\@" + "[a-zA-Z0-9][a-zA-Z0-9\\-]{0,64}" + "(" + "\\." + "[a-zA-Z0-9][a-zA-Z0-9\\-]{0,25}" + ")+").toRegex() }
Подключение к специфичным для платформы API из кроссплатформенного кода
Универсальный уникальный идентификатор (UUID) для fakeUser в LoginDataSource генерируется с помощью класса java.util.UUID, который недоступен для iOS.
val fakeUser = LoggedInUser(java.util.UUID.randomUUID().toString(), "Jane Doe")
Поскольку стандартная библиотека Kotlin не предоставляет функциональность для генерации UUID, вам все еще необходимо использовать специфичную для платформы функциональность для этого случая.
Предоставьте объявление expect для функции randomUUID() в общем коде и её реализации actual для каждой платформы — Android и iOS — в соответствующих наборах исходных данных. Вы можете узнать больше о подключении к специфичным для платформы API.
-
Удалите класс
java.util.UUIDиз общего кода:val fakeUser = LoggedInUser(randomUUID(), "Jane Doe")
-
Создайте файл
Utils.ktв директорииshared/src/commonMainи предоставьте объявлениеexpect.package com.jetbrains.simplelogin.shared expect fun randomUUID(): String
-
Создайте файл
Utils.ktв директорииshared/src/androidMainи предоставьте реализациюactualдляrandomUUID()в Android:package com.jetbrains.simplelogin.shared import java.util.* actual fun randomUUID() = UUID.randomUUID().toString()
-
Создайте файл
Utils.ktв директорииshared/src/iosMainи предоставьте реализациюactualдляrandomUUID()в iOS:package com.jetbrains.simplelogin.shared import platform.Foundation.NSUUID actual fun randomUUID(): String = NSUUID().UUIDString()
Для Android и iOS Kotlin будет использовать разные реализации, специфичные для платформы.
Запустите ваше кроссплатформенное приложение на Android
Запустите ваше кроссплатформенное приложение для Android, чтобы убедиться, что оно работает.
Сделайте ваше кроссплатформенное приложение совместимым с iOS
После того, как вы сделали своё приложение для Android кроссплатформенным, вы можете создать приложение для iOS и повторно использовать общую бизнес-логику в нём.
Создание проекта iOS в Xcode
В Xcode, нажмите Файл | Новый | Проект.
-
Выберите шаблон приложения iOS и нажмите Далее.
-
В качестве имени продукта укажите simpleLoginIOS и нажмите Далее.
В качестве расположения проекта выберите каталог, который хранит ваше кроссплатформенное приложение, например,
multiplatform-integrate-into-existing-app.
В Android Studio вы получите следующую структуру:
Для согласованности с другими директориями верхнего уровня вашего кроссплатформенного проекта вы можете переименовать директорию simpleLoginIOS в iosApp.
Подключение фреймворка к проекту iOS
После получения фреймворка вы можете подключить его к вашему проекту iOS вручную.
Подключите фреймворк к проекту iOS вручную:
В Xcode откройте настройки проекта iOS, дважды щелкнув имя проекта.
-
На вкладке Этапы сборки настроек проекта нажмите + и добавьте Новый этап выполнения скрипта.

-
Добавьте следующий скрипт:
cd "$SRCROOT/.." ./gradlew :shared:embedAndSignAppleFrameworkForXcode
-
Переместите этап Выполнение скрипта перед этапом Компиляция исходного кода.
-
На вкладке Настройки сборки укажите Путь поиска фреймворков в разделе Пути поиска:
$(SRCROOT)/../shared/build/xcode-frameworks/$(CONFIGURATION)/$(SDK_NAME)

-
На вкладке Настройки сборки укажите Другие флаги компоновщика в разделе Компоновка:
$(inherited) -framework shared
Соберите проект в Xcode. При правильной настройке проект будет успешно собран.
Использование общего модуля из Swift
-
В Xcode откройте файл
ContentView.swiftи импортируйте модульshared.import shared
-
Чтобы проверить правильность подключения, используйте функцию
greeting()из модуля Kotlin Multiplatform:import SwiftUI import shared struct ContentView: View { var body: some View { Text(Greeting().greeting()) .padding() } } В
ContentView.swift, напишите код для использования данных из модуля Kotlin Multiplatform и отрисовки пользовательского интерфейса приложения.-
В
simpleLoginIOSApp.swift, импортируйте модульsharedи укажите аргументы для функцииContentView().import SwiftUI import shared @main struct SimpleLoginIOSApp: App { var body: some Scene { WindowGroup { ContentView(viewModel: .init(loginRepository: LoginRepository(dataSource: LoginDataSource()), loginValidator: LoginDataValidator())) } } }
Получайте результат – обновляйте логику только один раз
Теперь ваше приложение кроссплатформенное. Вы можете обновить бизнес-логику в одном месте и увидеть результаты как на Android, так и на iOS.
-
В Android Studio измените логику валидации пароля пользователя в функции
checkPassword()классаLoginDataValidator.package com.jetbrains.simplelogin.shared.data class LoginDataValidator { //... fun checkPassword(password: String): Result { return when { password.length < 5 -> Result.Error("Password must be >5 characters") password.toLowerCase() == "password" -> Result.Error("Password shouldn't be \"password\"") else -> Result.Success } } //... } -
Обновите
gradle.propertiesдля подключения вашего приложения iOS к Android Studio для запуска на эмуляторе или реальном устройстве прямо там:xcodeproj=iosApp/SimpleLoginIOS.xcodeproj
-
Синхронизируйте файлы Gradle, нажав Синхронизировать сейчас в сообщении об ошибке.
Вы увидите новую конфигурацию запуска simpleLoginIOS для запуска вашего приложения iOS прямо из Android Studio.
Вы можете ознакомиться с окончательным кодом для этого руководства.
Что ещё можно поделиться?
Вы поделились бизнес-логикой своего приложения, но также можете решить поделиться и другими слоями вашего приложения. Например, код класса ViewModel практически одинаков для Android и приложений iOS, и вы можете его поделиться, если ваши мобильные приложения должны иметь одинаковый слой презентации.
Что дальше?
После того, как вы сделали своё приложение для Android кроссплатформенным, вы можете перейти к:
Вы также можете изучить ресурсы сообщества:
© 2010–2022 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/multiplatform-mobile-integrate-in-existing-app.html