Pub Package

Overview

This package enables Dart developers to use a large number Objective-C APIs. The package uses dart:ffi and the C APIs are generated with ffi_tool.

Most Flutter developers should not use this package. It's usually a better idea to write a Flutter plugin than use this package. Flutter plugins are less likely to contain memory management bugs, they are automatically isolated from the UI event loop, they support all APIs, and the development experience is just a lot better.

The advantages of this package are automatic generation of APIs (no need to write message passing code) and support for non-Flutter applications.

If you decide to use this package, you must follow the correct reference counting patterns. The patterns are documented below.

Contributing

Core foundation

  • Documentation: developer.apple.com
  • Import "package:cupertino_ffi/core_foundation.dart"
  • Note that Foundation types (NSString, etc.) and Core Foundation types (CFString, etc.) are "toll-free" bridged types. This means that Pointer<CFString> can be used as Pointer<NSString> and vice-versa.

Generated libraries

Dartdoc can be found here.

NameDocumentationImportDescription
CloudKitdocs"package:cupertino_ffi/cloudkit.dart"Cloud-based storage.
Contactsdocs"package:cupertino_ffi/contacts.dart"Contacts.
Core Datadocs"package:cupertino_ffi/core_data.dart"Loading and storing data.
Core Graphicsdocs"package:cupertino_ffi/core_graphics.dart"Images.
Core Locationdocs"package:cupertino_ffi/core_location.dart"Geographical location.
Core MLdocs"package:cupertino_ffi/core_ml.dart"Machine learning.
Core Spotlightdocs"package:cupertino_ffi/core_spotlight.dart"Search.
Core WLANdocs"package:cupertino_ffi/core_wlan.dart"WLAN.
EventKitdocs"package:cupertino_ffi/eventkit.dart"Calendar events.
Foundationdocs"package:cupertino_ffi/foundation.dart"Essential APIs.
HomeKitdocs"package:cupertino_ffi/homekit.dart"Home automation.
Multipeer Connectivitydocs"package:cupertino_ffi/multipeer_connectivity.dart"Peer-to-peer connectivity.
ModelIOdocs"package:cupertino_ffi/modelio.dart"3D model assets.
Natural Languagedocs"package:cupertino_ffi/natural_language.dart"Natural language processing (NLP).
Objective-C runtimedocs"package:cupertino_ffi/objective_c.dart"Objective-C internals.
PassKitdocs"package:cupertino_ffi/passkit.dart"Apple Pay and Apple Wallet.
PreferencePanesdocs"package:cupertino_ffi/preferencepanes.dart"System preferences.
SceneKitdocs"package:cupertino_ffi/scenekit.dart"3D rendering.
Securitydocs"package:cupertino_ffi/security.dart"Keychain, cryptography, authentication.
Speechdocs"package:cupertino_ffi/speech.dart"Speech recognition.
Socialdocs"package:cupertino_ffi/social.dart"Social media.
StoreKitdocs"package:cupertino_ffi/storekit.dart"App Store.
Visiondocs"package:cupertino_ffi/vision.dart"Computer vision.
WebKitdocs"package:cupertino_ffi/webkit.dart"Browser engine.

Want to add a library? Create an issue!

Generating bindings for an Objective-C library

Objective-C supports reflection so we are able to generate APIs automatically. The generated libraries use cupertino_ffi for reference counting. Please make sure you understand the reference counting patterns that you need to follow when you use the generated library.

For example, our generator script looks like this:

import 'package:cupertino_ffi/objc_ffi_generator.dart';

void main() {
  generateAll(ObjcBinding(
    libraries: libraries,
    packageName: "cupertino_ffi",
  ));
}

final libraries = [
  ObjcLibraryBinding(
    dynamicLibrary: DynamicLibraryInfo(
      path: "/System/Library/Frameworks/CloudKit.framework/Versions/A/CloudKit",
      name: "CloudKit",
      url: "https://developer.apple.com/documentation/cloudkit?language=objc",
    ),
    name: "cloudkit",
  ),

  ObjcLibraryBinding(
    dynamicLibrary: DynamicLibraryInfo(
      path: "/System/Library/Frameworks/CoreData.framework/Versions/A/CoreData",
      name: "Core Data",
      url: "https://developer.apple.com/documentation/coredata?language=objc",
    ),
    name: "core_data",
  ),

  // ...
];

Memory management patterns

Calling APIs that return ARC pointers

If you call any API that returns a reference-counter pointer, you need to call arcPush and arcPop like in the following example:

String example() {
    // Push a new ARC frame.
    arcPush();
    try {
      final pointer = CFDictionary.fromDart({"key": "value"});
      return "some return value";
    } finally {
      // Pop the topmost ARC frame.
      arcPop();
    }
}

Returning ARC pointers

If you return a pointer to reference counted value, you must call function 'arcReturn', which inserts the pointer into caller's reference counting frame and increments the reference count (so it will 2 before 'arcPop').

Example:

Pointer<CFDictionary> example() {
    arcPush();
    try {
      final result = CFDictionary.fromDart({"key": "value"});
      return arcReturn(result);
    } finally {
      arcPop();
    }
}

Storing ARC pointer

You need to ensure that arcFieldGet is invoked in the getter and arcFieldSet is invoked in the setter.

import 'package:cupertino_ffi/core_foundation.dart';

Pointer<CFString> _field;

Pointer<CFString> get field => arcFieldGet(_field);

set field(Pointer<CFString> newValue) {
  _field = arcFieldSet(_field, newValue);
}

Generating Objective-C bindings yourself

import 'package:ffi_tool/objective_c.dart';

void main() {
  generateAll([
    ObjcLibrary(
      // Just for documentation purposes
      productName: "Core ML",
      uri: "https://developer.apple.com/documentation/coreml",

      // For generated source code
      libraryName: "example",
      libraryPath: "/System/Library/Frameworks/CoreML.framework/Versions/Current/CoreML",
      generatedPath: "core_ml.dart",
    ),
  ]);
}

Libraries

cupertino_ffi.cloudkit
Automatically generated API for CloudKit. [...]
cupertino_ffi.contacts
Automatically generated API for Contacts. [...]
cupertino_ffi.core_data
Automatically generated API for Core Data. [...]
cupertino_ffi.core_foundation
Bindings for Core Foundation in iOS/Mac OS X.
cupertino_ffi.core_graphics
Bindings for Core Graphics in iOS and Mac OS X.
cupertino_ffi.core_location
Automatically generated API for Core Location. [...]
cupertino_ffi.core_ml
Automatically generated API for Core ML. [...]
cupertino_ffi.core_spotlight
Automatically generated API for Core Spotlight. [...]
cupertino_ffi.core_wlan
Automatically generated API for Core WLAN. [...]
cupertino_ffi.eventkit
Automatically generated API for EventKit. [...]
cupertino_ffi.foundation
Automatically generated API for Foundation. [...]
cupertino_ffi.homekit
Automatically generated API for HomeKit. [...]
cupertino_ffi.modelio
Automatically generated API for ModelIO. [...]
cupertino_ffi.natural_language
Automatically generated API for Natural Language. [...]
cupertino_ffi.objc_ffi_generator
Generates Dart libraries that expose Objective-C libraries.
cupertino_ffi.objective_c
C bindings for Objective-C runtime.
cupertino_ffi.objective_c_helpers
Helpers for working with Objective-C bindings.
cupertino_ffi.passkit
Automatically generated API for PassKit. [...]
cupertino_ffi.preferencepanes
Automatically generated API for PreferencePanes. [...]
cupertino_ffi.safari_services
Automatically generated API for SafariServices. [...]
cupertino_ffi.scenekit
Automatically generated API for SceneKit. [...]
cupertino_ffi.security
Bindings for Security framework in iOS/Mac OS X.
cupertino_ffi.social
Automatically generated API for Social. [...]
cupertino_ffi.speech
Automatically generated API for Speech. [...]
cupertino_ffi.storekit
Automatically generated API for StoreKit. [...]
cupertino_ffi.vision
Automatically generated API for Vision. [...]
cupertino_ffi.webkit
Automatically generated API for WebKit. [...]