Skip to content

Commit

Permalink
Prototype UIKit Utils module (#902)
Browse files Browse the repository at this point in the history
Implement UIKit Utils library on Objective-C

Kotlin module: compose:ui:ui-uikit
Package: androidx.compose.ui.uikit.utils
Objc-Library: CMPUIKitUtils
Location: ./compose/ui/ui-uikit
  • Loading branch information
ASalavei authored Dec 7, 2023
1 parent a0658b0 commit e001c08
Show file tree
Hide file tree
Showing 21 changed files with 1,416 additions and 2 deletions.
9 changes: 7 additions & 2 deletions buildSrc/src/main/kotlin/AbstractComposePublishingTask.kt
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,13 @@ abstract class AbstractComposePublishingTask : DefaultTask() {
// To make OEL publishing (for android artifacts) work properly with kotlin >= 1.9.0,
// we use decorated `KotlinMultiplatform` publication named - 'KotlinMultiplatformDecorated'.
// see AndroidXComposeMultiplatformExtensionImpl.publishAndroidxReference for details.
val kotlinCommonPublicationName = "${ComposePlatforms.KotlinMultiplatform.name}Decorated"
dependsOnComposeTask("${component.path}:publish${kotlinCommonPublicationName}PublicationTo$repository")
if (ComposePlatforms.ANDROID.any { it in component.supportedPlatforms }) {
val kotlinCommonPublicationName =
"${ComposePlatforms.KotlinMultiplatform.name}Decorated"
dependsOnComposeTask("${component.path}:publish${kotlinCommonPublicationName}PublicationTo$repository")
} else {
dependsOnComposeTask("${component.path}:publish${ComposePlatforms.KotlinMultiplatform.name}PublicationTo$repository")
}

for (platform in targetPlatforms) {
if (platform !in component.supportedPlatforms) continue
Expand Down
6 changes: 6 additions & 0 deletions buildSrc/src/main/kotlin/ComposePlatforms.kt
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ enum class ComposePlatforms(vararg val alternativeNames: String) {
ComposePlatforms.AndroidRelease
)

val IOS = EnumSet.of(
ComposePlatforms.UikitX64,
ComposePlatforms.UikitArm64,
ComposePlatforms.UikitSimArm64
)

val ANDROID = EnumSet.of(
ComposePlatforms.AndroidDebug,
ComposePlatforms.AndroidRelease
Expand Down
135 changes: 135 additions & 0 deletions compose/ui/ui-uikit/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
/*
* Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import androidx.build.LibraryType

plugins {
id("AndroidXPlugin")
id("kotlin-multiplatform")
}

kotlin {
iosX64("uikitX64") {
configureCInterop(it, false)
}
iosArm64("uikitArm64") {
configureCInterop(it, true)
}
iosSimulatorArm64("uikitSimArm64") {
configureCInterop(it, false)
}

sourceSets {
commonMain {}
def uikitMain = sourceSets.create("uikitMain")
def uikitX64Main = sourceSets.getByName("uikitX64Main")
def uikitArm64Main = sourceSets.getByName("uikitArm64Main")
def uikitSimArm64Main = sourceSets.getByName("uikitSimArm64Main")

uikitMain.dependsOn(commonMain)
uikitX64Main.dependsOn(uikitMain)
uikitArm64Main.dependsOn(uikitMain)
uikitSimArm64Main.dependsOn(uikitMain)
}
}

def configureCInterop(target, isDevice) {
def frameworkName = "CMPUIKitUtils"
def schemeName = frameworkName
def objcDir = new File(project.projectDir, "src/uikitMain/objc")
def frameworkSourcesDir = new File(objcDir, frameworkName)
def sdkName
def destination
def architectures
if (isDevice) {
sdkName = "iphoneos"
destination = "generic/platform=iOS"
architectures = "arm64"
} else {
sdkName = "iphonesimulator"
destination = "generic/platform=iOS Simulator"
architectures = "arm64 x86_64"
}
def buildDir = new File(project.buildDir, "objc/${sdkName}.xcarchive")
def frameworkPath = new File(buildDir, "/Products/usr/local/lib/lib${frameworkName}.a")
def headersPath = new File(frameworkSourcesDir, frameworkName)

def systemFrameworks = ["UIKit", frameworkName]
def linkerFlags = ["-ObjC"] + systemFrameworks.collectMany {
["-framework", it]
}
def compilerArgs = [
"-include-binary", frameworkPath.toString(),
] + linkerFlags.collectMany {
["-linker-option", it]
}

target.compilations.main {
def taskName = "${compileTaskProvider.name}ObjCLib"
project.tasks.register(taskName, Exec) {
inputs.dir(frameworkSourcesDir)
.withPropertyName("${frameworkName}-${sdkName}")
.withPathSensitivity(PathSensitivity.RELATIVE)

outputs.cacheIf { true }
outputs.dir(buildDir)
.withPropertyName("${frameworkName}-${sdkName}-archive")

workingDir(frameworkSourcesDir)
commandLine("xcodebuild")
args(
"archive",
"-scheme", schemeName,
"-archivePath", buildDir,
"-sdk", sdkName,
"-destination", destination,
"SKIP_INSTALL=NO",
"BUILD_LIBRARY_FOR_DISTRIBUTION=YES",
"VALID_ARCHS=" + architectures,
"MACH_O_TYPE=staticlib"
)
}

tasks[compileTaskProvider.name].dependsOn(taskName)

cinterops {
utils {
headersPath.eachFileRecurse {
if (it.name.endsWith('.h')) {
headers(it)
}
}
}
}
}

target.binaries.all {
freeCompilerArgs += compilerArgs
}
target.compilations.all {
kotlinOptions {
freeCompilerArgs += compilerArgs
}
}
}

androidx {
name = "Compose UIKit Utils"
type = LibraryType.PUBLISHED_LIBRARY
inceptionYear = "2023"
description = "Internal iOS UIKit utilities including Objective-C library."
legacyDisableKotlinStrictApiMode = true
}
3 changes: 3 additions & 0 deletions compose/ui/ui-uikit/src/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
xcuserdata
xcshareddata
build
3 changes: 3 additions & 0 deletions compose/ui/ui-uikit/src/nativeInterop/cinterop/utils.def
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
linkerOpts = -framework UIKit
package = androidx.compose.ui.uikit.utils
language = Objective-C
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package androidx.compose.ui.uikit.utils
Loading

0 comments on commit e001c08

Please sign in to comment.