Skip to content

Commit 3bf305a

Browse files
authored
feat: more info from interopedia (#4261)
1 parent 5d9cceb commit 3bf305a

File tree

1 file changed

+121
-106
lines changed

1 file changed

+121
-106
lines changed

docs/topics/native/native-objc-interop.md

Lines changed: 121 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -32,27 +32,134 @@ Kotlin modules can be used in Swift/Objective-C code if compiled into a framewor
3232
* See [Build final native binaries](multiplatform-build-native-binaries.md#declare-binaries) to see how to declare binaries.
3333
* Check out the [Kotlin Multiplatform sample project](https://github.com/Kotlin/kmm-basic-sample) for an example.
3434

35-
### Hiding Kotlin declarations
35+
### Hide Kotlin declarations from Objective-C and Swift
3636

37-
> `@HiddenFromObjC` and `@ShouldRefineInSwift` annotations are [Experimental](components-stability.md#stability-levels-explained) and require [opt-in](opt-in-requirements.md).
37+
> The `@HiddenFromObjC` annotation is [Experimental](components-stability.md#stability-levels-explained) and requires [opt-in](opt-in-requirements.md).
3838
>
3939
{type="warning"}
4040

41-
If you don't want to export Kotlin declarations to Objective-C and Swift, use special annotations:
41+
To make your Kotlin code more Objective-C/Swift-friendly, you can hide a Kotlin declaration from Objective-C and Swift
42+
with `@HiddenFromObjC`. The annotation disables a function or property export to Objective-C.
4243

43-
* `@HiddenFromObjC` hides a Kotlin declaration from Objective-C and Swift. The annotation disables a function or property
44-
export to Objective-C, making your Kotlin code more Objective-C/Swift-friendly.
44+
Alternatively, you can mark Kotlin declarations with the` internal` modifier to restrict their visibility in the
45+
compilation module. Choose `@HiddenFromObjC` if you only want to hide the Kotlin declaration from Objective-C and Swift,
46+
but still keep it visible from other Kotlin modules.
4547

46-
[See an example in the Kotlin-Swift interopedia](https://github.com/kotlin-hands-on/kotlin-swift-interopedia/blob/main/docs/overview/HiddenFromObjC.md).
47-
* `@ShouldRefineInSwift` helps to replace a Kotlin declaration with a wrapper written in Swift. The annotation marks a
48-
function or property as `swift_private` in the generated Objective-C API. Such declarations get the `__` prefix,
49-
which makes them invisible from Swift.
48+
[See an example in the Kotlin-Swift interopedia](https://github.com/kotlin-hands-on/kotlin-swift-interopedia/blob/main/docs/overview/HiddenFromObjC.md).
5049

51-
You can still use these declarations in your Swift code to create a Swift-friendly API, but they won't be suggested in
52-
the Xcode autocomplete.
50+
### Use refining in Swift
5351

54-
* For more information on refining Objective-C declarations in Swift, see the [official Apple documentation](https://developer.apple.com/documentation/swift/improving-objective-c-api-declarations-for-swift).
55-
* For an example on how to use the `@ShouldRefineInSwift` annotation, see the [Kotlin-Swift interopedia](https://github.com/kotlin-hands-on/kotlin-swift-interopedia/blob/main/docs/overview/ShouldRefineInSwift.md).
52+
> The `@ShouldRefineInSwift` annotation is [Experimental](components-stability.md#stability-levels-explained) and requires [opt-in](opt-in-requirements.md).
53+
>
54+
{type="warning"}
55+
56+
`@ShouldRefineInSwift` helps to replace a Kotlin declaration with a wrapper written in Swift. The annotation marks a
57+
function or property as `swift_private` in the generated Objective-C API. Such declarations get the `__` prefix,
58+
which makes them invisible from Swift.
59+
60+
You can still use these declarations in your Swift code to create a Swift-friendly API, but they won't be suggested in
61+
the Xcode autocomplete.
62+
63+
* For more information on refining Objective-C declarations in Swift, see the [official Apple documentation](https://developer.apple.com/documentation/swift/improving-objective-c-api-declarations-for-swift).
64+
* For an example on how to use the `@ShouldRefineInSwift` annotation, see the [Kotlin-Swift interopedia](https://github.com/kotlin-hands-on/kotlin-swift-interopedia/blob/main/docs/overview/ShouldRefineInSwift.md).
65+
66+
### Change declaration names
67+
68+
> The `@ObjCName` annotation is [Experimental](components-stability.md#stability-levels-explained) and requires [opt-in](opt-in-requirements.md).
69+
>
70+
{type="warning"}
71+
72+
To avoid renaming Kotlin declarations, use the `@ObjCName` annotation. It instructs the Kotlin compiler to use the
73+
custom Objective-C and Swift name for the annotated class, interface, or another Kotlin entity:
74+
75+
```kotlin
76+
@ObjCName(swiftName = "MySwiftArray")
77+
class MyKotlinArray {
78+
@ObjCName("index")
79+
fun indexOf(@ObjCName("of") element: String): Int = TODO()
80+
}
81+
82+
// Usage with the ObjCName annotations
83+
let array = MySwiftArray()
84+
let index = array.index(of: "element")
85+
```
86+
87+
[See another example in the Kotlin-Swift interopedia](https://github.com/kotlin-hands-on/kotlin-swift-interopedia/blob/main/docs/overview/ObjCName.md).
88+
89+
### Provide documentation with KDoc comments
90+
91+
Documentation is essential for understanding any API. Providing documentation for
92+
the shared Kotlin API allows you to communicate with its users on matters of usage, dos and don'ts, and so on.
93+
94+
By default, [KDocs](kotlin-doc.md) comments are not translated into corresponding comments when generating
95+
an Objective-C header. For example, the following Kotlin code with KDoc:
96+
97+
```kotlin
98+
/**
99+
* Prints the sum of the arguments.
100+
* Properly handles the case when the sum doesn't fit in 32-bit integer.
101+
*/
102+
fun printSum(a: Int, b: Int) = println(a.toLong() + b)
103+
```
104+
105+
Will produce an Objective-C declaration without any comments:
106+
107+
```objc
108+
+ (void)printSumA:(int32_t)a b:(int32_t)b __attribute__((swift_name("printSum(a:b:)")));
109+
```
110+
111+
To enable export of KDoc comments, add the following compiler option to your `build.gradle(.kts)`:
112+
113+
<tabs group="build-script">
114+
<tab title="Kotlin" group-key="kotlin">
115+
116+
```kotlin
117+
kotlin {
118+
targets.withType<org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget> {
119+
compilations.get("main").compilerOptions.options.freeCompilerArgs.add("-Xexport-kdoc")
120+
}
121+
}
122+
```
123+
124+
</tab>
125+
<tab title="Groovy" group-key="groovy">
126+
127+
```groovy
128+
kotlin {
129+
targets.withType(org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget) {
130+
compilations.get("main").compilerOptions.options.freeCompilerArgs.add("-Xexport-kdoc")
131+
}
132+
}
133+
```
134+
135+
</tab>
136+
</tabs>
137+
138+
After that, the Objective-C header will contain a corresponding comment:
139+
140+
```objc
141+
/**
142+
* Prints the sum of the arguments.
143+
* Properly handles the case when the sum doesn't fit in 32-bit integer.
144+
*/
145+
+ (void)printSumA:(int32_t)a b:(int32_t)b __attribute__((swift_name("printSum(a:b:)")));
146+
```
147+
148+
You'll be able to see comments on classes and methods in autocompletion, for example, in Xcode. If you go to the
149+
definition of functions (in the `.h` file), you'll see comments on `@param`, `@return`, and so on.
150+
151+
Known limitations:
152+
153+
> The ability to export KDoc comments to generated Objective-C headers is [Experimental](components-stability.md).
154+
> It may be dropped or changed at any time.
155+
> Opt-in is required (see the details below), and you should use it only for evaluation purposes.
156+
> We would appreciate your feedback on it in [YouTrack](https://youtrack.jetbrains.com/issue/KT-38600).
157+
>
158+
{type="warning"}
159+
160+
* Dependency documentation is not exported unless it is compiled with `-Xexport-kdoc` itself. The feature is Experimental,
161+
so libraries compiled with this option might be incompatible with other compiler versions.
162+
* KDoc comments are mostly exported as is. Many KDoc features, for example `@property`, are not supported.
56163
57164
## Mappings
58165
@@ -101,29 +208,6 @@ Objective-C does not support packages in a framework. If the Kotlin compiler fin
101208
which have the same name but different packages, it renames them. This algorithm is not stable yet and can change between
102209
Kotlin releases. To work around this, you can rename the conflicting Kotlin classes in the framework.
103210
104-
### Custom declaration names
105-
106-
> The `@ObjCName` annotation is [Experimental](components-stability.md#stability-levels-explained) and requires [opt-in](opt-in-requirements.md).
107-
>
108-
{type="warning"}
109-
110-
To avoid renaming Kotlin declarations, use the `@ObjCName` annotation. It instructs the Kotlin compiler to use
111-
a custom Objective-C and Swift name for classes, interfaces, and other Kotlin concepts:
112-
113-
```kotlin
114-
@ObjCName(swiftName = "MySwiftArray")
115-
class MyKotlinArray {
116-
@ObjCName("index")
117-
fun indexOf(@ObjCName("of") element: String): Int = TODO()
118-
}
119-
120-
// Usage with the ObjCName annotations
121-
let array = MySwiftArray()
122-
let index = array.index(of: "element")
123-
```
124-
125-
[See another example in the Kotlin-Swift interopedia](https://github.com/kotlin-hands-on/kotlin-swift-interopedia/blob/main/docs/overview/ObjCName.md).
126-
127211
### Initializers
128212
129213
A Swift/Objective-C initializer is imported to Kotlin as constructors or as factory methods named `create`.
@@ -190,7 +274,7 @@ Here's how the `kotlin.Any` functions are mapped to Swift/Objective-C:
190274
[See an example with data classes in the Kotlin-Swift interopedia](https://github.com/kotlin-hands-on/kotlin-swift-interopedia/blob/main/docs/classesandinterfaces/Data%20classes.md).
191275

192276
You can specify a more idiomatic name in Swift or Objective-C, instead of renaming the Kotlin declaration with
193-
the [`@ObjCName` annotation](#custom-declaration-names).
277+
the [`@ObjCName` annotation](#change-declaration-names).
194278

195279
### Errors and exceptions
196280

@@ -523,75 +607,6 @@ library. To disable these compiler checks, add the `disableDesignatedInitializer
523607
See [Interoperability with C](native-c-interop.md) for an example case where the library uses some plain C features,
524608
such as unsafe pointers, structs, and so on.
525609

526-
## Export of KDoc comments to generated Objective-C headers
527-
528-
> The ability to export KDoc comments to generated Objective-C headers is [Experimental](components-stability.md).
529-
> It may be dropped or changed at any time.
530-
> Opt-in is required (see the details below), and you should use it only for evaluation purposes.
531-
> We would appreciate your feedback on it in [YouTrack](https://youtrack.jetbrains.com/issue/KT-38600).
532-
>
533-
{type="warning"}
534-
535-
By default, [KDocs](kotlin-doc.md) documentation comments are not translated into corresponding comments when generating
536-
an Objective-C header. For example, the following Kotlin code with KDoc:
537-
538-
```kotlin
539-
/**
540-
* Prints the sum of the arguments.
541-
* Properly handles the case when the sum doesn't fit in 32-bit integer.
542-
*/
543-
fun printSum(a: Int, b: Int) = println(a.toLong() + b)
544-
```
545-
546-
Will produce an Objective-C declaration without any comments:
547-
548-
```objc
549-
+ (void)printSumA:(int32_t)a b:(int32_t)b __attribute__((swift_name("printSum(a:b:)")));
550-
```
551-
552-
To enable export of KDoc comments, add the following compiler option to your `build.gradle(.kts)`:
553-
554-
<tabs group="build-script">
555-
<tab title="Kotlin" group-key="kotlin">
556-
557-
```kotlin
558-
kotlin {
559-
targets.withType<org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget> {
560-
compilations.get("main").compilerOptions.options.freeCompilerArgs.add("-Xexport-kdoc")
561-
}
562-
}
563-
```
564-
565-
</tab>
566-
<tab title="Groovy" group-key="groovy">
567-
568-
```groovy
569-
kotlin {
570-
targets.withType(org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget) {
571-
compilations.get("main").compilerOptions.options.freeCompilerArgs.add("-Xexport-kdoc")
572-
}
573-
}
574-
```
575-
576-
</tab>
577-
</tabs>
578-
579-
After that, the Objective-C header will contain a corresponding comment:
580-
581-
```objc
582-
/**
583-
* Prints the sum of the arguments.
584-
* Properly handles the case when the sum doesn't fit in 32-bit integer.
585-
*/
586-
+ (void)printSumA:(int32_t)a b:(int32_t)b __attribute__((swift_name("printSum(a:b:)")));
587-
```
588-
589-
Known limitations:
590-
591-
* Dependency documentation is not exported unless it is compiled with `-Xexport-kdoc` itself. The feature is Experimental,
592-
so libraries compiled with this option might be incompatible with other compiler versions.
593-
* KDoc comments are mostly exported as is. Many KDoc features, for example `@property`, are not supported.
594-
595610
## Unsupported
596611

597612
Some features of Kotlin programming language are not yet mapped into the respective features of Objective-C or Swift.

0 commit comments

Comments
 (0)