Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
3 changes: 3 additions & 0 deletions lib/onesignal_flutter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import 'package:onesignal_flutter/src/location.dart';
import 'package:onesignal_flutter/src/notifications.dart';
import 'package:onesignal_flutter/src/session.dart';
import 'package:onesignal_flutter/src/user.dart';
import 'package:onesignal_flutter/src/utils.dart';

export 'src/defines.dart';
export 'src/inappmessage.dart';
Expand Down Expand Up @@ -48,6 +49,7 @@ class OneSignal {
/// The initializer accepts an [appId] which the developer can get
/// from the OneSignal consoleas well as a dictonary of [launchOptions]
static Future<void> initialize(String appId) async {
if (isMissing(appId, 'initialize: appId')) return;
await _channel.invokeMethod('OneSignal#initialize', {'appId': appId});
await Future.wait([
InAppMessages.lifecycleInit(),
Expand All @@ -62,6 +64,7 @@ class OneSignal {
/// The act of logging a user into the OneSignal SDK will switch the
/// user context to that specific user.
static Future<void> login(String externalId) async {
if (isMissing(externalId, 'login: externalId')) return;
return await _channel
.invokeMethod('OneSignal#login', {'externalId': externalId});
}
Expand Down
15 changes: 9 additions & 6 deletions lib/src/inappmessages.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'dart:async';
import 'package:flutter/services.dart';
import 'package:onesignal_flutter/onesignal_flutter.dart';
import 'package:onesignal_flutter/src/inappmessage.dart';
import 'package:onesignal_flutter/src/utils.dart';

typedef void OnClickInAppMessageListener(OSInAppMessageClickEvent event);

Expand Down Expand Up @@ -38,24 +39,26 @@ class OneSignalInAppMessages {
/// Adds a single key, value trigger, which will trigger an in app message
/// if one exists matching the specific trigger added
Future<void> addTrigger(String key, String value) async {
if (isMissing(key, 'addTrigger: key')) return;
return await _channel.invokeMethod("OneSignal#addTrigger", {key: value});
}

/// Adds one or more key, value triggers, which will trigger in app messages
/// (one at a time) if any exist matching the specific triggers added
Future<void> addTriggers(Map<String, String> triggers) async {
for (final key in triggers.keys) {
if (isMissing(key, 'addTriggers: key')) return;
}
return await _channel.invokeMethod("OneSignal#addTriggers", triggers);
}

/// Remove a single key, value trigger to prevent an in app message from
/// showing with that trigger
Future<void> removeTrigger(String key) async {
if (isMissing(key, 'removeTrigger: key')) return;
return await _channel.invokeMethod("OneSignal#removeTrigger", key);
}

/// Remove one or more key, value triggers to prevent any in app messages
/// from showing with those triggers
Future<void> removeTriggers(List<String> keys) async {
for (final key in keys) {
if (isMissing(key, 'removeTriggers: key')) return;
}
return await _channel.invokeMethod("OneSignal#removeTriggers", keys);
}

Expand Down
24 changes: 24 additions & 0 deletions lib/src/liveactivities.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:onesignal_flutter/src/utils.dart';

class OneSignalLiveActivities {
// private channels used to bridge to ObjC/Java
Expand All @@ -10,6 +11,10 @@ class OneSignalLiveActivities {
///
/// Only applies to iOS.
Future<void> enterLiveActivity(String activityId, String token) async {
if (isMissing(activityId, 'enterLiveActivity: activityId') ||
isMissing(token, 'enterLiveActivity: token')) {
return;
}
if (defaultTargetPlatform == TargetPlatform.iOS) {
return await _channel.invokeMethod("OneSignal#enterLiveActivity",
{'activityId': activityId, 'token': token});
Expand All @@ -21,6 +26,7 @@ class OneSignalLiveActivities {
/// Only applies to iOS.
@Deprecated('Currently unsupported, avoid using this method.')
Future<void> exitLiveActivity(String activityId) async {
if (isMissing(activityId, 'exitLiveActivity: activityId')) return;
if (defaultTargetPlatform == TargetPlatform.iOS) {
return await _channel.invokeMethod(
"OneSignal#exitLiveActivity", {'activityId': activityId});
Expand Down Expand Up @@ -62,6 +68,11 @@ class OneSignalLiveActivities {
/// Only applies to iOS.
Future<void> startDefault(
String activityId, dynamic attributes, dynamic content) async {
if (isMissing(activityId, 'startDefault: activityId') ||
!_isMap(attributes, 'startDefault: attributes') ||
!_isMap(content, 'startDefault: content')) {
return;
}
if (defaultTargetPlatform == TargetPlatform.iOS) {
return await _channel.invokeMethod("OneSignal#startDefault", {
'activityId': activityId,
Expand All @@ -78,6 +89,10 @@ class OneSignalLiveActivities {
///
/// Only applies to iOS.
Future<void> setPushToStartToken(String activityType, String token) async {
if (isMissing(activityType, 'setPushToStartToken: activityType') ||
isMissing(token, 'setPushToStartToken: token')) {
return;
}
if (defaultTargetPlatform == TargetPlatform.iOS) {
return await _channel.invokeMethod("OneSignal#setPushToStartToken",
{'activityType': activityType, 'token': token});
Expand All @@ -90,11 +105,20 @@ class OneSignalLiveActivities {
///
/// Only applies to iOS.
Future<void> removePushToStartToken(String activityType) async {
if (isMissing(activityType, 'removePushToStartToken: activityType')) {
return;
}
if (defaultTargetPlatform == TargetPlatform.iOS) {
return await _channel.invokeMethod(
"OneSignal#removePushToStartToken", {'activityType': activityType});
}
}

bool _isMap(Object? value, String api) {
if (value is Map) return true;
logError('$api must be a map');
return false;
}
}

/// The setup options for [OneSignal.LiveActivities.setupDefault].
Expand Down
5 changes: 5 additions & 0 deletions lib/src/notifications.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:onesignal_flutter/src/defines.dart';
import 'package:onesignal_flutter/src/notification.dart';
import 'package:onesignal_flutter/src/utils.dart';

typedef void OnNotificationPermissionChangeObserver(bool permission);

Expand Down Expand Up @@ -84,6 +85,10 @@ class OneSignalNotifications {

/// Removes a grouped notification.
Future<void> removeGroupedNotifications(String notificationGroup) async {
if (isMissing(
notificationGroup, 'removeGroupedNotifications: notificationGroup')) {
return;
}
if (defaultTargetPlatform == TargetPlatform.android) {
return await _channel.invokeMethod("OneSignal#removeGroupedNotifications",
{'notificationGroup': notificationGroup});
Expand Down
8 changes: 8 additions & 0 deletions lib/src/session.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'dart:async';
import 'package:flutter/services.dart';
import 'package:onesignal_flutter/src/utils.dart';

class OneSignalSession {
// private channels used to bridge to ObjC/Java
Expand All @@ -8,18 +9,25 @@ class OneSignalSession {
/// Send a normal outcome event for the current session and notifications with the attribution window
/// Counted each time sent successfully, failed ones will be cached and reattempted in future
Future<void> addOutcome(String name) async {
if (isMissing(name, 'addOutcome: name')) return;
return await _channel.invokeMethod("OneSignal#addOutcome", name);
}

/// Send a unique outcome event for the current session and notifications with the attribution window
/// Counted once per notification when sent successfully, failed ones will be cached and reattempted in future
Future<void> addUniqueOutcome(String name) async {
if (isMissing(name, 'addUniqueOutcome: name')) return;
return await _channel.invokeMethod("OneSignal#addUniqueOutcome", name);
}

/// Send an outcome event with a value for the current session and notifications with the attribution window
/// Counted each time sent successfully, failed ones will be cached and reattempted in future
Future<void> addOutcomeWithValue(String name, double value) async {
if (isMissing(name, 'addOutcomeWithValue: name')) return;
if (!value.isFinite) {
logError('addOutcomeWithValue: value must be a finite number');
return;
}
return await _channel.invokeMethod("OneSignal#addOutcomeWithValue",
{"outcome_name": name, "outcome_value": value});
}
Expand Down
35 changes: 35 additions & 0 deletions lib/src/user.dart
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ class OneSignalUser {
/// Sets the user's language to [language] this also applies to
/// the email and/or SMS player if those are logged in on the device.
Future<void> setLanguage(String language) async {
// Empty string is the reset to the device language.
return await _channel.invokeMethod("OneSignal#setLanguage", {
'language': language,
});
Expand All @@ -72,23 +73,36 @@ class OneSignalUser {
/// If this [alias] label already exists on this user,
/// it will be overwritten with the new alias [id].
Future<void> addAlias(String alias, dynamic id) async {
if (isMissing(alias, 'addAlias: label') || isMissing(id, 'addAlias: id')) {
return;
}
return await this.addAliases({alias: id});
}

/// Set [aliases] for the current user.
///
/// If any alias already exists, it will be overwritten to the new values.
Future<void> addAliases(Map<String, dynamic> aliases) async {
for (final label in aliases.keys) {
if (isMissing(label, 'addAliases: label') ||
isMissing(aliases[label], 'addAliases: id')) {
return;
}
}
return await _channel.invokeMethod("OneSignal#addAliases", aliases);
}

/// Remove an [alias] from the current user.
Future<void> removeAlias(String label) async {
if (isMissing(label, 'removeAlias: label')) return;
return await this.removeAliases([label]);
}

/// Remove [aliases] from the current user.
Future<void> removeAliases(List<String> aliases) async {
for (final label in aliases) {
if (isMissing(label, 'removeAliases: label')) return;
}
return await _channel.invokeMethod("OneSignal#removeAliases", aliases);
}

Expand All @@ -98,6 +112,11 @@ class OneSignalUser {
/// specific users and/or personalizing messages. If the tag [key] already
/// exists, it will be replaced with the [value] provided here.
Future<void> addTagWithKey(String key, dynamic value) async {
if (isMissing(key, 'addTag: key')) return;
if (value == null) {
logError('addTag: value is required');
return;
}
return await this.addTags({key: value.toString()});
}

Expand All @@ -107,6 +126,13 @@ class OneSignalUser {
/// specific users and/or personalizing messages. If the tag key already
/// exists, it will be replaced with the value provided here.
Future<void> addTags(Map<String, dynamic> tags) async {
for (final key in tags.keys) {
if (isMissing(key, 'addTags: key')) return;
if (tags[key] == null) {
logError('addTags: value is required');
return;
}
}
tags.forEach((key, value) {
tags[key] = value.toString();
});
Expand All @@ -115,11 +141,15 @@ class OneSignalUser {

/// Remove the data tag with the provided [key] from the current user.
Future<void> removeTag(String key) async {
if (isMissing(key, 'removeTag: key')) return;
return await this.removeTags([key]);
}

/// Remove multiple [tags] with the provided keys from the current user.
Future<void> removeTags(List<String> tags) async {
for (final key in tags) {
if (isMissing(key, 'removeTags: key')) return;
}
return await _channel.invokeMethod("OneSignal#removeTags", tags);
}

Expand All @@ -133,6 +163,7 @@ class OneSignalUser {

/// Add a new [email] subscription to the current user.
Future<void> addEmail(String email) async {
if (isMissing(email, 'addEmail: email')) return;
return await _channel.invokeMethod("OneSignal#addEmail", email);
}

Expand All @@ -141,13 +172,15 @@ class OneSignalUser {
/// Returns false if the specified [email] does not exist
/// on the user within the SDK, and no request will be made.
Future<void> removeEmail(String email) async {
if (isMissing(email, 'removeEmail: email')) return;
return await _channel.invokeMethod("OneSignal#removeEmail", email);
}

/// Add a new SMS subscription to the current user.
///
/// Add an SMS subscription by adding an [smsNumber]
Future<void> addSms(String smsNumber) async {
if (isMissing(smsNumber, 'addSms: smsNumber')) return;
return await _channel.invokeMethod("OneSignal#addSms", smsNumber);
}

Expand All @@ -156,6 +189,7 @@ class OneSignalUser {
/// Returns false if the specified [smsNumber] does not
/// exist on the user within the SDK, and no request will be made.
Future<void> removeSms(String smsNumber) async {
if (isMissing(smsNumber, 'removeSms: smsNumber')) return;
return await _channel.invokeMethod("OneSignal#removeSms", smsNumber);
}

Expand All @@ -175,6 +209,7 @@ class OneSignalUser {
/// [properties] is an optional map of custom properties associated with the event.
Future<void> trackEvent(String name,
[Map<String, dynamic>? properties]) async {
if (isMissing(name, 'trackEvent: name')) return;
return await _channel.invokeMethod("OneSignal#trackEvent", {
'name': name,
'properties': properties,
Expand Down
10 changes: 10 additions & 0 deletions lib/src/utils.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
import 'dart:convert';

import 'package:flutter/foundation.dart';

void logError(String message) => debugPrint('[OneSignal] $message');

bool isMissing(Object? value, String api) {
if (value is String && value.isNotEmpty) return false;
logError('$api is required');
return true;
}

/// An abstract class to provide JSON decoding
abstract class JSONStringRepresentable {
String jsonRepresentation();
Expand Down
Loading
Loading