dima-avdeev-jb
2 years ago
committed by
GitHub
19 changed files with 422 additions and 155 deletions
@ -1 +1 @@
|
||||
ComposeFallingBalls.xcodeproj |
||||
local.properties |
||||
|
@ -0,0 +1,34 @@
|
||||
## Run native on MacOS |
||||
`./gradlew runDebugExecutableMacosX64` (Works on Intel processors) |
||||
|
||||
## Run web assembly in browser |
||||
`./gradlew jsBrowserDevelopmentRun` |
||||
|
||||
## Run on iOS simulator |
||||
`./gradlew iosDeployIPhone8Debug` |
||||
`./gradlew iosDeployIPadDebug` |
||||
|
||||
## Prepare Xcode to launch on iOS device |
||||
1) **Add your Apple ID.** |
||||
Xcode -> Preferences... -> Accounts |
||||
![apple-id.png](apple-id.png) |
||||
|
||||
2) **Create certificates with XCode in temporary project.** |
||||
You can create a certificate in Xcode. Create a new iOS app in Xcode. |
||||
File -> New -> Project |
||||
Choose iOS, App: |
||||
![ios-app.png](ios-app.png) |
||||
|
||||
3) **In next dialog set any product name and choose your teamID.** |
||||
|
||||
4) **Run project on iOS Device.** |
||||
Xcode prompts you to install the certificate. Require password from login.keychain |
||||
|
||||
5) **Done** |
||||
After a successful launch on the device - you can delete this temporary project. |
||||
Certificates will remain in login.keychain |
||||
|
||||
## Run on iOS device |
||||
set teamId in local.properties |
||||
`./gradlew iosDeployDeviceRelease` |
||||
During the build, you will be prompted to access login.keychain |
After Width: | Height: | Size: 213 KiB |
After Width: | Height: | Size: 64 KiB |
@ -0,0 +1 @@
|
||||
local.properties |
@ -0,0 +1,10 @@
|
||||
/* |
||||
* Copyright 2020-2022 JetBrains s.r.o. and respective authors and developers. |
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. |
||||
*/ |
||||
|
||||
package org.jetbrains.compose.experimental.dsl |
||||
|
||||
class UiKitConfiguration( |
||||
val name: String |
||||
) |
@ -0,0 +1,40 @@
|
||||
/* |
||||
* Copyright 2020-2022 JetBrains s.r.o. and respective authors and developers. |
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. |
||||
*/ |
||||
|
||||
package org.jetbrains.compose.experimental.uikit.internal |
||||
|
||||
import org.gradle.api.Project |
||||
import org.jetbrains.compose.desktop.application.internal.MacUtils |
||||
import org.jetbrains.compose.desktop.application.internal.UnixUtils |
||||
import org.jetbrains.compose.experimental.uikit.tasks.AbstractComposeIosTask |
||||
|
||||
internal val Project.iosDeployExecutable get() = iosDeploySrc.resolve("build/Release/ios-deploy") |
||||
|
||||
private const val IOS_DEPLOY_GIT = "https://github.com/ios-control/ios-deploy.git" |
||||
private const val IOS_DEPLOY_TAG = "1.11.4" |
||||
private val Project.iosDeploySrc get() = rootProject.buildDir.resolve("ios-deploy-$IOS_DEPLOY_TAG-src") |
||||
|
||||
internal fun Project.configureInstallIosDeployTask() = |
||||
tasks.composeIosTask<AbstractComposeIosTask>("iosInstallIosDeploy") { |
||||
onlyIf { !iosDeployExecutable.exists() } |
||||
doLast { |
||||
iosDeploySrc.deleteRecursively() |
||||
runExternalTool( |
||||
UnixUtils.git, |
||||
listOf( |
||||
"clone", |
||||
"--depth", "1", |
||||
"--branch", IOS_DEPLOY_TAG, |
||||
IOS_DEPLOY_GIT, |
||||
iosDeploySrc.absolutePath |
||||
) |
||||
) |
||||
runExternalTool( |
||||
MacUtils.xcodeBuild, |
||||
listOf("-target", "ios-deploy"), |
||||
workingDir = iosDeploySrc |
||||
) |
||||
} |
||||
} |
@ -0,0 +1,40 @@
|
||||
/* |
||||
* Copyright 2020-2022 JetBrains s.r.o. and respective authors and developers. |
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. |
||||
*/ |
||||
|
||||
package org.jetbrains.compose.experimental.uikit.internal |
||||
|
||||
import org.gradle.api.Project |
||||
import org.jetbrains.compose.desktop.application.internal.MacUtils |
||||
import org.jetbrains.compose.desktop.application.internal.UnixUtils |
||||
import org.jetbrains.compose.experimental.uikit.tasks.AbstractComposeIosTask |
||||
|
||||
internal val Project.xcodeGenExecutable get() = xcodeGenSrc.resolve(".build/apple/Products/Release/xcodegen") |
||||
|
||||
private const val XCODE_GEN_GIT = "https://github.com/yonaskolb/XcodeGen.git" |
||||
private const val XCODE_GEN_TAG = "2.26.0" |
||||
private val Project.xcodeGenSrc get() = rootProject.buildDir.resolve("xcodegen-$XCODE_GEN_TAG-src") |
||||
|
||||
fun Project.configureInstallXcodeGenTask() = |
||||
tasks.composeIosTask<AbstractComposeIosTask>("iosInstallXcodeGen") { |
||||
onlyIf { !xcodeGenExecutable.exists() } |
||||
doLast { |
||||
xcodeGenSrc.deleteRecursively() |
||||
runExternalTool( |
||||
UnixUtils.git, |
||||
listOf( |
||||
"clone", |
||||
"--depth", "1", |
||||
"--branch", XCODE_GEN_TAG, |
||||
XCODE_GEN_GIT, |
||||
xcodeGenSrc.absolutePath |
||||
) |
||||
) |
||||
runExternalTool( |
||||
MacUtils.make, |
||||
listOf("build"), |
||||
workingDir = xcodeGenSrc |
||||
) |
||||
} |
||||
} |
@ -0,0 +1,59 @@
|
||||
/* |
||||
* Copyright 2020-2022 JetBrains s.r.o. and respective authors and developers. |
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. |
||||
*/ |
||||
|
||||
package org.jetbrains.compose.experimental.uikit.internal |
||||
|
||||
import org.gradle.api.Project |
||||
import org.gradle.api.tasks.TaskProvider |
||||
import org.jetbrains.compose.experimental.uikit.tasks.AbstractComposeIosTask |
||||
|
||||
internal fun Project.configureTaskToGenerateXcodeProject( |
||||
id: String, |
||||
projectName: String, |
||||
bundleIdPrefix: String, |
||||
teamId: String? = null, |
||||
taskInstallXcodeGen: TaskProvider<*>, |
||||
): TaskProvider<AbstractComposeIosTask> = tasks.composeIosTask<AbstractComposeIosTask>("iosGenerateXcodeProject$id") { |
||||
dependsOn(taskInstallXcodeGen) |
||||
doLast { |
||||
val buildIosDir = getBuildIosDir(id) |
||||
buildIosDir.mkdirs() |
||||
buildIosDir.resolve("project.yml").writeText( |
||||
""" |
||||
name: $projectName |
||||
options: |
||||
bundleIdPrefix: $bundleIdPrefix |
||||
settings: |
||||
${if (teamId != null) "DEVELOPMENT_TEAM: \"$teamId\"" else ""} |
||||
CODE_SIGN_IDENTITY: "iPhone Developer" |
||||
CODE_SIGN_STYLE: Automatic |
||||
MARKETING_VERSION: "1.0" |
||||
CURRENT_PROJECT_VERSION: "4" |
||||
SDKROOT: iphoneos |
||||
targets: |
||||
$projectName: |
||||
type: application |
||||
platform: iOS |
||||
deploymentTarget: "12.0" |
||||
prebuildScripts: |
||||
- script: cd "${rootDir.absolutePath}" && ./gradlew -i -p . packComposeUikitApplicationForXCode |
||||
name: GradleCompile |
||||
info: |
||||
path: plists/Ios/Info.plist |
||||
properties: |
||||
UILaunchStoryboardName: "" |
||||
method: "development" |
||||
sources: |
||||
- "../../../src/" |
||||
settings: |
||||
LIBRARY_SEARCH_PATHS: "$(inherited)" |
||||
ENABLE_BITCODE: "YES" |
||||
ONLY_ACTIVE_ARCH: "NO" |
||||
VALID_ARCHS: "arm64" |
||||
""".trimIndent() |
||||
) |
||||
runExternalTool(xcodeGenExecutable, emptyList(), workingDir = buildIosDir) |
||||
} |
||||
} |
@ -1,57 +0,0 @@
|
||||
/* |
||||
* Copyright 2020-2022 JetBrains s.r.o. and respective authors and developers. |
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. |
||||
*/ |
||||
|
||||
package org.jetbrains.compose.experimental.uikit.internal |
||||
|
||||
import org.gradle.api.Project |
||||
import org.jetbrains.compose.experimental.uikit.tasks.AbstractComposeIosTask |
||||
import java.io.File |
||||
|
||||
internal fun Project.configureUseXcodeGenTask( |
||||
buildIosDir: File, |
||||
projectName: String, |
||||
bundleIdPrefix: String, |
||||
xcodeGenExecutable: File |
||||
) { |
||||
tasks.composeIosTask<AbstractComposeIosTask>(TASK_USE_XCODE_GEN_NAME) { |
||||
dependsOn(TASK_INSTALL_XCODE_GEN_NAME) |
||||
doLast { |
||||
buildIosDir.mkdirs() |
||||
buildIosDir.resolve("project.yml").writeText( |
||||
""" |
||||
name: $projectName |
||||
options: |
||||
bundleIdPrefix: $bundleIdPrefix |
||||
settings: |
||||
CODE_SIGN_IDENTITY: "iPhone Developer" |
||||
CODE_SIGN_STYLE: Automatic |
||||
MARKETING_VERSION: "1.0" |
||||
CURRENT_PROJECT_VERSION: "4" |
||||
SDKROOT: iphoneos |
||||
targets: |
||||
$projectName: |
||||
type: application |
||||
platform: iOS |
||||
deploymentTarget: "12.0" |
||||
prebuildScripts: |
||||
- script: cd "${rootDir.absolutePath}" && ./gradlew -i -p . packComposeUikitApplicationForXCode |
||||
name: GradleCompile |
||||
info: |
||||
path: plists/Ios/Info.plist |
||||
properties: |
||||
UILaunchStoryboardName: "" |
||||
sources: |
||||
- "../../src/" |
||||
settings: |
||||
LIBRARY_SEARCH_PATHS: "${'$'}(inherited)" |
||||
ENABLE_BITCODE: "YES" |
||||
ONLY_ACTIVE_ARCH: "NO" |
||||
VALID_ARCHS: "arm64" |
||||
""".trimIndent() |
||||
) |
||||
runExternalTool(xcodeGenExecutable, emptyList(), workingDir = buildIosDir) |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,92 @@
|
||||
/* |
||||
* Copyright 2020-2022 JetBrains s.r.o. and respective authors and developers. |
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. |
||||
*/ |
||||
|
||||
package org.jetbrains.compose.experimental.uikit.internal |
||||
|
||||
import org.gradle.api.* |
||||
import org.gradle.api.tasks.TaskProvider |
||||
import org.jetbrains.compose.desktop.application.internal.MacUtils |
||||
import org.jetbrains.compose.experimental.dsl.DeployTarget |
||||
import org.jetbrains.compose.experimental.dsl.UiKitConfiguration |
||||
import org.jetbrains.compose.experimental.uikit.tasks.AbstractComposeIosTask |
||||
import org.jetbrains.compose.internal.getLocalProperty |
||||
import org.jetbrains.compose.internal.localPropertiesFile |
||||
|
||||
fun Project.registerConnectedDeviceTasks( |
||||
id: String, |
||||
deploy: DeployTarget.ConnectedDevice, |
||||
projectName: String, |
||||
bundleIdPrefix: String, |
||||
taskInstallXcodeGen: TaskProvider<*>, |
||||
taskInstallIosDeploy: TaskProvider<*>, |
||||
configurations: List<UiKitConfiguration>, |
||||
) { |
||||
val xcodeProjectDir = getBuildIosDir(id).resolve("$projectName.xcodeproj") |
||||
val taskGenerateXcodeProject = configureTaskToGenerateXcodeProject( |
||||
id = id, |
||||
projectName = projectName, |
||||
bundleIdPrefix = bundleIdPrefix, |
||||
teamId = deploy.teamId ?: getLocalProperty(TEAM_ID_PROPERTY_KEY) |
||||
?: error( |
||||
buildString { |
||||
appendLine("In local.properties (${localPropertiesFile.absolutePath})") |
||||
appendLine("Add property") |
||||
appendLine("$TEAM_ID_PROPERTY_KEY=***") |
||||
appendLine("Or set teamId in deploy with id: $id") |
||||
} |
||||
), |
||||
taskInstallXcodeGen = taskInstallXcodeGen, |
||||
) |
||||
|
||||
for (configuration in configurations) { |
||||
val configName = configuration.name |
||||
val iosCompiledAppDir = xcodeProjectDir.resolve(RELATIVE_PRODUCTS_PATH) |
||||
.resolve("$configName-iphoneos/${projectName}.app") |
||||
|
||||
val taskBuild = tasks.composeIosTask<AbstractComposeIosTask>("iosBuildIphoneOs$id$configName") { |
||||
dependsOn(taskGenerateXcodeProject) |
||||
doLast { |
||||
// xcrun xcodebuild -showsdks (list all sdk) |
||||
val sdk = SDK_PREFIX_IPHONEOS + getSimctlListData().runtimes.first().version |
||||
val scheme = projectName // xcrun xcodebuild -list -project . (list all schemes) |
||||
repeat(2) { |
||||
// todo repeat(2) is workaround of error (domain=NSPOSIXErrorDomain, code=22) |
||||
// The bundle identifier of the application could not be determined |
||||
// Ensure that the application's Info.plist contains a value for CFBundleIdentifier. |
||||
runExternalTool( |
||||
MacUtils.xcrun, |
||||
listOf( |
||||
"xcodebuild", |
||||
"-scheme", scheme, |
||||
"-project", ".", |
||||
"-configuration", configName, |
||||
"-derivedDataPath", "build", |
||||
"-arch", "arm64", |
||||
"-sdk", sdk, |
||||
"-allowProvisioningUpdates", |
||||
"-allowProvisioningDeviceRegistration", |
||||
), |
||||
workingDir = xcodeProjectDir |
||||
) |
||||
} |
||||
} |
||||
} |
||||
|
||||
val taskDeploy = tasks.composeIosTask<AbstractComposeIosTask>("iosDeploy$id$configName") { |
||||
dependsOn(taskInstallIosDeploy) |
||||
dependsOn(taskBuild) |
||||
doLast { |
||||
runExternalTool( |
||||
iosDeployExecutable, |
||||
listOf( |
||||
"--debug", |
||||
"--bundle", iosCompiledAppDir.absolutePath, |
||||
) |
||||
) |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
Loading…
Reference in new issue