0
# Native Interoperability
1
2
Advanced native code integration layer providing pointer arithmetic, memory management, type conversion, and native function calls specifically for iOS platform development. Essential for low-level native iOS API access.
3
4
## Capabilities
5
6
### Pointer Management
7
8
Core pointer operations for direct memory access and native API integration.
9
10
```typescript { .api }
11
declare module interop {
12
/**
13
* A type that represents a void* pointer for direct memory access
14
*/
15
interface Pointer {
16
/**
17
* Create a new pointer with the given offset
18
* @param offset - The offset in bytes
19
*/
20
new(offset: number);
21
22
/**
23
* Create a new pointer by adding an offset to the current pointer
24
* @param offset - The offset in bytes
25
* @returns New pointer with added offset
26
*/
27
add(offset: number): Pointer;
28
29
/**
30
* Create a new pointer by removing an offset from the current pointer
31
* @param offset - The offset in bytes
32
* @returns New pointer with subtracted offset
33
*/
34
subtract(offset: number): Pointer;
35
36
/**
37
* Convert the value of this instance to a number
38
* @returns Numeric representation of the pointer address
39
*/
40
toNumber(): number;
41
}
42
43
var Pointer;
44
45
/**
46
* A pointer that will free the memory it points to automatically when garbage collected
47
*/
48
interface AdoptedPointer extends Pointer {
49
}
50
}
51
```
52
53
**Usage Examples:**
54
55
```typescript
56
// Create and manipulate pointers
57
const ptr = new interop.Pointer(0x1000);
58
const offsetPtr = ptr.add(64); // Add 64 bytes
59
const backPtr = offsetPtr.subtract(32); // Subtract 32 bytes
60
61
// Convert pointer to numeric address
62
const address = ptr.toNumber();
63
console.log(`Pointer address: 0x${address.toString(16)}`);
64
```
65
66
### Memory Allocation
67
68
Memory management functions for allocating and releasing native memory.
69
70
```typescript { .api }
71
declare module interop {
72
/**
73
* Make the pointer adopted - it will hold its memory automatically
74
* @param ptr - The pointer to adopt
75
* @returns AdoptedPointer that will auto-free memory
76
*/
77
function adopt(ptr: Pointer): AdoptedPointer;
78
79
/**
80
* Allocate memory block
81
* @param size - The size in bytes to allocate
82
* @returns AdoptedPointer to allocated memory
83
*/
84
function alloc(size: number): AdoptedPointer;
85
86
/**
87
* Release the memory of a pointer (should not be adopted)
88
* @param ptr - Pointer to the memory to free
89
*/
90
function free(ptr: Pointer): void;
91
92
/**
93
* Return the size of the provided type
94
* @param type - Class constructor, instance, struct, reference, protocol, or function
95
* @returns Size in bytes of the type
96
*/
97
function sizeof(type: any): number;
98
99
/**
100
* Get a pointer to the backing native object from a JavaScript object
101
* @param instance - Class constructor, instance, struct, reference, protocol, function, or block
102
* @returns Pointer to the native object
103
*/
104
function handleof(instance: any): Pointer;
105
106
/**
107
* Wrap an NSData instance in an ArrayBuffer
108
* @param data - NSData instance to wrap
109
* @returns ArrayBuffer wrapping the data
110
*/
111
function bufferFromData(data: NSData): ArrayBuffer;
112
}
113
```
114
115
**Usage Examples:**
116
117
```typescript
118
// Allocate and manage memory
119
const buffer = interop.alloc(1024); // Allocate 1KB, auto-freed
120
const rawPtr = new interop.Pointer(0x2000);
121
const adoptedPtr = interop.adopt(rawPtr); // Now auto-freed
122
123
// Get size information
124
const nsStringSize = interop.sizeof(NSString);
125
const intSize = interop.sizeof(interop.types.int32);
126
127
// Get native handle
128
const nsString = NSString.stringWithString("Hello");
129
const handle = interop.handleof(nsString);
130
131
// Convert NSData to ArrayBuffer
132
const nsData = NSData.dataWithContentsOfFile("/path/to/file");
133
const buffer = interop.bufferFromData(nsData);
134
```
135
136
### Reference Types
137
138
Typed references for passing values by reference to native functions.
139
140
```typescript { .api }
141
declare module interop {
142
/**
143
* A type that wraps a pointer and allows read/write operations on its value
144
*/
145
interface Reference<T> {
146
/** The referenced value */
147
value: T;
148
}
149
150
/**
151
* Reference constructor for creating typed references
152
*/
153
var Reference: {
154
/**
155
* Create a new reference around a value
156
* @param value - JavaScript value to initialize the reference
157
* @returns Reference wrapping the value
158
*/
159
new <T>(value?: T): Reference<T>;
160
161
/**
162
* Create a reference from pointer with given type
163
* @param type - The type to interpret the pointer as
164
* @param data - Pointer to the data
165
* @returns Typed reference to the pointer data
166
*/
167
new <T>(type: Type<T>, data: Pointer): Reference<T>;
168
169
/**
170
* Create a new reference around a value with explicit type
171
* @param type - The type to interpret the value as
172
* @param value - Value to reference
173
* @returns Typed reference to the value
174
*/
175
new <T>(type: Type<T>, value: any): Reference<T>;
176
177
/**
178
* Access values using pointer arithmetic
179
*/
180
[index: number]: any;
181
}
182
}
183
```
184
185
**Usage Examples:**
186
187
```typescript
188
// Create references for passing by reference
189
const intRef = new interop.Reference<number>(42);
190
const stringRef = new interop.Reference<string>("Hello");
191
192
// Use with native functions that expect references
193
someNativeFunction(intRef);
194
console.log(intRef.value); // May be modified by native function
195
196
// Create typed references from pointers
197
const ptr = interop.alloc(interop.sizeof(interop.types.int32));
198
const typedRef = new interop.Reference(interop.types.int32, ptr);
199
typedRef.value = 100;
200
201
// Array-style access for pointer arithmetic
202
typedRef[0] = 100; // Same as typedRef.value = 100
203
typedRef[1] = 200; // Next int32 in memory
204
```
205
206
### Function References
207
208
Native function pointer support for callback scenarios, including Objective-C blocks.
209
210
```typescript { .api }
211
declare module interop {
212
interface FunctionReference<T> {
213
(...params);
214
}
215
216
/**
217
* Create a function reference that can be marshalled as a native function pointer
218
* The JavaScript reference must be held alive as long as the native code needs it
219
*/
220
var FunctionReference: {
221
new <T>(func: T): FunctionReference<T>;
222
}
223
224
/**
225
* Objective-C Block type for callback scenarios
226
* Blocks are Objective-C's closure implementation
227
*/
228
interface Block<T> {
229
(...params);
230
}
231
232
/**
233
* Create an Objective-C block from a JavaScript function
234
* The JavaScript reference must be held alive as long as the native code needs it
235
*/
236
var Block: {
237
new <T>(func: T): Block<T>;
238
}
239
}
240
```
241
242
**Usage Examples:**
243
244
```typescript
245
// Create function reference for native callbacks
246
const callback = (result: number) => {
247
console.log(`Native callback result: ${result}`);
248
};
249
250
const funcRef = new interop.FunctionReference(callback);
251
252
// Pass to native function expecting callback
253
someNativeFunctionWithCallback(funcRef);
254
// Keep funcRef alive as long as native code might call it
255
256
// Create Objective-C block for iOS callbacks
257
const blockCallback = (success: boolean, error: NSError) => {
258
if (success) {
259
console.log("Operation completed successfully");
260
} else {
261
console.log(`Operation failed: ${error.localizedDescription}`);
262
}
263
};
264
265
const block = new interop.Block(blockCallback);
266
267
// Pass block to Objective-C method expecting a completion handler
268
someNSObjectMethod.performOperationWithCompletion(block);
269
// Keep block reference alive during async operation
270
```
271
272
### Type System
273
274
Comprehensive type definitions for native type conversion and marshalling.
275
276
```typescript { .api }
277
declare module interop {
278
interface Type<T> {
279
(ptr: Pointer): T;
280
}
281
282
var types: {
283
/** Void type */
284
"void": Type<void>;
285
/** Boolean type */
286
bool: Type<boolean>;
287
/** 8-bit signed integer */
288
int8: Type<number>;
289
/** 8-bit unsigned integer */
290
uint8: Type<number>;
291
/** 16-bit signed integer */
292
int16: Type<number>;
293
/** 16-bit unsigned integer */
294
uint16: Type<number>;
295
/** 32-bit signed integer */
296
int32: Type<number>;
297
/** 32-bit unsigned integer */
298
uint32: Type<number>;
299
/** 64-bit signed integer */
300
int64: Type<number>;
301
/** 64-bit unsigned integer */
302
uint64: Type<number>;
303
/** 32-bit floating point */
304
float: Type<number>;
305
/** 64-bit floating point */
306
double: Type<number>;
307
308
/** UTF-8 C string type */
309
UTF8CString: Type<Reference<number>>;
310
/** Unicode character type */
311
unichar: Type<string>;
312
313
/** Objective-C id type */
314
id: Type<any>;
315
/** Objective-C protocol type */
316
protocol: Type<any>;
317
/** Objective-C class type */
318
"class": Type<any>;
319
/** Objective-C selector type */
320
selector: Type<string>;
321
}
322
}
323
```
324
325
**Usage Examples:**
326
327
```typescript
328
// Use primitive types
329
const intSize = interop.sizeof(interop.types.int32);
330
const doubleSize = interop.sizeof(interop.types.double);
331
332
// Create typed references
333
const intRef = new interop.Reference(interop.types.int32, 42);
334
const floatRef = new interop.Reference(interop.types.float, 3.14);
335
336
// Work with C strings
337
const cStringRef = new interop.Reference(interop.types.UTF8CString);
338
```
339
340
### Struct Types
341
342
Support for C struct definitions and manipulation.
343
344
```typescript { .api }
345
declare module interop {
346
/**
347
* A type for JavaScript constructors for C structs
348
*/
349
interface StructType<T> extends Type<T> {
350
/**
351
* Create a new instance of the struct
352
*/
353
new(): T;
354
355
/**
356
* Create a new instance and initialize from provided object fields
357
* @param obj - Initializer object
358
* @returns New struct instance
359
*/
360
new(obj: T): T;
361
362
/**
363
* Create a new struct by copying memory from pointer
364
* @param obj - Pointer to struct data
365
* @returns New struct instance
366
*/
367
new(obj: Pointer): T;
368
369
/**
370
* Check two structs for equality
371
* @param left - First struct to compare
372
* @param right - Second struct to compare
373
* @returns True if structs are equal
374
*/
375
equals(left: T, right: T): boolean;
376
}
377
}
378
```
379
380
**Usage Examples:**
381
382
```typescript
383
// Define a struct type (example - actual structs depend on iOS SDK)
384
interface CGPoint {
385
x: number;
386
y: number;
387
}
388
389
// Assuming CGPoint is available as StructType
390
const point1 = new CGPoint();
391
point1.x = 10;
392
point1.y = 20;
393
394
const point2 = new CGPoint({ x: 30, y: 40 });
395
396
// Compare structs
397
const areEqual = CGPoint.equals(point1, point2);
398
```
399
400
### Unmanaged References
401
402
Support for unmanaged object references and memory ownership transfer.
403
404
```typescript { .api }
405
declare module interop {
406
/**
407
* A type for propagating an unmanaged object reference
408
* When you use this type, you become partially responsible for keeping the object alive
409
*/
410
interface Unmanaged<T> {
411
/**
412
* Get the value as a managed reference and consume an unbalanced retain
413
* Use when a function returns unmanaged reference and you're responsible for releasing
414
* @returns Managed reference to the object
415
*/
416
takeRetainedValue(): T;
417
418
/**
419
* Get the value as a managed reference without consuming an unbalanced retain
420
* Use when a function returns unmanaged reference and you're not responsible for releasing
421
* @returns Managed reference to the object
422
*/
423
takeUnretainedValue(): T;
424
}
425
}
426
```
427
428
**Usage Examples:**
429
430
```typescript
431
// Handle unmanaged references (typically from native functions)
432
declare function getNativeObjectUnmanaged(): interop.Unmanaged<NSString>;
433
434
// Take ownership of returned object
435
const managedString = getNativeObjectUnmanaged().takeRetainedValue();
436
// You are now responsible for this object
437
438
// Or get without taking ownership
439
const borrowedString = getNativeObjectUnmanaged().takeUnretainedValue();
440
// Someone else manages this object
441
```
442
443
### Error Handling
444
445
Native error handling integration with NSError.
446
447
```typescript { .api }
448
declare module interop {
449
interface NSErrorWrapper extends Error {
450
/** The wrapped NSError instance */
451
error: NSError;
452
}
453
454
var NSErrorWrapper: {
455
new(error: NSError): NSErrorWrapper;
456
(error: NSError): NSErrorWrapper;
457
prototype: NSErrorWrapper;
458
}
459
}
460
```
461
462
**Usage Examples:**
463
464
```typescript
465
// Handle NSError in JavaScript
466
try {
467
// Some operation that might produce NSError
468
const result = someNativeOperationThatMightFail();
469
} catch (error) {
470
if (error instanceof interop.NSErrorWrapper) {
471
const nsError = error.error;
472
console.log(`Native error: ${nsError.localizedDescription}`);
473
console.log(`Error code: ${nsError.code}`);
474
}
475
}
476
477
// Create NSErrorWrapper from NSError
478
const nsError = NSError.errorWithDomainCodeUserInfo("MyDomain", 100, null);
479
const wrapper = new interop.NSErrorWrapper(nsError);
480
```
481
482
## Advanced Usage Patterns
483
484
### Memory Management Best Practices
485
486
```typescript
487
// Use adopted pointers for automatic cleanup
488
const buffer = interop.alloc(1024); // Automatically freed
489
490
// Manual management when needed
491
const rawPtr = new interop.Pointer(0x1000);
492
try {
493
// Use rawPtr...
494
} finally {
495
interop.free(rawPtr);
496
}
497
498
// Reference management
499
const objRef = new interop.Reference<NSString>();
500
someNativeFunctionThatSetsRef(objRef);
501
// objRef.value now contains the result
502
```
503
504
### Type Conversion Patterns
505
506
```typescript
507
// Converting between JavaScript and native types
508
const jsNumber = 42;
509
const nativeInt = new interop.Reference(interop.types.int32, jsNumber);
510
511
// Working with C strings
512
const jsString = "Hello World";
513
const cString = NSString.stringWithString(jsString).UTF8String;
514
515
// Buffer operations
516
const nsData = NSData.dataWithContentsOfFile("/path/to/file");
517
const buffer = interop.bufferFromData(nsData);
518
const uint8Array = new Uint8Array(buffer);
519
```