Skip to content

Commit 5c7152e

Browse files
authored
[objective_c] CFString conversions (#2293)
1 parent 6d51ecf commit 5c7152e

File tree

7 files changed

+57
-0
lines changed

7 files changed

+57
-0
lines changed

pkgs/ffigen/lib/src/code_generator/objc_built_in_functions.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ class ObjCBuiltInFunctions {
9999
static const builtInCompounds = {
100100
'AEDesc': 'AEDesc',
101101
'__CFRunLoop': 'CFRunLoop',
102+
'__CFString': 'CFString',
102103
'CGPoint': 'CGPoint',
103104
'CGRect': 'CGRect',
104105
'CGSize': 'CGSize',

pkgs/objective_c/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
- `NSSet` and `NSMutableSet` are now Dart `Set`s.
77
- Add `.toNSNumber()` extension method to `int`, `double`, and `num`.
88
- Add `DateTime.toNSDate()` and `NSDate.toDateTime()` extension methods.
9+
- Add `CFStringRef.toDartString()` and `CFStringRef.toNSString()`.
910
- Add `toObjCObject` and `toDartObject` that automatically convert between
1011
supported Objective C and Dart types.
1112
- Added various interfaces, protocols, categories etc to the built ins, such as

pkgs/objective_c/ffigen_objc.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ structs:
106106
include:
107107
- AEDesc
108108
- __CFRunLoop
109+
- __CFString
109110
- CGPoint
110111
- CGRect
111112
- CGSize
@@ -116,6 +117,7 @@ structs:
116117
- OpaqueAEDataStorageType
117118
rename:
118119
__CFRunLoop: CFRunLoop
120+
__CFString: CFString
119121
_NSRange: NSRange
120122
_NSZone: NSZone
121123
enums:
@@ -153,6 +155,9 @@ enums:
153155
globals:
154156
include:
155157
- NSLocalizedDescriptionKey
158+
typedefs:
159+
include:
160+
- 'CFStringRef'
156161
preamble: |
157162
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
158163
// for details. All rights reserved. Use of this source code is governed by a

pkgs/objective_c/lib/objective_c.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export 'src/c_bindings_generated.dart'
1818
objectRelease,
1919
objectRetain,
2020
signalWaiter;
21+
export 'src/cf_string.dart';
2122
export 'src/converter.dart';
2223
export 'src/internal.dart'
2324
hide blockHasRegisteredClosure, isValidBlock, isValidClass, isValidObject;
@@ -32,6 +33,8 @@ export 'src/objective_c_bindings_generated.dart'
3233
show
3334
AEDesc,
3435
CFRunLoop,
36+
CFString,
37+
CFStringRef,
3538
CGPoint,
3639
CGRect,
3740
CGSize,
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'ns_string.dart';
6+
import 'objective_c_bindings_generated.dart';
7+
8+
extension CFStringRefConversions on CFStringRef {
9+
NSString toNSString() =>
10+
NSString.castFromPointer(cast(), retain: true, release: true);
11+
12+
String toDartString() => NSString.castFromPointer(cast()).toDartString();
13+
}

pkgs/objective_c/lib/src/objective_c_bindings_generated.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,10 @@ final class AEDesc extends ffi.Struct {
321321

322322
final class CFRunLoop extends ffi.Opaque {}
323323

324+
final class CFString extends ffi.Opaque {}
325+
326+
typedef CFStringRef = ffi.Pointer<CFString>;
327+
324328
final class CGPoint extends ffi.Struct {
325329
@ffi.Double()
326330
external double x;
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
// Objective C support is only available on mac.
6+
@TestOn('mac-os')
7+
library;
8+
9+
import 'dart:ffi';
10+
11+
import 'package:objective_c/objective_c.dart';
12+
import 'package:test/test.dart';
13+
14+
void main() {
15+
group('CFString', () {
16+
setUpAll(() {
17+
// TODO(https://github.com/dart-lang/native/issues/1068): Remove this.
18+
DynamicLibrary.open('test/objective_c.dylib');
19+
});
20+
21+
for (final s in ['Hello', '🇵🇬', 'Embedded\u0000Null']) {
22+
test('CFString conversions [$s]', () {
23+
final cfString =
24+
s.toNSString().ref.retainAndAutorelease().cast<CFString>();
25+
expect(cfString.toDartString(), s);
26+
expect(cfString.toNSString().toDartString(), s);
27+
});
28+
}
29+
});
30+
}

0 commit comments

Comments
 (0)