Skip to content

WIP: Swiftgen prototype and example #1367

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 48 commits into
base: main
Choose a base branch
from
Draft

WIP: Swiftgen prototype and example #1367

wants to merge 48 commits into from

Conversation

liamappelbe
Copy link
Contributor

@liamappelbe liamappelbe commented Jul 22, 2024

This is a prototype of swiftgen, and an example program that uses the Swift AVAudioPlayer API to play some audio from Dart.

example/generate_code.dart uses swiftgen to generate Dart bindings like this:

await generate(Config(
  target: Target(
    triple: 'x86_64-apple-macosx14.0',
    sdk: Uri.directory(
        '/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk'),
  ),
  input: SwiftModuleInput(module: 'AVFAudio'),
  tempDir: Uri.directory('temp'),
  outputModule: 'AVFAudioWrapper',
  objcSwiftFile: Uri.file('avf_audio_wrapper.swift'),
  ffigen: FfiGenConfig(
    output: Uri.file('avf_audio_bindings.dart'),
    outputObjC: Uri.file('avf_audio_wrapper.m'),
    externalVersions: ffigen.ExternalVersions(
      ios: ffigen.Versions(min: Version(12, 0, 0)),
      macos: ffigen.Versions(min: Version(10, 14, 0)),
    ),
    objcInterfaces: ffigen.DeclarationFilters(
      shouldInclude: (decl) => decl.originalName == 'AVAudioPlayerWrapper',
    ),
  ),
));

Then example/play_audio.dart uses the generated Dart bindings to play audio:

for (final file in args) {
  final fileStr = NSString(file);
  print('Loading $fileStr');
  final fileUrl = NSURL.fileURLWithPath_(fileStr);
  final player = AVAudioPlayerWrapper.alloc()
      .initWithContentsOf_error_(fileUrl, nullptr);
  if (player == null) {
    print('Failed to load audio');
    continue;
  }
  final durationSeconds = player.duration.ceil();
  print('$durationSeconds sec');
  final status = player.play();
  if (status) {
    print('Playing...');
    await Future<void>.delayed(Duration(seconds: durationSeconds));
  } else {
    print('Failed to play audio.');
  }
}

There are a few remaining hacks to iron out, due to #1775 and #1774.

@github-actions github-actions bot added type-infra A repository infrastructure change or enhancement package:swiftgen labels Jul 22, 2024
@github-actions github-actions bot removed the type-infra A repository infrastructure change or enhancement label Jul 22, 2024
Copy link

github-actions bot commented Aug 6, 2024

PR Health

Breaking changes ✔️
Package Change Current Version New Version Needed Version Looking good?
Changelog Entry ✔️
Package Changed Files

Changes to files need to be accounted for in their respective changelogs.

API leaks ✔️

The following packages contain symbols visible in the public API, but not exported by the library. Export these symbols or remove them from your publicly visible API.

Package Leaked API symbols
License Headers ✔️
// 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.
Files
no missing headers

All source files should start with a license header.

Unrelated files missing license headers
Files
pkgs/jni/lib/src/third_party/generated_bindings.dart
pkgs/native_doc_dartifier/lib/native_doc_dartifier.dart
pkgs/native_doc_dartifier/lib/src/native_doc_dartifier_base.dart
pkgs/native_doc_dartifier/tool/compile_java.dart
pkgs/objective_c/lib/src/ns_input_stream.dart

@liamappelbe liamappelbe changed the title WIP: swiftgen prototype WIP: Swiftgen prototype and example Dec 4, 2024
@orestesgaolin
Copy link

Hey there, would you be able to briefly explain how could I run this locally? Should I execute example/generate_code.dart?

@liamappelbe
Copy link
Contributor Author

@orestesgaolin Yeah, if you want to try the example you can run example/generate_code.dart to regenerate the bindings (avf_audio_bindings.dart etc) and example/play_audio.dart foo.mp3 to run the example.

@dcharkes
Copy link
Collaborator

Given we have a merged https://github.com/dart-lang/native/tree/main/pkgs/swiftgen, I presume this can be closed.

@dcharkes dcharkes closed this Mar 26, 2025
@orestesgaolin
Copy link

I don't see swiftgen updated on main... Is that something that needs to be synchronized with google's repos?
screenshot_20250326_085933

@dcharkes
Copy link
Collaborator

dcharkes commented Mar 26, 2025

Oh, it's an empty directory, my bad! (I was in overzealous spring-cleaning-mode!)

@dcharkes dcharkes reopened this Mar 26, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants