Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
@objc annotation
  • Loading branch information
tarrinneal committed Mar 22, 2024
commit a992a23223b8fd9fbdd5d1b71826f84756278cd3
6 changes: 6 additions & 0 deletions packages/pigeon/lib/ast.dart
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,7 @@ class Class extends Node {
Class({
required this.name,
required this.fields,
this.isSwiftObjcInteropClass = false,
this.isSwiftClass = false,
this.documentationComments = const <String>[],
});
Expand All @@ -649,6 +650,11 @@ class Class extends Node {
/// All the fields contained in the class.
List<NamedType> fields;

/// Determines whether the defined class should inherit from NSObject in Swift.
///
/// Defaults to false.
bool isSwiftObjcInteropClass;

/// Determines whether the defined class should be represented as a struct or
/// a class in Swift generation.
///
Expand Down
8 changes: 8 additions & 0 deletions packages/pigeon/lib/pigeon_lib.dart
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,12 @@ class SwiftClass {
const SwiftClass();
}

/// Metadata to annotate data classes to be defined as inheriting from NSObject.
class SwiftObjcInteropClass {
/// Constructor.
const SwiftObjcInteropClass();
}

/// Type of TaskQueue which determines how handlers are dispatched for
/// HostApi's.
enum TaskQueueType {
Expand Down Expand Up @@ -1557,6 +1563,8 @@ class _RootBuilder extends dart_ast_visitor.RecursiveAstVisitor<Object?> {
name: node.name.lexeme,
fields: <NamedType>[],
isSwiftClass: _hasMetadata(node.metadata, 'SwiftClass'),
isSwiftObjcInteropClass:
_hasMetadata(node.metadata, 'SwiftObjcInteropClass'),
documentationComments:
_documentationCommentsParser(node.documentationComment?.tokens),
);
Expand Down
7 changes: 6 additions & 1 deletion packages/pigeon/lib/swift_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,12 @@ class SwiftGenerator extends StructuredGenerator<SwiftOptions> {
generatorComments: generatedComments);

if (classDefinition.isSwiftClass) {
indent.write('class ${classDefinition.name} ');
String inheritNSObject = '';
if (classDefinition.isSwiftObjcInteropClass) {
inheritNSObject = ': NSObject';
indent.writeln('@objc');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

iirc @objc isn't necessary since it's already a subclass of NSObject, which is already exposed to objc runtime.

Copy link
Contributor

@hellohuanlin hellohuanlin Mar 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh sorry i missed it in my previous review - in addition to the above, we probably need to add @objc for all custom members that are not inherited from NSObject (basically all the properties and the init function defined here).

Can you also write some ObjC tests to make sure it works? (requesting changes since this is not tested)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all properties? even primitives? or only custom types?

Copy link
Contributor

@hellohuanlin hellohuanlin Mar 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All properties and methods that are not inherited from NSObject need to be annotated, in order for them to be accessible by objc runtime. The class definition itself and its members inherited from NSObject are already implicitly annotated.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So yes, even the properties of primitive types.

}
indent.write('class ${classDefinition.name}$inheritNSObject ');
} else {
indent.write('struct ${classDefinition.name} ');
}
Expand Down
1 change: 1 addition & 0 deletions packages/pigeon/pigeons/core_tests.dart
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class AllTypes {

/// A class containing all supported nullable types.
@SwiftClass()
@SwiftObjcInteropClass()
class AllNullableTypes {
AllNullableTypes(
this.aNullableBool,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,8 @@ struct AllTypes {
/// A class containing all supported nullable types.
///
/// Generated class from Pigeon that represents data sent in messages.
class AllNullableTypes {
@objc
class AllNullableTypes: NSObject {
init(
aNullableBool: Bool? = nil,
aNullableInt: Int64? = nil,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,8 @@ struct AllTypes {
/// A class containing all supported nullable types.
///
/// Generated class from Pigeon that represents data sent in messages.
class AllNullableTypes {
@objc
class AllNullableTypes: NSObject {
init(
aNullableBool: Bool? = nil,
aNullableInt: Int64? = nil,
Expand Down