Spec-Zone.ru › Kotlin 1.6

Преобразование вашего Android-приложения для работы на iOS – учебник

Здесь вы можете узнать, как сделать ваше существующее Android-приложение кроссплатформенным, чтобы оно работало как на Android, так и на iOS. Вы сможете написать код и протестировать его для Android и iOS всего один раз, в одном месте.

В этом учебнике используется пример Android-приложения с одним экраном для ввода имени пользователя и пароля. Данные учетных данных проверяются и сохраняются в базе данных оперативной памяти.

Если вы не знакомы с Kotlin Multiplatform Mobile, вы можете сначала узнать, как создать и настроить кроссплатформенное мобильное приложение с нуля.

Подготовка среды разработки

  1. Установите Android Studio 4.2 или Android Studio 2020.3.1 Canary 8 или выше и другие инструменты для кроссплатформенной мобильной разработки на macOS.

    Для выполнения определенных шагов в этом учебнике, включая написание кода, специфичного для iOS, и запуск приложения iOS, вам потребуется Mac с macOS.
    Эти шаги не могут быть выполнены на других операционных системах, таких как Microsoft Windows. Это связано с требованиями Apple.

  2. В Android Studio создайте новый проект из системы контроля версий: https://github.com/Kotlin/kmm-integration-sample.

  3. Переключитесь на представление Проект.

    Project view

Сделайте ваш код кроссплатформенным

Чтобы ваше приложение работало на iOS, сначала сделайте ваш код кроссплатформенным, а затем используйте этот код в новом приложении для iOS.

Чтобы сделать ваш код кроссплатформенным:

  1. Определите, какой код сделать кроссплатформенным.

  2. Создайте общий модуль для кроссплатформенного кода.

  3. Добавьте зависимость от общего модуля к вашему Android-приложению.

  4. Сделайте бизнес-логику кроссплатформенной.

  5. Запустите ваше кроссплатформенное приложение на Android.

Определите, какой код сделать кроссплатформенным

Определите, какой код вашего Android-приложения лучше всего использовать совместно для iOS, а какой оставить нативным. Простое правило: используйте то, что вы хотите повторно использовать как можно чаще. Бизнес-логика часто одинакова как для Android, так и для iOS, поэтому она отлично подходит для повторного использования.

В вашем примере Android-приложения бизнес-логика хранится в пакете com.jetbrains.simplelogin.androidapp.data. Ваше будущее приложение для iOS будет использовать ту же логику, поэтому вам также следует сделать её кроссплатформенной.

Business logic to share

Создайте общий модуль для кроссплатформенного кода

Кроссплатформенный код, используемый как для iOS, так и для Android, хранится в общем модуле. Kotlin Multiplatform предоставляет специальный мастер для создания таких модулей.

В вашем Android-проекте создайте общий модуль Kotlin Multiplatform для вашего кроссплатформенного кода. Позже вы подключите его к вашему существующему Android-приложению и вашему будущему приложению для iOS.

  1. В Android Studio нажмите Файл | Создать | Новый модуль.

  2. В списке шаблонов выберите Kotlin Multiplatform Shared Module, введите имя модуля shared, и выберите Regular framework в списке параметров распространения фреймворка iOS.
    Это необходимо для подключения общего модуля к приложению iOS.

    Kotlin Multiplatform shared module
  3. Нажмите Готово.

Мастер создаст общий модуль Kotlin Multiplatform, обновит файлы конфигурации и создаст файлы с классами, демонстрирующими преимущества Kotlin Multiplatform. Вы можете узнать больше о структуре проекта.

Добавьте зависимость от общего модуля к вашему Android-приложению

Чтобы использовать кроссплатформенный код в вашем Android-приложении, подключите к нему общий модуль, переместите туда код бизнес-логики и сделайте этот код кроссплатформенным.

  1. Убедитесь, что compileSdkVersion и minSdkVersion в build.gradle.kts модуля shared совпадают с теми, которые находятся в build.gradle вашего Android-приложения в модуле app.
    Если они отличаются, обновите их в build.gradle.kts общего модуля. В противном случае вы столкнетесь с ошибкой компиляции.

  2. Добавьте зависимость от общего модуля к build.gradle вашего Android-приложения.

    dependencies {
        implementation project(':shared')
    }
    
  3. Синхронизируйте файлы Gradle, нажав Синхронизировать сейчас в предупреждении.

    Synchronize the Gradle files
  4. Чтобы убедиться, что общий модуль успешно подключен к вашему приложению, выведите результат функции greeting() в лог, обновив метод onCreate() класса LoginActivity.

    override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
    
       Log.i("Login Activity", "Hello from shared module: " + (Greeting().greeting()))
    
    }
    
  5. Найдите Hello в логе, и вы найдете приветствие из общего модуля.

    Greeting from the shared module

Сделайте бизнес-логику кроссплатформенной

Теперь вы можете извлечь код бизнес-логики в общий модуль Kotlin Multiplatform и сделать его независимым от платформы. Это необходимо для повторного использования кода как для Android, так и для iOS.

  1. Переместите код бизнес-логики com.jetbrains.simplelogin.androidapp.data из директории app в пакет com.jetbrains.simplelogin.shared в директории shared/src/commonMain. Вы можете перетащить пакет или рефакторить его, перемещая все из одной директории в другую.

    Drag and drop the package with the business logic code
  2. Когда Android Studio спросит, что вы хотите сделать, выберите переместить пакет, а затем подтвердите рефакторинг.

    Refactor the business logic package
  3. Проигнорируйте все предупреждения о коде, зависящем от платформы, и нажмите Продолжить.

    Warnings about platform-dependent code
  4. Удалите специфичный для Android код, заменив его кроссплатформенным кодом Kotlin или подключившись к специфичным для Android API, используя expect и actual объявления. См. следующие разделы для подробностей.

Замените специфичный для Android код кроссплатформенным кодом

Чтобы ваш код хорошо работал как на Android, так и на iOS, замените все зависимости JVM на зависимости Kotlin везде, где это возможно.

  1. В функции login() класса LoginDataSource, замените IOException, который недоступен в Kotlin, на RuntimeException.

    // Before
    return Result.Error(IOException("Error logging in", e))
    
    //After
    return Result.Error(RuntimeException("Error logging in", e))
    
  2. Для проверки электронной почты замените класс 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.

  1. Удалите класс java.util.UUID из общего кода:

    val fakeUser = LoggedInUser(randomUUID(), "Jane Doe") 
    
  2. Создайте файл Utils.kt в директории shared/src/commonMain и предоставьте объявление expect.

    package com.jetbrains.simplelogin.shared
    
    expect fun randomUUID(): String
    
  3. Создайте файл Utils.kt в директории shared/src/androidMain и предоставьте реализацию actual для randomUUID() в Android:

    package com.jetbrains.simplelogin.shared
    
    import java.util.*
    actual fun randomUUID() = UUID.randomUUID().toString()
    
  4. Создайте файл 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, чтобы убедиться, что оно работает.

Android login application

Сделайте ваше кроссплатформенное приложение совместимым с iOS

После того, как вы сделали своё приложение для Android кроссплатформенным, вы можете создать приложение для iOS и повторно использовать общую бизнес-логику в нём.

  1. Создайте проект iOS в Xcode.

  2. Подключите фреймворк к вашему проекту iOS.

  3. Используйте общий модуль из Swift.

Создание проекта iOS в Xcode

  1. В Xcode, нажмите Файл | Новый | Проект.

  2. Выберите шаблон приложения iOS и нажмите Далее.

    iOS project template
  3. В качестве имени продукта укажите simpleLoginIOS и нажмите Далее.

    iOS project settings
  4. В качестве расположения проекта выберите каталог, который хранит ваше кроссплатформенное приложение, например, multiplatform-integrate-into-existing-app.

В Android Studio вы получите следующую структуру:

iOS project in Android Studio

Для согласованности с другими директориями верхнего уровня вашего кроссплатформенного проекта вы можете переименовать директорию simpleLoginIOS в iosApp.

Renamed iOS project directory in Android Studio

Подключение фреймворка к проекту iOS

После получения фреймворка вы можете подключить его к вашему проекту iOS вручную.

Альтернативный вариант — настроить интеграцию через CocoaPods, но эта интеграция выходит за рамки этого руководства.

Подключите фреймворк к проекту iOS вручную:

  1. В Xcode откройте настройки проекта iOS, дважды щелкнув имя проекта.

  2. На вкладке Этапы сборки настроек проекта нажмите + и добавьте Новый этап выполнения скрипта.

    Add run script phase
  3. Добавьте следующий скрипт:

    cd "$SRCROOT/.."
    ./gradlew :shared:embedAndSignAppleFrameworkForXcode
    
    Add the script
  4. Переместите этап Выполнение скрипта перед этапом Компиляция исходного кода.

    Move the Run Script phase
  5. На вкладке Настройки сборки укажите Путь поиска фреймворков в разделе Пути поиска:

    $(SRCROOT)/../shared/build/xcode-frameworks/$(CONFIGURATION)/$(SDK_NAME)
    
    Framework search path
  6. На вкладке Настройки сборки укажите Другие флаги компоновщика в разделе Компоновка:

    $(inherited) -framework shared
    
    Linker flag
  7. Соберите проект в Xcode. При правильной настройке проект будет успешно собран.

Использование общего модуля из Swift

  1. В Xcode откройте файл ContentView.swift и импортируйте модуль shared.

    import shared
    
  2. Чтобы проверить правильность подключения, используйте функцию greeting() из модуля Kotlin Multiplatform:

    import SwiftUI
    import shared
    
    struct ContentView: View {
        var body: some View {
            Text(Greeting().greeting())
            .padding()
        }   
    }
    
    Greeting from the Kotlin Multiplatform module
  3. В ContentView.swift, напишите код для использования данных из модуля Kotlin Multiplatform и отрисовки пользовательского интерфейса приложения.

  4. В 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()))
            }
        }
    }
    
    Simple login application

Получайте результат – обновляйте логику только один раз

Теперь ваше приложение кроссплатформенное. Вы можете обновить бизнес-логику в одном месте и увидеть результаты как на Android, так и на iOS.

  1. В 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
            }
    }
    //...
    }
    
  2. Обновите gradle.properties для подключения вашего приложения iOS к Android Studio для запуска на эмуляторе или реальном устройстве прямо там:

    xcodeproj=iosApp/SimpleLoginIOS.xcodeproj
    
  3. Синхронизируйте файлы Gradle, нажав Синхронизировать сейчас в сообщении об ошибке.

    Synchronize the Gradle files

Вы увидите новую конфигурацию запуска simpleLoginIOS для запуска вашего приложения iOS прямо из Android Studio.

iOS run configuration
iOS application password error
Android application password error

Вы можете ознакомиться с окончательным кодом для этого руководства.

Что ещё можно поделиться?

Вы поделились бизнес-логикой своего приложения, но также можете решить поделиться и другими слоями вашего приложения. Например, код класса ViewModel практически одинаков для Android и приложений iOS, и вы можете его поделиться, если ваши мобильные приложения должны иметь одинаковый слой презентации.

Что дальше?

После того, как вы сделали своё приложение для Android кроссплатформенным, вы можете перейти к:

  • Добавление зависимостей от кроссплатформенных библиотек

  • Добавление зависимостей для Android

  • Добавление зависимостей для iOS

  • Изучение асинхронности

Вы также можете изучить ресурсы сообщества:

  • Видео: 3 способа подготовки кода Kotlin JVM для Kotlin Multiplatform Mobile

Последнее изменение: 07 апреля 2022
Понимание структуры проекта мобильного приложения Публикация вашего приложения

© 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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API