Flutter SDK for Dengage SDKs

dengage_flutter

D·engage Customer Driven Marketing Platform (CDMP) serves as a customer data platform (CDP) with built-in omnichannel marketing features. It replaces your marketing automation and cross-channel campaign management. For further details about D·engage please visit here.

This package makes it easy to integrate, D·engage, with your React-Native iOS and/or Android apps. Following are instructions for installation of react-native-dengage SDK to your react-native applications.

Quick Video Guide

Here is a quick video guide on how to install dengage_flutter SDK to your flutter application using this documentation. Guide consists of 2 parts please watch both in sequence.

[Part 1] (https://youtu.be/YP1WZdn7rgE) [Part 2] (https://youtu.be/SMmAtPCtZUY)

Installation

a) Edit your project's pubspec.yaml file to include the dengage_flutter SDK:


dependencies:
    dengage_flutter: ^0.0.8
    

b) Run flutter pub get to install the SDK.

c) In your Dart code, access DengageFlutter with:

// at top in imports
import 'package:dengage_flutter/dengage_flutter.dart'

// somewhere down in the code
  try {
    Object result = await DengageFlutter.setIntegerationKey("");
    print("result: $result");
  } on PlatformException catch (error) {
    print("error: $error");
  } on Exception catch (error) {
    print("exception: $error");
  }

Platform Specific Extra Steps

Following extra steps after the installation of the dengage_flutter SDK are required for it to work properly.

iOS Specific Extra steps

Requirements

  • D·engage Integration Key
  • iOS Push Cerificate
  • iOS Device (you need to test on a real device for notifications)
  • A mac with latest Xcode

Steps

1. Endpoint Configuration in PInfo.list

For initial setup, if you have given URL addresses by D·engage Support team, you need to setup url address by using Info.plist file. Otherwise you don’t need to add anything to Info.plist file. Following screenshot for the keys in Info.plist file.

Info.plist screenshot

Note: Please see API Endpoints by Datacenter documentation in this section for end points. here is link

2. Add Required Capabilities

In Xcode, select the root project and main app target. In Signing & Capabilities, select All and + Capability. Add "Push Notifications" and Background Modes. Kindly make sure to tick Remote Notifications in Background Modes.

screenshot 1

push notifications

screenshot 2

background modes

3. Add Notification Service Extension (required only if using rich notifications)

The DengageNotificationServiceExtension allows your application to receive rich notifications with images and/or buttons, and to report analytics about which notifications users receive. 3.1 In Xcode Select File > New > Target 3.2 Select Notification Service Extension then press Next

step 3.2 screenshot

3.3 Enter the product name as DengageNotificationServiceExtension and press Finish.

Do NOT press "Activate" on the dialog shown after this.

step 3.3 screenshot

3.4 Press Cancel on the Activate scheme prompt.

step 3.4 screenshot

By canceling, you are keeping Xcode debugging your app, instead of just the extension. If you activate by accident, you can always switch back to debug your app within Xcode (next to the play button).

3.5 In the Project Navigator, select the top-level project directory and select the DengageNotificationServiceExtension target in the project and targets list. Ensure the Deployment Target is set to iOS 10 for maximum platform compatibility.

step 3_5 screenshot

3.6 Finish Notification Service Extension Setup

If you did not use Cocoapods, follow these steps.

Note: non-cocoapods steps yet to be determined.

Otherwise, continue with the following setup:

  • In your Project Root > iOS > Podfile, add the notification service extension outside the main target (should be at the same level as your main target):
    target 'DengageNotificationServiceExtension' do
      pod 'Dengage.Framework',‘~> 3.0.6’
    end

Close Xcode. While still in the ios directory, run pod install again.

  • Open the .xcworkspace file in Xcode. In the DengageNotificationServiceExtension directory > NotificationService.swift file, replace the whole file contents with the code below:
      override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
        self.contentHandler = contentHandler
        bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
         
        if let bestAttemptContent = bestAttemptContent {
            
            // add this line of code
            Dengage.didReceiveNotificationExtentionRequest(receivedRequest: request, with: bestAttemptContent)
            contentHandler(bestAttemptContent)
        }
    }

Ignore any build errors at this point, we will resolve these later by importing the D·engage library.

NotificationService.swift screenshot

4. Setup Dengage SDK (it include two steps of the iOS native SDK. 1. Setting Integration Key 2. Initialization with Launch Options)

Integration Key is genereted by CDMP Platform while defining application. It is a hash string which contains information about application. At the beginning of your application cycle you must set Integration Key and right after initialize sdk with launch options. Following sample shows how to do that in your AppDelegate.swift file:

Sample: In the AppDelegate.swift

import UIKit
import Flutter
import dengage_flutter          // ADD THIS IN IMPORTS

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    GeneratedPluginRegistrant.register(with: self)
    /************* FLutter Setup Code Starts here ********************/
    // please Node key here is the integeration Key received while registering your iOS Application on Dengage Dashboard.
    let coordinator = DengageCoordinator.staticInstance;
    coordinator.setupDengage(key: "K8sbLq1mShD52Hu2ZoHyb3tvDE_s_l_h99xFTF60WiNPdHhJtvmOqekutthtzRIPiMTbAa3y_p_l_PZqpon8nanH8YnJ8yYKocDb4GCAp7kOsi5qv7mDR_p_l_qOFLLp9_p_l_lloC6ds97X", launchOptions: launchOptions as NSDictionary?);
     /************* FLutter Setup Code Ends here ********************/
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
    
    override func application( _ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
            let coordinator = DengageCoordinator.staticInstance;
            coordinator.registerForPushToken(deviceToken:deviceToken)
    }
}

5. Register for remote notification with device token

To register for remote notifications with device token, add following method and code inside your AppDelegate.swift file:

import UIKit
import Flutter
import dengage_flutter          // ADD THIS IN IMPORTS

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
    // ... other things here ...
    
    /**************** Here this method override *****************/
    override func application( _ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
            let coordinator = DengageCoordinator.staticInstance;
            coordinator.registerForPushToken(deviceToken:deviceToken)
    }
}

android Specific Extra Steps

Firebase SDK Setup (Follow these steps only if you're using firebase for push, for Huawei follow these steps)

Requirements

  • Google Firebase App Configuration
  • Android Studio
  • Android Device or Emulator

D·engage Android SDK provides an interface which handles push notification messages easily. Optionally, It also gives to send event functionality such as open and subscription to dEngage Platform.

Supports Android API level 4.1.x or higher.

For detailed steps for firebase SDK setup and it's integeration with D·engage, click here

Huawei SDK Setup (Note: use these steps only if you're using HUAWEI Messaging Service for push, if using firebase, follow these steps)

Requirements

  • Huawei Developer Account
  • Java JDK installation package
  • Android SDK package
  • Android Studio 3.X
  • HMS Core (APK) 4.X or later
  • Huawei Device or Huawei Cloud Debugging

Supports Android API level 4.4 or higher. (Note that Huawei AdID service requires min target SDK version 19)

D·engage Huawei SDK provides an interface which handles push notification messages that delivered by Huawei Messaging Service (HMS). It is similar to Firebase but has a bit different configuration process that contains steps mentioned here.

Create DengageManager instance

First, you need to create DengageManager instance in your main or launcher activity.

    // import statement
    import com.example.dengage_flutter.DengageCoordinator;
    
    // ...
    @Override
    protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      // Following line need to be added
      DengageCoordinator.sharedInstance.setupDengage(
                true,
                "FEYl27JxJfay6TxiYCdlkP2FXeuhNfEoI8WkxI_p_l__s_l_5sLbzKmc9c88mSZxRCrLuqMK4y0e8nHajQnBt8poBNDMvNtIytYKZ6byBQZOE8kqkkgDnlye2Lb5AcW3tuIWQjYz",
                "your-huawei-key-here",
                applicationContext
        )    
    }

After these steps, You will be able to send a push notification message to your app.

Change Subscription Api Endpoint

You can change subscription api endpoint by adding following metadata tag in YourProject/android/src/main/AndroidManifest.xml

        // for prod
        <meta-data
            android:name="den_push_api_url"
            android:value="https://push.dengage.com" />

        // for dev
        <!--    android:value="https://pushdev.dengage.com" />-->  

Note: Please see API Endpoints By Datacenter to set your subscription end point.

Changing Event Api Endpoint

similar to subscription endpoints, you can change event api endpoints by setting following metadata tag in YourProject/android/src/main/AndroidManifest.xml

        // for prod
        <meta-data
            android:name="den_event_api_url"
            android:value="https://event.dengage.com" />
        
        // for dev
        <!--      android:value="https://eventdev.dengage.com" />-->

Note: Please see API Endpoints By Datacenter to set your event end point.

Now you can setContactKey like mentioned here

Supported Versions

iOS

D·engage Mobile SDK for IOS supports version IOS 10 and later.

android

D·engage Mobile SDK for Android supports version 4.4 (API Level 19) and later.

Huawei

D·engage Mobile SDK for Huawei supports all new versions.

Usage

Subscription

Subscription is a process which is triggered by sending subscription event to D·engage. It contains necessary informations about application to send push notifications to clients.

Subscriptions are self managed by D·engage SDK and subcription cycle starts with Prompting user permission. SDK will automaticlly send subscription events under following circumstances:

  • Initialization
  • Setting Contact key
  • Setting Token
  • Setting User Permission (if you have manual management of permission)

Asking User Permission for Notification

Note: Android doesn't require to ask for push notifications explicitly. Therefore, you can only ask for push notification's permissions on iOS.

IOS uses shared UNUserNotificationCenter by itself while asking user to send notification. D·engage SDK manager uses UNUserNotificationCenter to ask permission as well. Apple Doc Reference

If in your application, you want to get UserNotification permissions explicitly, you can do by calling one of the following methods:

// At the top import
import 'package:dengage_flutter/dengage_flutter.dart';

// somewhere in your javascript/typescript code
DengageFlutter.promptForPushNotifications()

OR

// At the top import
import 'package:dengage_flutter/dengage_flutter.dart';

// somewhere in your javascript/typescript code
Object result = await DengageFlutter.promptForPushNotificationsWitCallback()

Setting Contact Key

Contact Key represents user id in your system. There are two types of devices. Anonymous Devices and Contact Devices. Contact Devices contains Contact Key.

To track devices by their contacts you need to set contact key on SDK.

Note: It is recommended to call this method, if you have user information. You should call in every app open and on login, logout pages.

// import statement
import 'package:dengage_flutter/dengage_flutter.dart';

// in js/ts code
Object result = await DengageFlutter.setContactKey(userId: String)


// You may need getting current contact key from SDK. In that case you can use getContactKey
Object result = await DengageFlutter.getContactKey()

Manual Management of Tokens

If you need to get current token or if you are managing token subscription process manually, you can use setToken and getToken functions.

// At the top import
import 'package:dengage_flutter/dengage_flutter.dart';

// somewhere in your javascript/typescript code
Object result = await DengageFlutter.getToken()

// setting the token that is taken manually
DengageFlutter.setToken(token)

User Permission Management (optional)

If you manage your own user permission states on your application you may send user permission by using setUserPermission method.

// At the top import
import 'package:dengage_flutter/dengage_flutter.dart';

// somewhere in your javascript/typescript code
DengageFlutter.setUserPermission(true)

// For getting last permission set by user
Object result = await DengageFlutter.getUserPermission(true)

Logging

SDK can provide logs for debuging. It displays queries and payloads which are sent to REST API’s.

To validate your inputs you can enable SDK’s log by a method.

// isVisible is Boolean. By default isVisible set to false.
DengageFlutter.setLogStatus(isVisible)

Handling Notification Action using onNotificationClicked event

SDK provides a listener if you want to get and parse payload manually, whenever a push notification is clicked.

// declare as class level static variable
  static const EventChannel eventChannel = EventChannel("com.dengage.flutter/onNotificationClicked");

  @override
  void initState() {
    // rest of code here ...

    eventChannel.receiveBroadcastStream().listen(_onEvent, onError: _onError);

    super.initState();
  }

  void _onEvent(Object event) {
    print("in on Event object is: ");
    print(event);
  }

  void _onError(Object error) {
    print("in on Error Object is: ");
    print(error);
  }

DeepLinking

SDK supports URL schema deeplink. If target url has a valid link, it will redirect to the related link. Please see related links below about deeplinking.

iOS Specific Links

Apple Url Scheme Links

Apple Universal Link

android Specific Links

Create a deep link for a destination

Create Deep Links to App Content

Rich Notifications

Rich Notifications is a notification type which supports image, gif, video content. D·engage SDK supports varieties of contents and handles notification. Rich Notifications supports following media types:

  • Image
  • Video
  • Gif

For further details about rich notification and its setup on iOS side please follow this link

Note: on Android there is no special setup required for rich notifications.

Carousel Push

Carousel Push is a notification type which has a different UI than Rich Notification. SDK will handle notification payload and displays UI if it’s a carousel push. Carousel Push functionality allows you to show your notification with a slideshow.

iOS

Requirements

  • iOS 10 or higher
  • Notification Service Extension
  • Notification Content Extension
  • Dengage.Framework.Extensions

to setup Carousel Push on iOS you can follow this link

android

Requirements

  • Android SDK 2.0.0+

to setup Carousel Push on android you can follow this link

Action Buttons

Android SDK allows you to put clickable buttons under the notification. Action buttons are supported in Android SDK 2.0.0+. For further setup of Action Buttons, follow this link.

Event Collection

In order to collect android mobile events and use that data to create behavioral segments in D·engage you have to determine the type of events and data that needs to collected. Once you have determined that, you will need to create a “Big Data” table in D·engage. Collected events will be stored in this table. Multiple tables can be defined depending on your specific need.

Any type of event can be collected. The content and the structure of the events are completely flexible and can be changed according to unique business requirements. You will just need to define a table for events.

Once defined, all you have to do is to send the event data to these tables. D·engage SDK has only two functions for sending events: sendDeviceEvent and sendCustomEvent. Most of the time you will just need the sendDeviceEvent function.

1. Login / Logout Action

If the user loggs in or you have user information, this means you have contact_key for that user. You can set contact_key in order to match user with the browser. There are two functions for getting and setting contact_key.

1.a setContactKey

If user logged in set user id. This is important for identifying your users. You can put this function call in every page. It will not send unnecessary events. code example is here

1.b getContactKey

to get the current user information from SDK getContactKey method can be used.

// in imports
import 'package:dengage_flutter/dengage_flutter.dart';

// in the code, where user information required
Object result = await DengageFlutter.getContactKey()

2. Event Collection

If your D·engage account is an ecommerce account, you should use standard ecommerce events in the SDK. If you need some custom events or your account is not standard ecommerce account, you should use custom event functions.

2.1 Events for Ecommerce Accounts

There are standard ecommerce events in D·engage SDK.

Page View Events

  • Home page view
  • Product page view
  • Category page view
  • Promotion page view

Shopping Cart Events

  • Add to cart
  • Remove from cart
  • View Cart
  • Begin Checkout

Order Events

  • Order
  • Cancel order

Wishlist Events

  • Add to wishlist
  • Remove from wishlist

Search Event

For these event there are related tables in your account. Following are the details and sample codes for each of above events.

Page View Events Page view events will be sent to page_view_events table. If you add new columns to this table. You can send these in the event data.

// import at top
import 'package:dengage_flutter/dengage_flutter.dart';
...


// Home page view
DengageFlutter.pageView({
      "page_type":"home",
      "page_title": "home",
      "app_type": "Mobile",
      "page_url": ""
      // ... extra columns in page_view_events table, can be added here
    });

// Category page view
DengageFlutter.pageView({
    "page_type":"category",
    "category_id":"1",
    "page_title": "",
    "app_type": "Mobile",
    "page_url": ""
    // ... extra columns in page_view_events table, can be added here
})

// Product page view
DengageFlutter.pageView({
    "page_type":"product",
    "product_id":"1",
    "page_title": "",
    "app_type": "Mobile",
    "page_url": ""
    // ... extra columns in page_view_events table, can be added here
})

//promotion page view
DengageFlutter.pageView({
    "page_type":"promotion",
    "promotion_id":"1",
    "page_title": "",
    "app_type": "Mobile",
    "page_url": ""
    // ... extra columns in page_view_events table, can be added here
})

//custom page view
DengageFlutter.pageView({
    "page_type":"custom"
    "page_title": "custom",
    "app_type": "Mobile",
    "page_url": ""
    // ... extra columns in page_view_events table, can be added here
})

// For other pages you can send anything as page_type

Shopping Cart Events

These events will be stored in shopping_cart_events and shopping_cart_events_detail. There are 4 shopping cart event functions. addToCart, removeFromCart, viewCart, beginCheckout Every shopping cart event function needs all items in cart as an array. You must send last version of the shopping cart.

For example: If there is one item in cart and item id is 5. And after that, an add to cart action is happened with the item id 10. You have to send 10 as product_id in event parameters and you must send current version of cart items. Meaning [5, 10]

// import statement
import 'package:dengage_flutter/dengage_flutter.dart';

// All items currently exists in shopping cart must be added to an array
const cartItem = {}, // cartItem will be an object with key:value types as String:Any

cartItem["product_id"] = 1
cartItem["product_variant_id"] = 1
cartItem["quantity"] = 1
cartItem["unit_price"] = 10.00
cartItem["discounted_price"] = 9.99
// ... extra columns in shopping_cart_events_detail table, can be added in cartItem

let cartItems = []
cartItems.push(cartItem) 
cartItems.push(cartItem2) 


// Add to cart action
const addParams = {
    "product_id":1,
    "product_variant_id":1,
    "quantity":1,
    "unit_price":10.00,
    "discounted_price":9.99,
    // ... extra columns in shopping_cart_events table, can be added here
    "cartItems":cartItems // all items in cart
}
DengageFlutter.addToCart(addParams)

// ....
// Remove from cart action
const removeParams = {
    "product_id":1,
    "product_variant_id":1,
    "quantity":1,
    "unit_price":10.00,
    "discounted_price":9.99,
    // ... extra columns in shopping_cart_events table, can be added here
    "cartItems":cartItems // all items in cart
}
DengageFlutter.removeFromCart(removeParams)

// view cart action
const viewParams = {
    // ... extra columns in shopping_cart_events table, can be added here
    "cartItems":cartItems
}
DengageFlutter.viewCart(viewParams)

// begin checkout action
var checkoutParams = {
    // ... extra columns in shopping_cart_events table, can be added here
    "cartItems":cartItems
}
DengageFlutter.beginCheckout(checkoutParams)

Order Events

Orders events will be sent to order_events and order_events_detail tables.

// Ordered items or canceled items must be added to an array
// import statement
import 'package:dengage_flutter/dengage_flutter.dart';

const cartItem = {}

cartItem["product_id"] = 1
cartItem["product_variant_id"] = 1
cartItem["quantity"] = 1
cartItem["unit_price"] = 10.00
cartItem["discounted_price"] = 9.99
// ... extra columns in order_events_detail table, can be added in cartItem

const cartItems = []
cartItems.push(cartItem) 
cartItems.push(cartItem2) 
// ... ordered or canceled items must be added


// Place order action
const placeOrderParams = {
    "order_id":1,
    "item_count":1, // total ordered item count
    "total_amount":1, // total price
    "discounted_price":9.99, // use total price if there is no discount
    "payment_method":"card",
    "shipping":5,
    "coupon_code":"",
    // ... extra columns in order_events table, can be added here
    "cartItems":cartItems //ordered items
}
DengageFlutter.placeOrder(placeOrderParams)

// Cancel order action
const cancelParams = {
    "order_id":1, // canceled order id
    "item_count":1, // canceled total item count
    "total_amount":1, // canceled item's total price
    "discounted_price":9.99, // use total price if there is no discount
    // ... extra columns in order_events table, can be added here
    "cartItems":cartItems // // canceled items 
}
DengageFlutter.cancelOrder(cancelParams)

Wishlist Event

These events will be stored in wishlist_events and wishlist_events_detail. There are 2 wishlist event functions. addToWishlist, removeFromWishlist. In every event call, you can send all items in wishlist. It makes it easy to track current items in wishlist.

  // import statement 
  import 'package:dengage_flutter/dengage_flutter.dart';

  // Current items in wishlist
  const wishListItem = {}
  wishListItem["product_id"] = 1

  const wishListItems = []
  wishListItems.push(wishListItem)


  // Add to wishlist action
  const params = [
      "product_id": 1,
      // ... extra columns in wishlist_events table, can be added here
      "items": wishlistItems // current items
  ]
  DengageFlutter.addToWishList(params)

  // Remove from wishlist action
  const removeParams = [
      "product_id": 1,
      // ... extra columns in wishlist_events table, can be added here
      "items": wishlistItems // current items
  ]
  DengageFlutter.removeFromWishList(removeParams)

Search Event

Search events will be stored in search_events table.

  const params = {
      "keywords":"some product name", // text in the searchbox
      "result_count":12,
      "filters":"" //you can send extra filters selected by user here. Formating is not specified
      // ... extra columns in search_events table, can be added here
  }
  DengageFlutter.search(params)

2.1 Custom Events

Send device specific events

You can use sendDeviceEvent function for sending events for the device. Events are sent to a big data table defined in your D·engage account. That table must have relation to the master_device table. If you set contact_key for that device. Collected events will be associated for that user.

// for example if you have a table named "events"
// and events table has "key", "event_date", "event_name", "product_id" columns
// you just have to send the columns except "key" and "event_date", because those columns sent by the SDK
// methodSignature => dengage(‘sendDeviceEvent’, tableName: String, dataObject, callback);
  Map data = new HashMap<String, dynamic>();
  data["name"] = "Kamran Younis";
  await DengageFlutter.sendDeviceEvent("tableName", data);

App Inbox

App Inbox is a screen within a mobile app that stores persistent messages. It’s kind of like an email inbox, but it lives inside the app itself. App Inbox differs from other mobile channels such as push notifications or in-app messages. For both push and in-app messages, they’re gone once you open them.

In other words, D·engage admin panel lets you keep selected messages on the platform and Mobile SDK may retreive and display these messages when needed.

In order to save messages into App Inbox, you need to select “Save to Inbox” option when sending messages in D·engage admin panel by assigning an expire date to it.

Inbox messages are kept in the memory storage of the phone until app is completely closed or for a while and D·engage SDK provides functions for getting and managing these messages.

Requirements

  • Android: D·engage SDK 3.2.3+
  • iOS: D·engage SDK 2.5.21+

Methods

There are 3 methods to manage App Inbox Messages

To get app inbox messages from the server

  Object result = await DengageFlutter.getInboxMessages(offset, limit).catch(err => err)
  // where offset: Int, limit: Int = 20
  // inboxMessages now either have array of Inbox messages or an error.

To delete a specific message from the inbox.

  Object result = await DengageFlutter.deleteInboxMessage(id).catch(err => err)
  // where id: String
  // delMsgResponse now either have {success: true, id: "id-of-msg-deleted"} or an error

to mark a specific message as clicked.

  Object result = await DengageFlutter.setInboxMessageAsClicked(id).catch(err => err)
  // where id: String &
  // msgSetAsClicked now either have {success: true, id: "id-of-msg-deleted"} or an error

In-App Messaging

In-app message is a type of mobile message where the notification is displayed within the app. It is not sent in a specific time but it is show to user when user are using the app. Examples include popups, yes/no prompts, banners, and more. In order to show in-app messages, there is no permission requirement.

Requirements

  • iOS: D·engage SDK 3.2.3+
  • android: D·engage SDK 3.2.3+

Methods

Created messages will be stored in D·engage backend and will be served to mobile SDKs. If you integrated mobile SDK correctly for push messages, for using in-app features you just have to add setNavigtion function to every page navigation. If you want to use screen name filter, you should send screen name to setNavigation function in every page navigation.

Simple In App Messaging

    DengageFlutter.setNavigation()

In App Messaging with Screen Name

    DengageFlutter.setNavigation('cart')

In App Messaging with Screen Name and Page Data

  //
  // (Coming soon)
  // Scheduled: April 2021
  // if you have extra information 
  // you can send them to use screen data filters.
  Object screenData = {productId: "~hs7674", price: 1200}
  DengageFlutter.setNavigation('product', screenData)

Contributing

See the contributing guide to learn how to contribute to the repository and the development workflow.

Use this package as a library

Depend on it

Run this command:

With Flutter:

 $ flutter pub add dengage_flutter

This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get):

dependencies:
  dengage_flutter: ^0.1.0

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

Import it

Now in your Dart code, you can use:

import 'package:dengage_flutter/dengage_flutter.dart'; 

example/lib/main.dart

import 'dart:async';
import 'dart:collection';

import 'package:dengage_flutter/dengage_flutter.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  //  DengageFlutter.setFirebaseIntegrationKey(
  //      'FEYl27JxJfay6TxiYCdlkP2FXeuhNfEoI8WkxI_p_l__s_l_5sLbzKmc9c88mSZxRCrLuqMK4y0e8nHajQnBt8poBNDMvNtIytYKZ6byBQZOE8kqkkgDnlye2Lb5AcW3tuIWQjYz');
  // DengageFlutter.setLogStatus(true);

  runApp(
    MyApp(),
  );
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);

  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  String contactKey = '';
  var contactKeyController = TextEditingController();

static const EventChannel eventChannel = EventChannel("com.dengage.flutter/onNotificationClicked");

  void _onEvent(Object event) {
    print("in on Event object is: ");
    print(event);

  }

  void _onError(Object error) {
    print("in on Error Object is: ");
    print(error);
  }

  @override
  void initState() {
    DengageFlutter.getContactKey().then((value) {
      print("dengageContactKey: $value");
      contactKeyChanged(value);
    });
    // print("setting screen name.");
    // DengageFlutter.setNavigationWithName('MainScreen');

    eventChannel.receiveBroadcastStream().listen(_onEvent, onError: _onError);

    super.initState();
  }

  contactKeyChanged(String value) {
    if (value.isNotEmpty) {
      print("$value is not empty.");
      contactKeyController.value = TextEditingValue(
        text: value,
        selection: TextSelection.fromPosition(
          TextPosition(offset: value.length),
        ),
      );
      setState(() {
        contactKey = value;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.teal,
      appBar: AppBar(
        backgroundColor: Colors.teal[900],
        title: Text('Flutter Sample App'),
      ),
      body: Container(
        padding: EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            Text('Enter Your Contact Key'),
            TextFormField(
              controller: contactKeyController,
              decoration: const InputDecoration(
                icon: const Icon(
                  Icons.input,
                  color: Colors.black54,
                ),
                focusedBorder: UnderlineInputBorder(
                  borderSide: BorderSide(
                    color: Colors.black54,
                  ),
                ),
              ),
              cursorColor: Colors.black54,
              keyboardType: TextInputType.text,
              maxLines: 1,
              onChanged: contactKeyChanged,
            ),
            Container(
              padding: EdgeInsets.only(top: 10.0),
              child: ElevatedButton(
                onPressed: () {
                  String msg = contactKey;
                  if (contactKey.isEmpty) {
                    msg = 'Please enter proper value.';
                  } else {
                    DengageFlutter.setContactKey(contactKey);
                  }
                  ScaffoldMessenger.of(context).showSnackBar(
                    SnackBar(
                      content: Text(msg),
                      action: SnackBarAction(
                        label: 'Ok',
                        onPressed: () {},
                      ),
                    ),
                  );
                },
                child: Text('Set Contact Key'),
              ),
            ),
            Container(
              padding: EdgeInsets.only(top: 10.0),
              child: ElevatedButton(
                onPressed: () async {
                  String msg = await DengageFlutter.getContactKey();
                  ScaffoldMessenger.of(context).showSnackBar(
                    SnackBar(
                      content: Text(msg),
                      action: SnackBarAction(
                        label: 'Ok',
                        onPressed: () {},
                      ),
                    ),
                  );
                },
                child: Text('Get & Show Contact Key'),
              ),
            ),
            Container(
              padding: EdgeInsets.only(top: 10.0),
              child: ElevatedButton(
                onPressed: () async {
                  String token = await DengageFlutter.getToken();
                  ScaffoldMessenger.of(context).showSnackBar(
                    SnackBar(
                      content: Text('token: $token'),
                      action: SnackBarAction(
                        label: 'copy token',
                        onPressed: () {
                          Clipboard.setData(new ClipboardData(text: token));
                          },
                      ),
                    ),
                  );
                },
                child: Text('Get & Show Token'),
              ),
            ),
            Container(
              padding: EdgeInsets.only(top: 10.0),
              child: ElevatedButton(
                onPressed: () async {
                  Map data = new HashMap<String, dynamic>();
                  data["name"] = "Nawaz";
                  await DengageFlutter.sendDeviceEvent("tableName", data);
                },
                child: Text('Send Device Event'),
              ),
            ),
            Container(
              padding: EdgeInsets.only(top: 10.0),
              child: ElevatedButton(
                onPressed: () async {
                  String subscription = await DengageFlutter.getSubscription();
                  ScaffoldMessenger.of(context).showSnackBar(
                    SnackBar(
                      content: Text(subscription),
                      action: SnackBarAction(
                        label: 'copy',
                        onPressed: () {
                          Clipboard.setData(
                              new ClipboardData(text: subscription));
                        },
                      ),
                    ),
                  );
                },
                child: Text('Get & Show subscription'),
              ),
            ),
            Container(
              padding: EdgeInsets.only(top: 10.0),
              child: ElevatedButton(
                onPressed: () async {
                    DengageFlutter.setNavigationWithName('MainScreen');
                },
                child: Text('Set Screen Name as "MainScreen"'),
              ),
            ),
                        Container(
              padding: EdgeInsets.only(top: 10.0),
              child: ElevatedButton(
                onPressed: () async {
                    Navigator.push(context, MaterialPageRoute(builder: (context) => SecondRoute()));
                },
                child: Text('Navigate to "SecondScreen"'),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class SecondRoute extends StatelessWidget {
  SecondRoute () {
    print("setting screen name as SecondScreen");
    setScreenName();
  }

  setScreenName () async {
    DengageFlutter.pageView({
      "page_type":"SecondScreen"
      // ... extra columns in page_view_events table, can be added here
    });
    DengageFlutter.setNavigationWithName("SecondScreen");
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.teal,
      appBar: AppBar(
        backgroundColor: Colors.teal[900],
        title: Text('Flutter Sample App, "Second Screen"'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Navigator.pop(context);
          },
          child: Text('Go back!'),
        ),
      ),
    );
  }
} 

Download Details:

Author: dengage-tech/

Source Code: https://github.com/dengage-tech/dengage-flutter-sdk

#dengage #flutter 

What is GEEK

Buddha Community

Flutter SDK for Dengage SDKs

Google's Flutter 1.20 stable announced with new features - Navoki

Flutter Google cross-platform UI framework has released a new version 1.20 stable.

Flutter is Google’s UI framework to make apps for Android, iOS, Web, Windows, Mac, Linux, and Fuchsia OS. Since the last 2 years, the flutter Framework has already achieved popularity among mobile developers to develop Android and iOS apps. In the last few releases, Flutter also added the support of making web applications and desktop applications.

Last month they introduced the support of the Linux desktop app that can be distributed through Canonical Snap Store(Snapcraft), this enables the developers to publish there Linux desktop app for their users and publish on Snap Store.  If you want to learn how to Publish Flutter Desktop app in Snap Store that here is the tutorial.

Flutter 1.20 Framework is built on Google’s made Dart programming language that is a cross-platform language providing native performance, new UI widgets, and other more features for the developer usage.

Here are the few key points of this release:

Performance improvements for Flutter and Dart

In this release, they have got multiple performance improvements in the Dart language itself. A new improvement is to reduce the app size in the release versions of the app. Another performance improvement is to reduce junk in the display of app animation by using the warm-up phase.

sksl_warm-up

If your app is junk information during the first run then the Skia Shading Language shader provides for pre-compilation as part of your app’s build. This can speed it up by more than 2x.

Added a better support of mouse cursors for web and desktop flutter app,. Now many widgets will show cursor on top of them or you can specify the type of supported cursor you want.

Autofill for mobile text fields

Autofill was already supported in native applications now its been added to the Flutter SDK. Now prefilled information stored by your OS can be used for autofill in the application. This feature will be available soon on the flutter web.

flutter_autofill

A new widget for interaction

InteractiveViewer is a new widget design for common interactions in your app like pan, zoom drag and drop for resizing the widget. Informations on this you can check more on this API documentation where you can try this widget on the DartPad. In this release, drag-drop has more features added like you can know precisely where the drop happened and get the position.

Updated Material Slider, RangeSlider, TimePicker, and DatePicker

In this new release, there are many pre-existing widgets that were updated to match the latest material guidelines, these updates include better interaction with Slider and RangeSliderDatePicker with support for date range and time picker with the new style.

flutter_DatePicker

New pubspec.yaml format

Other than these widget updates there is some update within the project also like in pubspec.yaml file format. If you are a flutter plugin publisher then your old pubspec.yaml  is no longer supported to publish a plugin as the older format does not specify for which platform plugin you are making. All existing plugin will continue to work with flutter apps but you should make a plugin update as soon as possible.

Preview of embedded Dart DevTools in Visual Studio Code

Visual Studio code flutter extension got an update in this release. You get a preview of new features where you can analyze that Dev tools in your coding workspace. Enable this feature in your vs code by _dart.previewEmbeddedDevTools_setting. Dart DevTools menu you can choose your favorite page embed on your code workspace.

Network tracking

The updated the Dev tools comes with the network page that enables network profiling. You can track the timings and other information like status and content type of your** network calls** within your app. You can also monitor gRPC traffic.

Generate type-safe platform channels for platform interop

Pigeon is a command-line tool that will generate types of safe platform channels without adding additional dependencies. With this instead of manually matching method strings on platform channel and serializing arguments, you can invoke native class and pass nonprimitive data objects by directly calling the Dartmethod.

There is still a long list of updates in the new version of Flutter 1.2 that we cannot cover in this blog. You can get more details you can visit the official site to know more. Also, you can subscribe to the Navoki newsletter to get updates on these features and upcoming new updates and lessons. In upcoming new versions, we might see more new features and improvements.

You can get more free Flutter tutorials you can follow these courses:

#dart #developers #flutter #app developed #dart devtools in visual studio code #firebase local emulator suite in flutter #flutter autofill #flutter date picker #flutter desktop linux app build and publish on snapcraft store #flutter pigeon #flutter range slider #flutter slider #flutter time picker #flutter tutorial #flutter widget #google flutter #linux #navoki #pubspec format #setup flutter desktop on windows

Terry  Tremblay

Terry Tremblay

1598396940

What is Flutter and why you should learn it?

Flutter is an open-source UI toolkit for mobile developers, so they can use it to build native-looking** Android and iOS** applications from the same code base for both platforms. Flutter is also working to make Flutter apps for Web, PWA (progressive Web-App) and Desktop platform (Windows,macOS,Linux).

flutter-mobile-desktop-web-embedded_min

Flutter was officially released in December 2018. Since then, it has gone a much stronger flutter community.

There has been much increase in flutter developers, flutter packages, youtube tutorials, blogs, flutter examples apps, official and private events, and more. Flutter is now on top software repos based and trending on GitHub.

Flutter meaning?

What is Flutter? this question comes to many new developer’s mind.

humming_bird_dart_flutter

Flutter means flying wings quickly, and lightly but obviously, this doesn’t apply in our SDK.

So Flutter was one of the companies that were acquired by **Google **for around $40 million. That company was based on providing gesture detection and recognition from a standard webcam. But later when the Flutter was going to release in alpha version for developer it’s name was Sky, but since Google already owned Flutter name, so they rename it to Flutter.

Where Flutter is used?

Flutter is used in many startup companies nowadays, and even some MNCs are also adopting Flutter as a mobile development framework. Many top famous companies are using their apps in Flutter. Some of them here are

Dream11

Dream11

NuBank

NuBank

Reflectly app

Reflectly app

Abbey Road Studios

Abbey Road Studios

and many more other apps. Mobile development companies also adopted Flutter as a service for their clients. Even I was one of them who developed flutter apps as a freelancer and later as an IT company for mobile apps.

Flutter as a service

#dart #flutter #uncategorized #flutter framework #flutter jobs #flutter language #flutter meaning #flutter meaning in hindi #google flutter #how does flutter work #what is flutter

Adobe XD plugin for Flutter with CodePen Tutorial

Recently Adobe XD releases a new version of the plugin that you can use to export designs directly into flutter widgets or screens. Yes, you read it right, now you can make and export your favorite design in Adobe XD and export all the design in the widget form or as a full-screen design, this can save you a lot of time required in designing.

What we will do?
I will make a simple design of a dialogue box with a card design with text over it as shown below. After you complete this exercise you can experiment with the UI. You can make your own components or import UI kits available with the Adobe XD.

#developers #flutter #adobe xd design export to flutter #adobe xd flutter code #adobe xd flutter code generator - plugin #adobe xd flutter plugin #adobe xd flutter plugin tutorial #adobe xd plugins #adobe xd to flutter #adobe xd tutorial #codepen for flutter.

Download Android SDK Manager and SDK Tools

In this tutorial, we’ll read about the Android SDK Manager. We will see what is SDK manager in Android and why and how it is important for Android. So, SDK stands for Software Development Kit, which is a collection of software tools required. SDK basically helps Android to download tools and recent versions of Android. Every time a new Android version is released, along with it is released an SDK corresponding to it. This SDK must be installed by the developers for the devices.
What is SDK Manager?
A Software development kit is a set of tools required for the development of applications for Android. It also ensures that the progress of App development goes as flat as pancakes. We need SDK irrespective of the language we are using. Android SDK comes wrapped up with the Android Studio these days. An Android SDK separates the tools, platforms and other components into packages. These can be downloaded from the SDK Manager.

#android tutorials #android sdk manager #android sdk manager download #android sdk tools #android studio sdk manager #sdk download #sdk manager #sdk tools

Brain  Crist

Brain Crist

1602147600

Flutter App Development Trends 2020

As the new decade dawns upon us, a slew of technologies has been making a lot of noise to grab the developers’ attention. While native app development is going strong, the trade winds are now blowing towards going cross-platform.

Adobe PhoneGap, React Native, Xamarin and Ionic are all leaving no stone unturned to be the undefeated champion of cross-platform development. Still, Google’s Flutter is all set to take them all on at once.

There are a tonne of resources available online to learn about Flutter, and you can start with this step by step flutter guide.

With reduced code development time, increased time-to-market speed, near-native performance, and a bevy of advantages under its hood, Flutter is set to dominate the market this decade.

Before we take a look at trends making the Flutter race ahead in 2020, let us do a quick recap of what Flutter is, for those who have been living under a rock.

#flutter #flutter-for-mobile-app #flutter-app-development #mobile-app-development #flutter-trends #software-development #advantages-of-flutter-mobile #pros-and-cons-of-flutter