You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
You can add Objective-C/Swift source files to `App_Resources/iOS/src`. For Objective-C files, create a `.modulemap` file. To add a [CocoaPod](https://guides.cocoapods.org/using/getting-started.html), edit `App_Resources/iOS/Podfile`:
10
+
You can add Objective-C/Swift source files to `App_Resources/iOS/src`. Objective-C files also need a [`module.modulemap`](#_2-add-a-module-modulemap) file that lists their headers. To add a [CocoaPod](https://guides.cocoapods.org/using/getting-started.html), edit `App_Resources/iOS/Podfile`:
11
11
12
12
```bash
13
13
App_Resources/
14
14
├─ iOS/
15
15
│ ├─ src/
16
-
│ │ ├─ Shimmer.swift
16
+
│ │ ├─ HelloSwift.swift
17
17
│ │ ├─ Shimmer.h
18
18
│ │ ├─ Shimmer.m
19
19
│ │ └─ module.modulemap
@@ -23,7 +23,7 @@ App_Resources/
23
23
24
24
### Adding Swift code
25
25
26
-
Define the swfit file in `App_Resources/iOS/src`.
26
+
Define the Swift file in `App_Resources/iOS/src`.
27
27
28
28
```swift
29
29
// HelloSwift.swift
@@ -69,51 +69,125 @@ class HelloSwift: NSObject {
69
69
}
70
70
```
71
71
72
-
<!---
73
-
TODO: add Objective-C code
74
72
### Adding Objective-C code
75
73
76
-
Define the Objective-C code within the path `App_Resources/iOS/src`.
74
+
Objective-C code needs one more file than Swift: a `module.modulemap`. The example below adds a `Shimmer` class written in Objective-C to `App_Resources/iOS/src` and makes it callable from JavaScript/TypeScript.
A module map is a small text file, used by the Clang compiler, that groups a set of Objective-C header files into a named _module_. NativeScript reads the module map when it builds your app to find out which Objective-C classes, methods and properties exist. It uses that information to generate the metadata that lets JavaScript call your code.
127
+
128
+
**Without a module map, your Objective-C code is still compiled into the app, but JavaScript cannot see it.** The class will be `undefined` at runtime, and the build log will contain this warning:
129
+
130
+
```
131
+
warning: Directory .../App_Resources/iOS/src with native iOS source code doesn't contain a modulemap file. Metadata for it will not be generated and it will not be accessible from JavaScript.
132
+
```
133
+
134
+
Create a file named exactly `module.modulemap` at the root of `App_Resources/iOS/src`, next to your files:
135
+
136
+
```bash
137
+
App_Resources/
138
+
└─ iOS/
139
+
└─ src/
140
+
├─ Shimmer.h
141
+
├─ Shimmer.m
142
+
└─ module.modulemap
143
+
```
144
+
145
+
For the `Shimmer` example, it contains:
146
+
147
+
```
148
+
// module.modulemap
149
+
module Shimmer {
150
+
header "Shimmer.h"
151
+
export *
152
+
}
153
+
```
154
+
155
+
Each line does the following:
156
+
157
+
-`module Shimmer { ... }`: declares a module. The name can be anything that is unique in your app, and it does not need to match a class name. You never import this name in JavaScript, because the classes become globals (see step 3).
158
+
-`header "Shimmer.h"`: a header to include in the module. The path is relative to the `module.modulemap` file. List **only `.h` files**, never `.m` files. Classes that are only declared in a `.m` file are not exposed.
159
+
-`export *`: re-exports everything that the listed headers import (here, `UIKit`), so that types like `UIView` in your method signatures resolve correctly.
160
+
161
+
When you add more Objective-C classes, add one `header` line per header file to the same module. Headers in subfolders use a relative path:
162
+
163
+
```
164
+
module LocalModule {
165
+
header "Shimmer.h"
166
+
header "views/GradientView.h"
167
+
export *
168
+
}
169
+
```
170
+
171
+
::: tip Note
172
+
Swift files do **not** need to be listed in a module map. Only Objective-C headers do.
173
+
174
+
The `ns native add objective-c <ClassName>` command creates the `.h` and `.m` files and adds the header to `App_Resources/iOS/src/module.modulemap` for you, using a module named `LocalModule`. See [Adding custom native code](/guide/adding-native-code).
175
+
:::
176
+
177
+
#### 3. Use it from JavaScript/TypeScript
178
+
179
+
After a rebuild, the class is available as a global. Objective-C selectors are mapped to JavaScript method names by dropping the colons, so `startOnView:` becomes `startOnView`:
To get type checking and autocomplete for `Shimmer`, [generate TypeScript typings](/guide/native-code/generate-typings) for it. Until you do, you can declare it yourself with `declare const Shimmer: any`.
191
+
192
+
If the class is still `undefined` after you add or change the module map, run `ns clean` and build again.
0 commit comments