Unverified Commit 375a3792 authored by Nikolay Igotti's avatar Nikolay Igotti Committed by GitHub

iOS WIP (#247)

parent de761f6b
...@@ -122,3 +122,60 @@ project.tasks.register<Exec>("runIosSim") { ...@@ -122,3 +122,60 @@ project.tasks.register<Exec>("runIosSim") {
listOf(out.single { it.name.endsWith(".kexe") }.absolutePath) listOf(out.single { it.name.endsWith(".kexe") }.absolutePath)
} }
} }
// Create Xcode integration tasks.
val sdkName: String? = System.getenv("SDK_NAME")
enum class Target(val simulator: Boolean, val key: String) {
WATCHOS_X86(true, "watchos"), WATCHOS_ARM64(false, "watchos"),
IOS_X64(true, "iosX64"), IOS_ARM64(false, "iosArm64")
}
val target = sdkName.orEmpty().let {
when {
it.startsWith("iphoneos") -> Target.IOS_ARM64
it.startsWith("iphonesimulator") -> Target.IOS_X64
it.startsWith("watchos") -> Target.WATCHOS_ARM64
it.startsWith("watchsimulator") -> Target.WATCHOS_X86
else -> Target.IOS_X64
}
}
val targetBuildDir: String? = System.getenv("TARGET_BUILD_DIR")
val executablePath: String? = System.getenv("EXECUTABLE_PATH")
val buildType = System.getenv("CONFIGURATION")?.let {
org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType.valueOf(it.toUpperCase())
} ?: org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType.DEBUG
val currentTarget = kotlin.targets[target.key] as org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
val kotlinBinary = currentTarget.binaries.getExecutable(buildType)
val xcodeIntegrationGroup = "Xcode integration"
val packForXCode = if (sdkName == null || targetBuildDir == null || executablePath == null) {
// The build is launched not by Xcode ->
// We cannot create a copy task and just show a meaningful error message.
tasks.create("packForXCode").doLast {
throw IllegalStateException("Please run the task from Xcode")
}
} else {
// Otherwise copy the executable into the Xcode output directory.
tasks.create("packForXCode", Copy::class.java) {
dependsOn(kotlinBinary.linkTask)
destinationDir = file(targetBuildDir)
val dsymSource = kotlinBinary.outputFile.absolutePath + ".dSYM"
val dsymDestination = File(executablePath).parentFile.name + ".dSYM"
val oldExecName = kotlinBinary.outputFile.name
val newExecName = File(executablePath).name
from(dsymSource) {
into(dsymDestination)
rename(oldExecName, newExecName)
}
from(kotlinBinary.outputFile) {
rename { executablePath }
}
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>
name: SkikoSample
options:
bundleIdPrefix: org.jetbrains
settings:
DEVELOPMENT_TEAM: N462MKSJ7M
CODE_SIGN_IDENTITY: "iPhone Developer"
CODE_SIGN_STYLE: Automatic
MARKETING_VERSION: "1.0"
CURRENT_PROJECT_VERSION: "4"
SDKROOT: iphoneos
targets:
SkikoSample:
type: application
platform: iOS
deploymentTarget: "12.0"
prebuildScripts:
- script: cd "$SRCROOT" && ./gradlew -p . packForXCode
name: GradleCompile
info:
path: plists/Ios/Info.plist
properties:
sources:
- "src/"
settings:
LIBRARY_SEARCH_PATHS: "$(inherited)"
ENABLE_BITCODE: "YES"
ONLY_ACTIVE_ARCH: "NO"
VALID_ARCHS: "arm64"
// Use `xcodegen` first, then `open ./SkikoSample.xcodeproj` and then Rub
package org.jetbrains.skiko.sample package org.jetbrains.skiko.sample
import org.jetbrains.skia.* import org.jetbrains.skia.*
import org.jetbrains.skiko.*
fun main() { fun main(args: Array<String>) {
val paint = Paint().apply { color = Color.GREEN } val paint = Paint().apply { color = Color.GREEN }
println("HI: $paint") println("Paint is $paint")
runSkikoMain()
} }
package org.jetbrains.skiko
import kotlinx.cinterop.*
import platform.Foundation.*
import platform.UIKit.*
class SkikoAppDelegate : UIResponder, UIApplicationDelegateProtocol {
companion object : UIResponderMeta(), UIApplicationDelegateProtocolMeta {}
@ObjCObjectBase.OverrideInit
constructor() : super()
private var _window: UIWindow? = null
override fun window() = _window
override fun setWindow(window: UIWindow?) {
_window = window
}
override fun application(application: UIApplication, didFinishLaunchingWithOptions: Map<Any?, *>?): Boolean {
window = UIWindow(frame = UIScreen.mainScreen.bounds)
window!!.rootViewController = SkikoViewController()
window!!.makeKeyAndVisible()
return true
}
}
fun runSkikoMain(args: Array<String> = emptyArray()) {
memScoped {
val argc = args.size + 1
val argv = (arrayOf("skikoApp") + args).map { it.cstr.ptr }.toCValues()
autoreleasepool {
UIApplicationMain(argc, argv, null, NSStringFromClass(SkikoAppDelegate))
}
}
}
\ No newline at end of file
package org.jetbrains.skiko package org.jetbrains.skiko
import kotlinx.cinterop.*
import platform.Foundation.*
import platform.UIKit.*
actual open class SkiaLayer { actual open class SkiaLayer {
actual var renderApi: GraphicsApi actual var renderApi: GraphicsApi = GraphicsApi.OPENGL
get() = TODO("Not yet implemented")
set(value) {}
actual val contentScale: Float actual val contentScale: Float
get() = TODO("Not yet implemented") get() = 1.0f
actual var fullscreen: Boolean actual var fullscreen: Boolean
get() = TODO("Not yet implemented") get() = TODO("Not yet implemented")
set(value) {} set(value) {}
......
package org.jetbrains.skiko
import kotlinx.cinterop.*
import platform.Foundation.*
import platform.UIKit.*
import platform.CoreGraphics.CGPointMake
import platform.CoreGraphics.CGRectMake
import platform.Foundation.NSCoder
import platform.Foundation.NSSelectorFromString
@ExportObjCClass
class SkikoViewController : UIViewController {
@OverrideInit
constructor() : super(nibName = null, bundle = null)
@OverrideInit
constructor(coder: NSCoder) : super(coder)
@ObjCOutlet
lateinit var label: UILabel
@ObjCOutlet
lateinit var button: UIButton
var pressed = 0
@ObjCAction
fun buttonPressed() {
label.text = "Hello #${pressed++} from Skiko!"
println("Button pressed")
}
override fun viewDidLoad() {
super.viewDidLoad()
val (width, height) = UIScreen.mainScreen.bounds.useContents {
this.size.width to this.size.height
}
val header = UIView().apply {
backgroundColor = UIColor.lightGrayColor
view.addSubview(this)
translatesAutoresizingMaskIntoConstraints = false
leadingAnchor.constraintEqualToAnchor(view.leadingAnchor).active = true
topAnchor.constraintEqualToAnchor(view.topAnchor).active = true
widthAnchor.constraintEqualToAnchor(view.widthAnchor).active = true
heightAnchor.constraintEqualToAnchor(view.heightAnchor).active = true
}
label = UILabel().apply {
setFrame(CGRectMake(x = 10.0, y = 10.0, width = width - 100.0, height = 40.0))
center = CGPointMake(x = width / 2, y = 40.0 )
textAlignment = NSTextAlignmentCenter
text = "Press OK"
header.addSubview(this)
}
button = UIButton().apply {
setFrame(CGRectMake(x = 10.0, y = height - 100.0, width = width - 100.0, height = 40.0))
center = CGPointMake(x = width / 2, y = height / 2)
backgroundColor = UIColor.blueColor
setTitle("OK", forState = UIControlStateNormal)
font = UIFont.fontWithName(fontName = font.fontName, size = 28.0)!!
layer.borderWidth = 1.0
layer.borderColor = UIColor.colorWithRed(0x47 / 255.0, 0x43 / 255.0, 0x70 / 255.0, 1.0).CGColor
layer.masksToBounds = true
addTarget(target = this@SkikoViewController, action = NSSelectorFromString("buttonPressed"),
forControlEvents = UIControlEventTouchUpInside)
header.addSubview(this)
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment