cupertino_ffi 0.1.5

  • Readme
  • Changelog
  • Example
  • Installing
  • 33

Pub Package

Overview #

This package enables Dart developers to use a large number Objective-C APIs. The package uses dart:ffi and the 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.

Github project #

  • Github project
  • The project appreciates bug reports, suggestions, and general feedback.

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 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.
Multipeer Connectivitydocs"package:cupertino_ffi/multipeer_connectivity.dart"Peer-to-peer connectivity.
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.
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!

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 {
      Pointer 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);
}

0.1.5 #

  • Improved documentation.

0.1.4 #

  • A large number of fixes.

0.1.3 #

  • A large number of fixes.

0.1.2 #

  • Fixed various issues.

0.1.1 #

  • Fixed suggestions by the package analyzer.

0.1.0 #

  • Initial release

example/example.dart

import 'dart:ffi';

import 'package:cupertino_ffi/core_foundation.dart';
import 'package:cupertino_ffi/security.dart';

void main() {
  arcPush();
  try {
    // Allocate an error variable on heap.
    final errorPtrPtr = Pointer<Pointer<CFError>>.allocate();
    errorPtrPtr.cast<IntPtr>().store(0);

    // Define RSA key attributes
    final attributes = CFDictionary.fromPointerMap({
      kSecAttrKeyType: kSecAttrKeyTypeRSA,
      kSecAttrKeySizeInBits: CFNumber.fromDart(2048),
    });

    // Generate a random key.
    final secKey = SecKeyCreateRandomKey(attributes, errorPtrPtr);

    // Check for errors
    final error = CFError.toDart(errorPtrPtr.load<Pointer<CFError>>());
    if (error != null) {
      throw error;
    }

    // Get public key
    final publicKey = SecKeyCopyPublicKey(secKey);
    print(publicKey);
  } finally {
    arcPop();
  }
}

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  cupertino_ffi: ^0.1.5

2. Install it

You can install packages from the command line:

with pub:


$ pub get

Alternatively, your editor might support pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:cupertino_ffi/cloudkit.dart';
import 'package:cupertino_ffi/contacts.dart';
import 'package:cupertino_ffi/core_data.dart';
import 'package:cupertino_ffi/core_foundation.dart';
import 'package:cupertino_ffi/core_location.dart';
import 'package:cupertino_ffi/core_ml.dart';
import 'package:cupertino_ffi/core_spotlight.dart';
import 'package:cupertino_ffi/core_wlan.dart';
import 'package:cupertino_ffi/eventkit.dart';
import 'package:cupertino_ffi/foundation.dart';
import 'package:cupertino_ffi/homekit.dart';
import 'package:cupertino_ffi/natural_language.dart';
import 'package:cupertino_ffi/objective_c.dart';
import 'package:cupertino_ffi/objective_c_helpers.dart';
import 'package:cupertino_ffi/passkit.dart';
import 'package:cupertino_ffi/preferencepanes.dart';
import 'package:cupertino_ffi/safari_services.dart';
import 'package:cupertino_ffi/security.dart';
import 'package:cupertino_ffi/social.dart';
import 'package:cupertino_ffi/speech.dart';
import 'package:cupertino_ffi/storekit.dart';
import 'package:cupertino_ffi/vision.dart';
import 'package:cupertino_ffi/webkit.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
37
Health:
Code health derived from static analysis. [more]
0
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
70
Overall:
Weighted score of the above. [more]
33
Learn more about scoring.

We analyzed this package on Dec 9, 2019, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.6.1
  • pana: 0.12.21

Health issues and suggestions

Fix lib/cloudkit.dart. (-100 points)

Analysis of lib/cloudkit.dart failed with 222 errors, including:

line 27 col 39: The type 'Struct' is declared with 0 type parameters, but 1 type arguments were given.

line 238 col 43: The type 'Struct' is declared with 0 type parameters, but 1 type arguments were given.

line 307 col 29: The type 'Struct' is declared with 0 type parameters, but 1 type arguments were given.

line 548 col 37: The type 'Struct' is declared with 0 type parameters, but 1 type arguments were given.

line 804 col 13: The type 'Struct' is declared with 0 type parameters, but 1 type arguments were given.

Fix lib/contacts.dart. (-100 points)

Analysis of lib/contacts.dart failed with 242 errors, 1 hint, including:

line 27 col 18: The type 'Struct' is declared with 0 type parameters, but 1 type arguments were given.

line 38 col 42: The type 'Struct' is declared with 0 type parameters, but 1 type arguments were given.

line 52 col 13: The type 'Struct' is declared with 0 type parameters, but 1 type arguments were given.

line 125 col 25: The type 'Struct' is declared with 0 type parameters, but 1 type arguments were given.

line 249 col 13: The type 'Struct' is declared with 0 type parameters, but 1 type arguments were given.

Fix lib/core_data.dart. (-100 points)

Analysis of lib/core_data.dart failed with 316 errors, including:

line 27 col 42: The type 'Struct' is declared with 0 type parameters, but 1 type arguments were given.

line 126 col 41: The type 'Struct' is declared with 0 type parameters, but 1 type arguments were given.

line 222 col 29: The type 'Struct' is declared with 0 type parameters, but 1 type arguments were given.

line 573 col 38: The type 'Struct' is declared with 0 type parameters, but 1 type arguments were given.

line 698 col 38: The type 'Struct' is declared with 0 type parameters, but 1 type arguments were given.

Fix additional 34 files with analysis or formatting issues. (-2542.52 points)

Additional issues in the following files:

  • lib/core_ml.dart (97 errors, 1 hint)
  • lib/core_spotlight.dart (45 errors)
  • lib/core_wlan.dart (45 errors, 1 hint)
  • lib/eventkit.dart (155 errors)
  • lib/foundation.dart (636 errors)
  • lib/homekit.dart (147 errors, 1 hint)
  • lib/natural_language.dart (36 errors, 1 hint)
  • lib/social.dart (110 errors)
  • lib/src/security/generated.dart (52 errors)
  • lib/vision.dart (248 errors)
  • lib/webkit.dart (123 errors)
  • lib/storekit.dart (31 errors, 1 hint)
  • lib/core_location.dart (26 errors)
  • lib/preferencepanes.dart (20 errors)
  • lib/safari_services.dart (17 errors, 1 hint)
  • lib/src/core_foundation/generated.dart (13 errors)
  • lib/passkit.dart (10 errors, 1 hint)
  • lib/objective_c_helpers.dart (9 errors, 2 hints)
  • lib/src/objective_c/classes.dart (9 errors)
  • lib/speech.dart (8 errors)
  • lib/src/core_foundation/number.dart (7 errors)
  • lib/src/core_foundation/dictionary.dart (5 errors)
  • lib/src/core_foundation/data.dart (4 errors)
  • lib/src/core_foundation/array.dart (3 errors)
  • lib/src/core_foundation/string.dart (2 errors)
  • lib/src/security/classes.dart (2 errors)
  • lib/src/core_foundation/allocator.dart (1 error)
  • lib/src/core_foundation/boolean.dart (1 error)
  • lib/src/core_foundation/encoding.dart (1 error)
  • lib/src/core_foundation/error.dart (1 error)
  • lib/src/core_foundation/memory_management.dart (1 error)
  • lib/src/core_foundation/mutable_array.dart (1 error)
  • lib/src/core_foundation/mutable_dictionary.dart (1 error)
  • lib/src/core_foundation/type.dart (1 error)

Maintenance issues and suggestions

Fix platform conflicts. (-20 points)

Low code quality prevents platform classification.

Make sure dartdoc successfully runs on your package's source files. (-10 points)

Running dartdoc failed with the following output: FileSystemException: writeFrom failed, path = '/tmp/pub-dartlang-dartdocVVSORK/output/cupertino_ffi/0.1.5/cupertino_ffi.core_location/cupertino_ffi.core_location-library.html' (OS Error: No space left on device, errno = 28)

#0      _RandomAccessFile.writeFrom.<anonymous closure> (dart:io/file_impl.dart:856:9)
#1      StackZoneSpecification._registerUnaryCallback.<anonymous closure>.<anonymous closure> (package:stack_trace/src/stack_zone_specification.dart:129:26)
#2      StackZoneSpecification._run (package:stack_trace/src/stack_zone_specification.dart:209:15)
#3      StackZoneSpecification._registerUnaryCallback.<anonymous closure> (package:stack_trace/src/stack_zone_specification.dart:129:14)
#4      _rootRunUnary (dart:async/zone.dart:1132:38)
#5      _CustomZone.runUnary (dart:async/zone.dart:1029:19)
#6      _FutureListener.handleValue (dart:async/future_impl.dart:137:18)
#7      Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:678:45)
#8      Future._propagateToListeners (dart:async/future_impl.dart:707:32)
#9      Future._completeWithValue (dart:async/future_impl.dart:522:5)
#10     Future._asyncComplete.<anonymous closure> (dart:async/future_impl.dart:552:7)
#11     StackZoneSpecification._run (package:stack_trace/src/stack_zone_specification.dart:209:15)
#12     StackZoneSpecification._registerCallback.<anonymous closure> (package:stack_trace/src/stack_zone_specification.dart:119:48)
#13     _rootRun (dart:async/zone.dart:1124:13)
#14     _CustomZone.run (dart:async/zone.dart:1021:19)
#15     _CustomZone.runGuarded (dart:async/zone.dart:923:7)
#16     _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:963:23)
#17     _microtaskLoop (dart:async/schedule_microtask.dart:41:21)
#18     _startMicrotaskLoop (dart:async/schedule_microtask.dart:50:5)
#19     _runPendingImmediateCallback (dart:isolate-patch/isolate_patch.dart:116:13)
#20     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:173:5)

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.5.0 <3.0.0
ffi ^0.1.1 0.1.3
meta ^1.1.0 1.1.8
Dev dependencies
ffi_tool any
pedantic ^1.8.0
test ^1.6.0