Piano SDK for Flutter
Installation
Add the dependency to your pubspec.yaml:
dependencies:
piano_common: ^1.0.4
Getting Started
Initialize the SDK with your Application ID (AID) and an endpoint:
import 'package:piano_common/piano_common.dart';
final piano = await Piano.init(
endpoint: PianoEndpoint.production,
aid: '<AID>',
);
Endpoints
Use one of the predefined regional endpoints or define a custom one:
// Predefined endpoints
PianoEndpoint.production // Global
PianoEndpoint.productionEurope // EU
PianoEndpoint.productionAustralia // Australia
PianoEndpoint.productionAsiaPacific // Asia-Pacific
PianoEndpoint.sandbox // Sandbox
// Custom endpoint
final custom = PianoEndpoint(
api: 'https://api.piano.io',
composer: 'https://c2.piano.io',
id: 'https://id.piano.io',
);
// Single-URL endpoint (all services on the same host)
final local = PianoEndpoint.fromUrl('http://localhost:8080');
Several Instances
An application reporting to more than one Piano account runs an instance per
account, and names each of them with id:
final news = await Piano.init(
endpoint: PianoEndpoint.production,
aid: '<NEWS_AID>',
id: 'news',
);
final sports = await Piano.init(
endpoint: PianoEndpoint.production,
aid: '<SPORTS_AID>',
id: 'sports',
);
The identifier is what tells the instances apart, so the modules of an instance
key what they open by it — the event storage of piano_cxense, for example, is
named after it. An instance therefore finds what its previous launch left behind
as long as it is created with the same identifier, which makes an identifier worth
keeping stable across releases.
Piano.init accepts an identifier only once as long as the instance carrying it
was not closed, and reports an ArgumentError otherwise; it also rejects an empty
one. Piano.close frees the identifier again, and so does an initialization that
failed — nothing holds the identifier of an instance that was never returned.
An application that names no identifier gets default, which is the single
instance case. piano.client.id reports what an instance carries.
Modules
Optional Piano SDKs are added as modules: pass the configuration of each one to
Piano.init and reach the module it creates through the extension its package
adds to Piano. The modules of an instance are held by
piano.client.modules, and Piano.close releases them.
import 'package:piano_cxense/piano_cxense.dart';
final piano = await Piano.init(
endpoint: PianoEndpoint.production,
aid: '<AID>',
configurations: [PianoCxenseConfiguration()],
);
// Added by piano_cxense; throws a StateError without its configuration.
final cxense = piano.cxense;
await piano.close();
Passing more than one configuration for the same module throws an
ArgumentError, because which of them would apply would otherwise depend on
their order.
A module may need to open a storage or read the platform before it can work, so
Piano.init awaits the creation of every module before it returns the instance.
A module that fails to be created reports its error from Piano.init, after the
modules created before it were closed again — the instance holding them is never
returned, so nothing else would release them.
Consent Configuration
Optionally pass a PianoConsentConfiguration to control consent behavior:
import 'package:piano_consents_flutter/piano_consents_flutter.dart';
final piano = await Piano.init(
endpoint: PianoEndpoint.production,
aid: '<AID>',
consentConfig: PianoConsentConfiguration(),
);
Localization
Pass a language code to localize Piano content. It defaults to en_US:
final piano = await Piano.init(
endpoint: PianoEndpoint.production,
aid: '<AID>',
language: 'fr_FR',
);
The value is available to all Piano services through piano.client.language.
Logging
Enable debug logging by providing a Logger instance:
import 'package:logger/logger.dart';
final piano = await Piano.init(
endpoint: PianoEndpoint.sandbox,
aid: '<AID>',
logger: Logger(),
);