proofread (#2066)
This commit is contained in:
committed by
Nikolay Igotti
parent
5b63cdb4b2
commit
a426738213
+45
-46
@@ -1,6 +1,6 @@
|
||||
# _Kotlin/Native_ interoperability with Swift/Objective-C
|
||||
|
||||
This documents covers some details of Kotlin/Native interoperability with
|
||||
This document covers some details of Kotlin/Native interoperability with
|
||||
Swift/Objective-C.
|
||||
|
||||
## Usage
|
||||
@@ -10,12 +10,12 @@ Objective-C frameworks and libraries can be used in Kotlin code if
|
||||
properly imported to the build (system frameworks are imported by default).
|
||||
See e.g. "Interop libraries" in
|
||||
[Gradle plugin documentation](GRADLE_PLUGIN.md#building-artifacts).
|
||||
Swift library can be used in Kotlin code if its API is exported to Objective-C
|
||||
A Swift library can be used in Kotlin code if its API is exported to Objective-C
|
||||
with `@objc`. Pure Swift modules are not yet supported.
|
||||
|
||||
Kotlin module can be used in Swift/Objective-C code if compiled into a
|
||||
Kotlin modules can be used in Swift/Objective-C code if compiled into a
|
||||
[framework](GRADLE_PLUGIN.md#framework). See [calculator sample](https://github.com/JetBrains/kotlin-native/tree/master/samples/calculator)
|
||||
as an example.
|
||||
for an example.
|
||||
|
||||
## Mappings
|
||||
|
||||
@@ -50,17 +50,17 @@ The table below shows how Kotlin concepts are mapped to Swift/Objective-C and vi
|
||||
Objective-C classes are imported into Kotlin with their original names.
|
||||
Protocols are imported as interfaces with `Protocol` name suffix,
|
||||
i.e. `@protocol Foo` -> `interface FooProtocol`.
|
||||
These classes and interfaces are placed into package [specified in build configuration](#usage)
|
||||
These classes and interfaces are placed into a package [specified in build configuration](#usage)
|
||||
(`platform.*` packages for preconfigured system frameworks).
|
||||
|
||||
Names of Kotlin classes and interfaces are prefixed when imported to Swift/Objective-C.
|
||||
The names of Kotlin classes and interfaces are prefixed when imported to Swift/Objective-C.
|
||||
The prefix is derived from the framework name.
|
||||
|
||||
### Initializers
|
||||
|
||||
Swift/Objective-C initializers are imported to Kotlin as constructors and factory methods
|
||||
named `create`. The latter happens with initializers declared in Objective-C category or
|
||||
as Swift extension, because Kotlin has no concept of extension constructors.
|
||||
named `create`. The latter happens with initializers declared in the Objective-C category or
|
||||
as a Swift extension, because Kotlin has no concept of extension constructors.
|
||||
|
||||
Kotlin constructors are imported as initializers to Swift/Objective-C.
|
||||
|
||||
@@ -93,11 +93,10 @@ Framework.foo()
|
||||
|
||||
Generally Swift argument labels and Objective-C selector pieces are mapped to Kotlin
|
||||
parameter names. Anyway these two concepts have different semantics, so sometimes
|
||||
Swift/Objective-C methods can be imported with clashing Kotlin signature. In this case
|
||||
clashing methods can be called from Kotlin using named arguments, e.g.:
|
||||
Swift/Objective-C methods can be imported with a clashing Kotlin signature. In this case
|
||||
the clashing methods can be called from Kotlin using named arguments, e.g.:
|
||||
|
||||
<div class="sample" markdown="1" theme="idea" mode="swift">
|
||||
|
||||
```swift
|
||||
[player moveTo:LEFT byMeters:17]
|
||||
[player moveTo:UP byInches:42]
|
||||
@@ -105,7 +104,7 @@ clashing methods can be called from Kotlin using named arguments, e.g.:
|
||||
|
||||
</div>
|
||||
|
||||
in Kotlin would be:
|
||||
in Kotlin it would be:
|
||||
|
||||
<div class="sample" markdown="1" theme="idea" data-highlight-only>
|
||||
|
||||
@@ -119,13 +118,13 @@ player.moveTo(UP, byInches = 42)
|
||||
### Errors and exceptions
|
||||
|
||||
Kotlin has no concept of checked exceptions, all Kotlin exceptions are unchecked.
|
||||
Swift has only checked errors. So if Swift or Objective-C code calls Kotlin method
|
||||
which throws an exception to be handled, then Kotlin method should be marked
|
||||
with `@Throws` annotation. In this case all Kotlin exceptions
|
||||
(except for instances of `Error`, `RuntimeException` and subclasses) are translated to
|
||||
Swift error/`NSError`.
|
||||
Swift has only checked errors. So if Swift or Objective-C code calls a Kotlin method
|
||||
which throws an exception to be handled, then the Kotlin method should be marked
|
||||
with a `@Throws` annotation. In this case all Kotlin exceptions
|
||||
(except for instances of `Error`, `RuntimeException` and subclasses) are translated into
|
||||
a Swift error/`NSError`.
|
||||
|
||||
Note that the opposite translation is not implemented yet:
|
||||
Note that the opposite reversed translation is not implemented yet:
|
||||
Swift/Objective-C error-throwing methods aren't imported to Kotlin as
|
||||
exception-throwing.
|
||||
|
||||
@@ -133,12 +132,12 @@ exception-throwing.
|
||||
|
||||
Members of Objective-C categories and Swift extensions are imported to Kotlin
|
||||
as extensions. That's why these declarations can't be overridden in Kotlin.
|
||||
And extension initializers aren't available as Kotlin constructors.
|
||||
And the extension initializers aren't available as Kotlin constructors.
|
||||
|
||||
### Kotlin singletons
|
||||
|
||||
Kotlin singleton (made with `object` declaration, including `companion object`)
|
||||
is imported to Swift/Objective-C as class with a single instance.
|
||||
Kotlin singleton (made with an `object` declaration, including `companion object`)
|
||||
is imported to Swift/Objective-C as a class with a single instance.
|
||||
The instance is available through the factory method, i.e. as
|
||||
`[MySingleton mySingleton]` in Objective-C and `MySingleton()` in Swift.
|
||||
|
||||
@@ -146,10 +145,10 @@ The instance is available through the factory method, i.e. as
|
||||
|
||||
While Kotlin primitive types in some cases are mapped to `NSNumber`
|
||||
(e.g. when they are boxed), `NSNumber` type is not automatically translated
|
||||
to Kotlin primitive types when used as Swift/Objective-C parameter type or return value.
|
||||
to Kotlin primitive types when used as a Swift/Objective-C parameter type or return value.
|
||||
The reason is that `NSNumber` type doesn't provide enough information
|
||||
about wrapped primitive value type, i.e. `NSNumber` is statically not known
|
||||
to be e.g. `Byte`, `Boolean` or `Double`. So Kotlin primitive values
|
||||
about a wrapped primitive value type, i.e. `NSNumber` is statically not known
|
||||
to be a e.g. `Byte`, `Boolean`, or `Double`. So Kotlin primitive values
|
||||
should be cast to/from `NSNumber` manually (see [below](#casting-between-mapped-types)).
|
||||
|
||||
### NSMutableString
|
||||
@@ -160,11 +159,11 @@ All instances of `NSMutableString` are copied when passed to Kotlin.
|
||||
### Collections
|
||||
|
||||
Kotlin collections are converted to Swift/Objective-C collections as described
|
||||
by the table above. Swift/Objective-C collections are mapped to Kotlin in the same way,
|
||||
in the table above. Swift/Objective-C collections are mapped to Kotlin in the same way,
|
||||
except for `NSMutableSet` and `NSMutableDictionary`. `NSMutableSet` isn't converted to
|
||||
Kotlin `MutableSet`. To pass an object for Kotlin `MutableSet`,
|
||||
one can create this kind of Kotlin collection explicitly by either creating it
|
||||
in Kotlin with e.g. `mutableSetOf()`, or using `${prefix}MutableSet` class in
|
||||
a Kotlin `MutableSet`. To pass an object for Kotlin `MutableSet`,
|
||||
you can create this kind of Kotlin collection explicitly by either creating it
|
||||
in Kotlin with e.g. `mutableSetOf()`, or using the `${prefix}MutableSet` class in
|
||||
Swift/Objective-C, where `prefix` is the framework names prefix.
|
||||
The same holds for `MutableMap`.
|
||||
|
||||
@@ -175,8 +174,8 @@ Swift functions / Objective-C blocks. However there is a difference in how
|
||||
types of parameters and return values are mapped when translating a function
|
||||
and a function type. In the latter case primitive types are mapped to their
|
||||
boxed representation, `NSNumber`. Kotlin `Unit` return value is represented
|
||||
as corresponding `Unit` singleton in Swift/Objective-C. The value of this singleton
|
||||
can be retrieved in the same way as for any other Kotlin `object`
|
||||
as a corresponding `Unit` singleton in Swift/Objective-C. The value of this singleton
|
||||
can be retrieved in the same way as it is for any other Kotlin `object`
|
||||
(see singletons in the table above).
|
||||
To sum the things up:
|
||||
|
||||
@@ -213,8 +212,8 @@ foo {
|
||||
|
||||
## Casting between mapped types
|
||||
|
||||
When writing Kotlin code, an object may require to be converted from Kotlin type
|
||||
to equivalent Swift/Objective-C type (or vice versa). In this case plain old
|
||||
When writing Kotlin code, an object may need to be converted from a Kotlin type
|
||||
to the equivalent Swift/Objective-C type (or vice versa). In this case a plain old
|
||||
Kotlin cast can be used, e.g.
|
||||
|
||||
<div class="sample" markdown="1" theme="idea" data-highlight-only>
|
||||
@@ -233,22 +232,22 @@ val nsNumber = 42 as NSNumber
|
||||
|
||||
Kotlin classes and interfaces can be subclassed by Swift/Objective-C classes
|
||||
and protocols.
|
||||
Currently a class that adopts Kotlin protocol should inherit `NSObject`
|
||||
Currently a class that adopts the Kotlin protocol should inherit `NSObject`
|
||||
(either directly or indirectly). Note that all Kotlin classes do inherit `NSObject`,
|
||||
so a Swift/Objective-C subclass of Kotlin class can adopt Kotlin protocol.
|
||||
so a Swift/Objective-C subclass of Kotlin class can adopt the Kotlin protocol.
|
||||
|
||||
### Subclassing Swift/Objective-C classes and protocols from Kotlin
|
||||
|
||||
Swift/Objective-C classes and protocols can be subclassed with Kotlin `final` class.
|
||||
Non-`final` Kotlin classes inherting Swift/Objective-C types aren't supported yet, so it is
|
||||
not possible to declare a complex class hierarchy inherting Swift/Objective-C types.
|
||||
Swift/Objective-C classes and protocols can be subclassed with a Kotlin `final` class.
|
||||
Non-`final` Kotlin classes inheriting Swift/Objective-C types aren't supported yet, so it is
|
||||
not possible to declare a complex class hierarchy inheriting Swift/Objective-C types.
|
||||
|
||||
Normal methods can be overridden using `override` Kotlin keyword. In this case
|
||||
overriding method must have the same parameter names as the overridden one.
|
||||
Normal methods can be overridden using the `override` Kotlin keyword. In this case
|
||||
the overriding method must have the same parameter names as the overridden one.
|
||||
|
||||
Sometimes it is required to override initializers, e.g. when subclassing `UIViewController`.
|
||||
Initializers imported as Kotlin constructors can be overridden by Kotlin constructors
|
||||
marked with `@OverrideInit` annotation:
|
||||
marked with the `@OverrideInit` annotation:
|
||||
|
||||
<div class="sample" markdown="1" theme="idea" mode="swift">
|
||||
|
||||
@@ -264,16 +263,16 @@ class ViewController : UIViewController {
|
||||
|
||||
The overriding constructor must have the same parameter names and types as the overridden one.
|
||||
|
||||
To override different methods with clashing Kotlin signatures, one can add
|
||||
To override different methods with clashing Kotlin signatures, you can add a
|
||||
`@Suppress("CONFLICTING_OVERLOADS")` annotation to the class.
|
||||
|
||||
By default Kotlin/Native compiler doesn't allow to call non-designated
|
||||
Objective-C initializer as `super(...)` constructor. This behaviour can be
|
||||
inconvenient if designated initializers aren't marked properly in the Objective-C
|
||||
library. Adding `disableDesignatedInitializerChecks = true` to `.def` file for
|
||||
By default the Kotlin/Native compiler doesn't allow calling a non-designated
|
||||
Objective-C initializer as a `super(...)` constructor. This behaviour can be
|
||||
inconvenient if the designated initializers aren't marked properly in the Objective-C
|
||||
library. Adding a `disableDesignatedInitializerChecks = true` to the `.def` file for
|
||||
this library would disable these compiler checks.
|
||||
|
||||
## C features
|
||||
|
||||
See [INTEROP.md](INTEROP.md) for the case when library uses some plain C features
|
||||
See [INTEROP.md](INTEROP.md) for an example case where the library uses some plain C features
|
||||
(e.g. unsafe pointers, structs etc.).
|
||||
|
||||
Reference in New Issue
Block a user