Brief description: Today we’re going to talk about some of the trendier things in Kotlin. Some might say, “Unlike your previous style, your previous articles were not all about grammar and the secrets behind grammar candy. While you’re still clinging to generic syntax, other people are already writing about new features in Kotlin/Native and Kotlin1.3. Today we will talk about these fashionable things, maybe you can see something different from others.

Some time ago, due to my love for Kotlin, your little panda brother (me) happened to see the 2018 JetBrains Developer Day — Kotlin special event one day. His brain was so hot that he instantly moved, and immediately bought tickets and train tickets to Attend the event in Beijing (the first time I went to Beijing alone). I bought a ticket without much thought, seeing the speaking schedule of the two leaders of the Kotlin Chinese community (whom I’ve followed since I started writing about Kotlin over a year ago) and a talk by JetBrains’ senior evangelist Hali. Finally, I’d like to meet with the leaders of the Kotlin community. Thank you for your hospitality. I learned a lot from my trip to Beijing, and sometimes it’s better to know the latest technology directions and trends than to keep your head down behind closed doors.

Because in my official account (Kotlin Developer Union), some friends hope that I can bring something back from the Developer conference in Beijing, so I summarize my actual development and bring you the following articles.

  • 1. Kotlin/Native1.0 Beta
  • What are the new 1.3 features in Kotlin?
  • 3. Coroutine in Kotlin for Android (Coroutine Pre-school)
  • 4. Initial experience of Ktor Asynchronous Framework (Ktor Preschool)

So, I will start my first article today. I have read some articles about Kotlin/ Native written by some big guys. They are basically translated from the official Blog of Kotlin Blog. I’m not going to do that today, but since today’s topic is fashion let’s do something interesting. Let’s take a look at today’s outline:

A new understanding of Kotlin language

Before I begin, I think it’s worth reintroducing Kotlin, a language that many people think of as a JVM language that runs on a JVM like Java and Scala. Kotlin isn’t just a JVM language, it’s really ambitious, and the JVM language has outgrown its ambitions. It is a multi-platform statically compiled language that can be used on JVMS (although it is well known at the JVM level, leading many to think of it as a gate JVM language), but in fact can be compiled as JavaScipt to run in browsers or as IOS runnable files to run on LLVM

2. Basic introduction of Kotlin/Native

Officially, Kotlin/Native is a technique for compiling Kotlin code into Native binaries that can be run without a virtual machine. It is an LLVM-based back end for the Kotlin compiler and the native implementation of the Kotlin standard library.

Kotlin/Native currently supports the following platforms:

  • — iOS (arm32, arm64, emulator x86_64)
  • — MacOS (x86_64)
  • — Android (arm32, arm64)
  • — Windows (mingw x86_64)
  • — Linux (x86_64, arm32, MIPS, MIPS little endian)
  • — WebAssembly (wasm32)

To better illustrate the Kotlin/Native ability, an official Kotlin/Native ability chart is given below:

I have never played Kotlin/Native before, but I often hear community friends say that compiling is very slow, it feels so fashionable. Curious, and in keeping with the fashionable theme of this article, WE decided to take you step by step.

Kotlin/Native developed IOS HelloWorld

1. Development tools to be prepared

  • AppCode 2018.1(recommended to download the latest version, this is not the latest version but can also play, the latest version should be 2018.3)
  • Kotlin/Native Plugin 181.5087.34(note: Plugin and AppCode IDE version match problem, it is recommended to install the IDE, then IDE search download will default to the best match plug-in version)
  • AppCode 2018.1(Xcode 9.2), AppCode 2018.3(Xcode 10.0), AppCode 2018.1(Xcode 9.2), AppCode 2018.3(Xcode 10.0), AppCode 2018.1(Xcode 9.2), AppCode 2018.3(Xcode 10.0)

2. Create a Kotlin/Native project

Step 1: Select Kotlin/Native on the left and Sing View App with a Kotlin/Native Framework on the right

Step 2: Fill in the project name and package name, and select Swift(Swift is used as an example)

Finish the Kotlin/Native project. The structure of the project is as follows

4. Run Kotlin/Native projects

If you’re lucky enough to be running, you should be loading an APP in the emulator and opening up a blank page that says “Hello from Kotlin!” Log of, something like this:

Note: If you are testing the IOS Device option at the top of Run by default, then you click Run and get the following error

The problem is that the default IOS Device option is to debug on a real Device, and then you need an IOS developer account. To set up a developer account, it is recommended to use Xcode to open the project and configure a developer account for the project.

AppCode will automatically detect the refresh after Xcode is set.

Iv. Analysis of operating principle of Kotlin/Native development IOS

How does Kotlin’s code run on aN IOS device?

In fact, there are scripts and tools behind the scenes to keep the project running. As mentioned earlier, the Kotlin/Native platform has its own compiler, but it’s obviously not efficient to run it manually every time you want to build a project. So Kotlin’s team chose Gradle. Kotlin/Native uses Gradle build tools to automate the entire Kotlin/Native build process in Xcode. Using Gradle here means that developers can take advantage of its internal incremental build architecture by simply building and downloading what they need, saving valuable developer time.

If you’re still wondering about the above, take a look at the build parameter scripts in the Kotlin/Native project:

  • To open the build script, you need to open it in Xcode, as shown below:

From the above projects, it can be analyzed that compiling a Kotlin/Native project in Xcode is actually executing a shell script, and compiling Kotlin/Native with the gradlew command during shell script execution. The script calls the gradlew tool. This tool is part of Gradle Build System and passes the Build environment and debug options. Then call a Konan Gradle plug-in to compile the project and output the xxx.kexe file, and finally copy it to the iOS project build directory (“$TARGET_BUILD_DIR/$EXECUTABLE_PATH”).

Finally, take a look at the build.gradle build file in the Supporting Files, which introduces konan plug-in (Kotlin/Native compiler plug-in). If you have time, I suggest that you can further study konan plug-in. Here is a brief analysis of the entire compilation process. If you delve into the konan plugin source code, you will see the Kotlin/Native nature through the phenomenon, which is most important.

buildscript {
    ext.kotlin_version = '1.2.0'
    repositories {
        mavenCentral()
        maven {
            url "https://dl.bintray.com/jetbrains/kotlin-native-dependencies"}}dependencies {
        classpath "Org. Jetbrains. Kotlin: kotlin - native - gradle - plugin: 0.7"
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

apply plugin: 'kotlin'

repositories {
    mavenCentral()
}

dependencies {
    compile "org.jetbrains.kotlin:kotlin-stdlib"
}

apply plugin: 'konan'

konan.targets = [
    'ios_arm64'.'ios_x64'
]
        
konanArtifacts {
    program('KotlinNativeOC')}Copy the code

5. Structural analysis of Kotlin/Native project

1. Structural analysis of Kotlin/Native + Swift project

We know that the main function is the entry point for many applications, and ios is no exception. In Appdelegate. swift we have the @UIApplicationMain annotation, which is the entry point for the APP launch.

@UIApplicationMain // The main function annotates the entry, so the AppDelegate class acts as a bootstrap entry class
class AppDelegate: UIResponder.UIApplicationDelegate {

    var window: UIWindow?// UIWindow is added by default



    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    // KNFKotlinNativeFramework class is located in the framework that is generated during build.
    // If it is not resolved, try building for the device (not simulator) and reopening the project
    NSLog("% @".KNFKotlinNativeFramework().helloFromKotlin())// Note that you are calling one of the helloFromKotlin methods and printing out the return value as a Log, so you will see a Log printed out when the App starts
                  
    return true}... }Copy the code

KotlinNativeFramework class

class KotlinNativeFramework {
    fun helloFromKotlin(a) = "Hello from Kotlin!" // Return a Hello from Kotlin! string
}
Copy the code

However, aspiring programmers should never be allowed to run out of a blank page, blank page that how to install force? Ha ha. Add a text (UILabel) to the viewDidLoad function in viewController.swift.

class ViewController: UIViewController {
    override func viewDidLoad(a) {
    super.viewDidLoad()
        let label = UILabel(frame: CGRect(x: 0, y: 0, width: 300, height: 21))
        label.center = CGPoint(x: 160, y: 285)
        label.textAlignment = .center
        label.font = label.font.withSize(15)
        label.text = "Hello IOS, I'm from Kotlin/Native"
        view.addSubview(label)
    }
    override func didReceiveMemoryWarning(a) {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.}}Copy the code

Finally run again, the result is as follows:

2. Kotlin/Native + Objective C project structure analysis

With the help of IOS colleagues, I will further understand the basic knowledge of IOS APP startup, which will help us to transform the structure of our project and make it more simple. Additional Swift codes can be completely deleted, including the part of APP startup agent, which will be completed by Kotlin.

  • Step 1: create a Kotlin/Native + OC project.

  • The second step:As you can see, the OC and Swift project structure is similar. You can see that there are several important files.M, appdelegate. m, viewController.mM APP startup entry, equivalent to the main function, start from the main function first, and then make clear the whole startup process step by step.
#import <UIKit/UIKit.h>
#import "AppDelegate.h"


int main(int argc, char * argv[]) {
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil.NSStringFromClass([AppDelegate class]));// The AppDelegate class is also called here}}Copy the code
  • Step 3: then turn to the AppDelegate. J m, you can see in the didFinishLaunchingWithOptions function calls in the KNFKotlinNativeFramework helloFromKotlin function.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // KNFKotlinNativeFramework class is located in the framework that is generated during build.
    // If it is not resolved, try building for the device (not simulator) and reopening the project
    NSLog(@ "% @", [[[KNFKotlinNativeFramework alloc] init] helloFromKotlin]);// Notice that helloFromKotlin is called and the log is printed
                  
    return YES;
}
Copy the code

3. Kotlin/Native + Kotlin project structure analysis

At this point a lot of people are going to ask, look at what you said above so you didn’t see what Kotlin was doing, it was all Swift and OC doing APP launch. Now it’s time to show you how Kotlin does the APP launch thing instead.

  • First, create a new project, this time it is no longer Sing View App with a Kotlin/Native Framework, but an Application project.

  • The generated directory files are all Kotlin files, as follows:

  • The generated main.kt replaces main.m and sets the corresponding startup AppDelegate
import kotlinx.cinterop.autoreleasepool
import kotlinx.cinterop.cstr
import kotlinx.cinterop.memScoped
import kotlinx.cinterop.toCValues
import platform.Foundation.NSStringFromClass
import platform.UIKit.UIApplicationMain

fun main(args: Array<String>) {
    memScoped {
        val argc = args.size + 1
        val argv = (arrayOf("konan") + args).map { it.cstr.getPointer(memScope) }.toCValues()

        autoreleasepool {
            UIApplicationMain(argc, argv, null, NSStringFromClass(AppDelegate))// Note: Set the corresponding startup AppDelegate here}}}Copy the code
  • Generate an AppDelegate instead of appdelegate. m, and internally set the launch Window.
import kotlinx.cinterop.initBy
import platform.Foundation.NSLog
import platform.UIKit.*

class AppDelegate : UIResponder(), UIApplicationDelegateProtocol {
    override fun init(a) = initBy(AppDelegate())
    private var _window: UIWindow? = null
    override fun window(a) = _window
    override fun setWindow(window: UIWindow?). { _window = window }
    override fun application(application: UIApplication, didFinishLaunchingWithOptions: Map<Any? , * >?: Boolean {// When the APP is started, print the Log
        NSLog("this is launch from kotlin appDelegate")
        return true
}
    companion object : UIResponderMeta(), UIApplicationDelegateProtocolMeta// Note that there must be a Companion object otherwise NSStringFromClass(AppDelegate) will fail in main
}
Copy the code
  • Regenerates into a ViewController, which is very similar to an Activity in Android.
import kotlinx.cinterop.*
import platform.Foundation.*
import platform.UIKit.*

@ExportObjCClass
class ViewController : UIViewController {

    constructor(aDecoder: NSCoder) : super(aDecoder)
    override fun initWithCoder(aDecoder: NSCoder) = initBy(ViewController(aDecoder))

    @ObjCOutlet
    lateinit var label: UILabel

    @ObjCOutlet
    lateinit var textField: UITextField

    @ObjCOutlet
    lateinit var button: UIButton

    @ObjCAction
    fun buttonPressed(a) {
        label.text = "Konan says: 'Hello, ${textField.text}! '"}}Copy the code

The result is as follows:

6. Kotlin/Native develop a map Demo

1. Analysis of binding process between IOS project ViewController and components

So if you look at the Demo above, is there a question that you’re wondering how the ViewController in an IOS project is tied to the UI component? I personally think this is very important. In other words, this is the basic formula for IOS development. If you don’t understand this formula, Demo development will be in the clouds.

  • Step one: in kotlin directory to create a new KNMapViewController class, and to inherit the UIViewController and realize it MKMapViewDelegateProtocol interface, and rewrite viewDidLoad () function. And implement the map basic configuration in viewDidLoad function.
// Import Kotlin to interoperate with Objective-C and some Cocoa Touch frameworks.
import kotlinx.cinterop.*
import platform.CoreLocation.CLLocationCoordinate2DMake
import platform.Foundation.*
import platform.MapKit.MKCoordinateRegionMake
import platform.MapKit.MKCoordinateSpanMake
import platform.MapKit.MKMapView
import platform.MapKit.MKMapViewDelegateProtocol
import platform.UIKit.*

@ExportObjCClass// Note: the @exportobjcClass annotation helps Kotlin create a class that is searchable at runtime.
class KNMapViewController: UIViewController.MKMapViewDelegateProtocol {
    @ObjCOutlet // Note: the @objcOutlet annotation is important, mainly to set the mMapView property as an outlet. This allows you to link MKMapview in main.storyboard to this property.
    lateinit var mMapView: MKMapView
    constructor(aDecoder: NSCoder) : super(aDecoder)
    override fun initWithCoder(aDecoder: NSCoder) = initBy(KNMapViewController(aDecoder))
    override fun viewDidLoad(a) {
        super.viewDidLoad()
        val center = CLLocationCoordinate2DMake(32.07.118.78)
        val span = MKCoordinateSpanMake(0.7.0.7)
        val region = MKCoordinateRegionMake(center, span)

        with(mMapView) {
            delegate = this@KNMapViewController
            setRegion(region, true)}}}Copy the code
  • The second step: Open main. storyboard in your project with Xcode and remove some view components that were automatically generated. (If you are developing your project in AppCode, actually double clicking main. storyboard directly in AppCode will automatically open the entire project with Xcode and open the project.)

  • Step 3: Bind the currently empty view to its corresponding ViewController, in this case KNMapViewController

  • Step 4: Add a Map View component to the currently empty view and set constraints on the component.

  • Step 5: right click on the MKMapView component to see the black dialog box, taking the Referencing Outlets is empty, indicating that the current ViewController is not bound to the MKMapView component

  • Step 6: Configure outlets. AppCode is a bit of a drag here, so you need to manually go to Source Code and configure outlets, so go to Main. storyboard and right click Open as and open Source Code

  • Step 7: Configure a Connection between the view and viewController end tags

    The configured code is as follows:

<connections>
   <outlet property="mMapView" destination="dest id" id="generate id"/>
</connections>
<! -- Property is the mMapView variable name in KNMapViewController; The destination attribute value is a map view tag id(can be found in subviews mapView tag ID), id attribute is automatically generated, can be specified according to the format of their own, as long as there is no duplicate ID ->
Copy the code

The configuration result is as follows:

  • Step 8: Check whether the binding is successful. Return to the main.stroyboard view and right click the component to check whether the following binding relationship is displayed in the black box.

2. After the above configuration steps, you can go back to AppCode and run the project

Kotlin/Native Demo GitHub

7. Kotlin/Native development experience analysis

Kotlin/Native is still in beta 1.0, so there is still a lot to be desired. Here I summarize the pros and cons of this Kotlin/Native development experience:

Advantages:

Through the above examples, it can be clearly shown that the cross-platform capability of Kotlin/Native language level is very strong, and the operability of OC and Swfit projects is also very strong. Basically, all the necessary things have been realized, so its follow-up development is very worthy of attention. As far as I know, Kotlin’s team is currently focusing on Kotlin/Native. I hope they can bring us more surprises about Kotlin/Native.

disadvantages

There are many disadvantages:

  • 1. Kotlin/Native compilation is surprisingly slow, but runs well.
  • 2. AppCode uses Kotlin to develop IOS projects. There is no strong code prompt, many API guide packages are quite troublesome, and beginners are even confused.
  • 3. The Kotlin/Native plugin in AppCode does not provide the right click to create Kotlin classes, interfaces, etc.

Here’s a final test:

  • 4. Use Kotlin to develop IOS projects in AppCode, and configure outlet should be switched to manual operation in Xcode. Hope for future improvement.
  • 5. AppCode consumes more memory than AndroidStudio, opens two more projects, basically makes the IDE go in circles every time you use it, hoping for further improvements.

Talk about Kotlin/Native and the Flutter framework

1. Brief Introduction:

I don’t really want to talk about this topic, because I don’t want to start a war of words in the programming language community. However, some people like to compare Kotlin/Native with Flutter because they all seem to have one thing in common: they can develop Android and IOS apps across platforms. And at Jetbrains Developer Day, a guest asked Hali, the official evangelist, what is the difference between Kotlin/Native and Flutter, and what are its advantages?

2. Give your personal opinion:

I would like to offer my personal opinion on this issue:

First of all, I am personally optimistic that Flutter is a mobile cross-platform framework that can completely bridge the differences between Android and IOS apis. In other words, he may not know Java, OC or Swift, but he can develop both Android and IOS apps with native experience as long as he is familiar with DART and the Flutter framework API. It’s really cool, both from the perspective of saving the company labor and maintenance costs and the developer technology costs. But on the other hand you can imagine if you get into a situation where a lot of new projects are developed with DART, SWIFT and OC will you use it for new developers? Apple Dad would be unhappy, but you can imagine the story for yourself. (Maybe the future doesn’t turn out that way, but it’s a personal guess.)

And then, Kotlin/Native, actually Kotlin/Native and Flutter are not at the same level, it’s not very easy to compare, Kotlin/Native is more at the language compiler level, while Flutter is at the framework level. The two are not in the same world. Flutter implements its own rendering mechanism and UI engine and has a rich Development API. Kotlin/Native focuses more on how the compiler compiles KT source code into IOS LLVM binaries. However, Kotlin/Native does not apply platform differences at the API level as Flutter does, but platform differences at the language level. In other words, to develop IOS apps, you need to know not only Kotlin/Native but also IOS app Development Api. This seems like Kotlin/Native is a little inferior to Flutter, but it makes sense to think that API leveling is not a language level responsibility, it still needs a framework level to do this, and maybe one day Kotlin’s team will build a wheel similar to Flutter. In addition, another advantage of cross-platform at the language level is code sharing. Android, IOS and front-end can be realized by Kotlin, and the codes written by Kotlin with the same logic can be unified managed in a common package. Moreover, Kotlin has made good support for multi-platform sharing. Then different platforms can share this common logic implementation without having to write one for each platform.

3. Suggestions for developers to choose:

From this point of view, we conclude that learning a new technology generally has two hidden costs for developers. One is mastery of the new Development language, and the other is familiarity and mastery of the technology’s Development Api. So Kotlin/Native is trying to smooth over the first level of language development barriers. The language level can only do so much. Unlike Flutter, which is a framework, it can be smoothed directly from the API level. If Flutter eventually takes off and has better support for hot updates and hot fixes than the current native, and you’re a beginner, it’s definitely a good choice.

If you’re a Kotlin developer, you can definitely use Kotlin/Native and spend some time familiarizing yourself with the IOS API to get your IOS app playing. Of course, Kotlin/Native IOS apps are just a small part of it, and you can use it entirely for more meaningful things.

If you are a mobile developer, it is suggested that you can try both technologies after all, skills are not too heavy. Of course, language is just a tool, and ultimately depends on the solid foundation of computer, the ability to analyze requirements and the functional ability to construct projects. Add these capabilities to an efficient programming language and you’re all the more invincible.

Welcome to Kotlin’s series of articles:

Original series:

  • How to overcome the difficulties of generic typing in Kotlin
  • How to overcome the difficulties of Generic typing in Kotlin (Part 2)
  • How to overcome the difficulties of Generic typing in Kotlin (Part 1)
  • Kotlin’s trick of Reified Type Parameter (Part 2)
  • Everything you need to know about the Kotlin property broker
  • Source code parsing for Kotlin Sequences
  • Complete analysis of Sets and functional apis in Kotlin – Part 1
  • Complete parsing of lambdas compiled into bytecode in Kotlin syntax
  • On the complete resolution of Lambda expressions in Kotlin’s Grammar
  • On extension functions in Kotlin’s Grammar
  • A brief introduction to Kotlin’s Grammar article on top-level functions, infix calls, and destruct declarations
  • How to Make functions call Better
  • On variables and Constants in Kotlin’s Grammar
  • Elementary Grammar in Kotlin’s Grammar Essay

Translation series:

  • Kotlin’s trick of Reified Type Parameter
  • When should type parameter constraints be used in Kotlin generics?
  • An easy way to remember Kotlin’s parameters and arguments
  • Should Kotlin define functions or attributes?
  • How to remove all of them from your Kotlin code! (Non-empty assertion)
  • Master Kotlin’s standard library functions: run, with, let, also, and apply
  • All you need to know about Kotlin type aliases
  • Should Sequences or Lists be used in Kotlin?
  • Kotlin’s turtle (List) rabbit (Sequence) race
  • The Effective Kotlin series considers using static factory methods instead of constructors
  • The Effective Kotlin series considers using a builder when encountering multiple constructor parameters

Actual combat series:

  • Use Kotlin to compress images with ImageSlimming.
  • Use Kotlin to create a picture compression plugin.
  • Use Kotlin to compress images.
  • Simple application of custom View picture fillet in Kotlin practice article

Welcome to the Kotlin Developer Association, where the latest Kotlin technical articles are published, and a weekly Kotlin foreign technical article is translated from time to time. If you like Kotlin, welcome to join us ~~~