Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pkgs/objective_c/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
- Add various ObjC categories (extension methods) to the built in classes.
- Add various ObjC protocols to the bindings.
- Make all visible API types public.
- Add a `osVersion` getter, which returns the current MacOS/iOS version.

## 4.1.0

Expand Down
2 changes: 2 additions & 0 deletions pkgs/objective_c/ffigen_c.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ headers:
- 'src/include/dart_api_dl.h'
- 'src/objective_c.h'
- 'src/objective_c_runtime.h'
- 'src/os_version.h'
ffi-native:
assetId: 'objective_c.framework/objective_c'
exclude-all-by-default: true
Expand Down Expand Up @@ -42,6 +43,7 @@ functions:
'DOBJC_newWaiter': 'newWaiter'
'DOBJC_signalWaiter': 'signalWaiter'
'DOBJC_awaitWaiter': 'awaitWaiter'
'DOBJC_getOsVesion': 'getOsVesion'
'sel_registerName': 'registerName'
'sel_getName': 'getName'
'objc_getClass': 'getClass'
Expand Down
2 changes: 2 additions & 0 deletions pkgs/objective_c/lib/objective_c.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

export 'package:pub_semver/pub_semver.dart' show Version;
export 'src/block.dart';
export 'src/c_bindings_generated.dart'
show
Expand Down Expand Up @@ -114,5 +115,6 @@ export 'src/objective_c_bindings_generated.dart'
NSValue,
NSZone,
Protocol;
export 'src/os_version.dart';
export 'src/protocol_builder.dart';
export 'src/selector.dart';
15 changes: 15 additions & 0 deletions pkgs/objective_c/lib/src/c_bindings_generated.dart
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@ external ffi.Pointer<ObjCObject> getObjectClass(
ffi.Pointer<ObjCObject> object,
);

/// Returns the MacOS/iOS version we're running on.
@ffi.Native<_Version Function()>(symbol: "DOBJC_getOsVesion", isLeaf: true)
external _Version getOsVesion();

@ffi.Native<ffi.Pointer<ObjCProtocol> Function(ffi.Pointer<ffi.Char>)>(
symbol: "objc_getProtocol", isLeaf: true)
external ffi.Pointer<ObjCProtocol> getProtocol(
Expand Down Expand Up @@ -261,3 +265,14 @@ final class ObjCObject extends ffi.Opaque {}
final class ObjCProtocol extends ffi.Opaque {}

final class ObjCSelector extends ffi.Opaque {}

final class _Version extends ffi.Struct {
@ffi.Int()
external int major;

@ffi.Int()
external int minor;

@ffi.Int()
external int patch;
}
14 changes: 14 additions & 0 deletions pkgs/objective_c/lib/src/os_version.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:pub_semver/pub_semver.dart';

import 'c_bindings_generated.dart' as c;

Version get osVersion => _osVersion;

Version _osVersion = () {
final ver = c.getOsVesion();
return Version(ver.major, ver.minor, ver.patch);
}();
1 change: 1 addition & 0 deletions pkgs/objective_c/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ dependencies:
ffi: ^2.1.0
flutter:
sdk: flutter
pub_semver: ^2.1.4

dev_dependencies:
args: ^2.6.0
Expand Down
2 changes: 1 addition & 1 deletion pkgs/objective_c/src/objective_c.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ FFI_EXPORT void DOBJC_runOnMainThread(void (*fn)(void *), void *arg);
// Functions for creating a waiter, signaling it, and waiting for the signal. A
// waiter is one-time-use, and the object that newWaiter creates will be
// destroyed once signalWaiter and awaitWaiter are called exactly once.
FFI_EXPORT void* DOBJC_newWaiter();
FFI_EXPORT void* DOBJC_newWaiter(void);
FFI_EXPORT void DOBJC_signalWaiter(void* waiter);
FFI_EXPORT void DOBJC_awaitWaiter(void* waiter);

Expand Down
13 changes: 12 additions & 1 deletion pkgs/objective_c/src/objective_c.m
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#import <dispatch/dispatch.h>

#include "ffi.h"
#include "os_version.h"

FFI_EXPORT void DOBJC_runOnMainThread(void (*fn)(void *), void *arg) {
#ifdef NO_MAIN_THREAD_DISPATCH
Expand Down Expand Up @@ -53,7 +54,7 @@ -(void)wait {
}
@end

FFI_EXPORT void* DOBJC_newWaiter() {
FFI_EXPORT void* DOBJC_newWaiter(void) {
DOBJCWaiter* w = [[DOBJCWaiter alloc] init];
// __bridge_retained increments the ref count, __bridge_transfer decrements
// it, and __bridge doesn't change it. One of the __bridge_retained calls is
Expand All @@ -71,3 +72,13 @@ FFI_EXPORT void DOBJC_signalWaiter(void* waiter) {
FFI_EXPORT void DOBJC_awaitWaiter(void* waiter) {
[(__bridge_transfer DOBJCWaiter*)waiter wait];
}

FFI_EXPORT Version DOBJC_getOsVesion(void) {
NSOperatingSystemVersion objc_version =
[[NSProcessInfo processInfo] operatingSystemVersion];
Version c_version;
c_version.major = objc_version.majorVersion;
c_version.minor = objc_version.minorVersion;
c_version.patch = objc_version.patchVersion;
return c_version;
}
19 changes: 19 additions & 0 deletions pkgs/objective_c/src/os_version.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#ifndef OBJECTIVE_C_SRC_OS_VERSION_H_
#define OBJECTIVE_C_SRC_OS_VERSION_H_

#include "ffi.h"

typedef struct _Version {
int major;
int minor;
int patch;
} Version;

/// Returns the MacOS/iOS version we're running on.
FFI_EXPORT Version DOBJC_getOsVesion(void);

#endif // OBJECTIVE_C_SRC_OS_VERSION_H_
27 changes: 27 additions & 0 deletions pkgs/objective_c/test/os_version_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// Objective C support is only available on mac.
@TestOn('mac-os')
library;

import 'dart:ffi';

import 'package:objective_c/objective_c.dart';
import 'package:test/test.dart';

void main() {
group('osVersion', () {
setUpAll(() {
// TODO(https://github.com/dart-lang/native/issues/1068): Remove this.
DynamicLibrary.open('test/objective_c.dylib');
});

test('getter', () {
// macOS 11 was released in 2020 and isn't supported anymore.
final oldVersion = Version(11, 0, 0);
expect(osVersion, greaterThan(oldVersion));
});
});
}