From a4267382136f055e64d76999f7a5074a7be06d05 Mon Sep 17 00:00:00 2001 From: Watson David <30525704+B1ggDave@users.noreply.github.com> Date: Fri, 14 Sep 2018 16:06:11 +0200 Subject: [PATCH] proofread (#2066) --- OBJC_INTEROP.md | 91 ++++++++++++++++++++++++------------------------- 1 file changed, 45 insertions(+), 46 deletions(-) diff --git a/OBJC_INTEROP.md b/OBJC_INTEROP.md index 4bdf3b886ec..addacab8b57 100644 --- a/OBJC_INTEROP.md +++ b/OBJC_INTEROP.md @@ -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.:
- ```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.:
-in Kotlin would be: +in Kotlin it would be:
@@ -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.
@@ -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:
@@ -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.).