Airo Global Software

Think Beyond Future !

enter image description here

ASP.NET Core Web APIs often need to serialize JSON data to JavaScript clients. On the server, your C# classes basically use Pascal Casing to name properties whereas JavaScript code uses Camel Casing for property names. Therefore it would be worthwhile to take a quick look at how ASP.NET Core serializes data in JSON form of Web API and MVC controllers.

There are three basic places from where C# objects are serialized in JSON format to the client:

  • Web API controllers
  • MVC controllers
  • Custom C# code using JsonSerializer

How camel casing and web API?

Let's first see the behavior of ASP.NET Core Web APIs when it comes to JSON serialization.

Analyze the resulting Web API controller:

[ApiController]
[Route("[controller]")]
public class EmployeeController : ControllerBase
{
[HttpGet]
public List<Employee> Get()
{
List<Employee> empList =
new List<Employee>();
empList.Add(new Employee()
{ EmployeeID=1,FirstName="Nancy",
LastName="Davolio" });
empList.Add(new Employee()
{ EmployeeID = 2, FirstName = "Andrew",
LastName = "Fuller" });
 return empList;
}
}

This code simply returns a List of Employee objects to the caller. The Employee class practiced in this system looks similar this:

public class Employee
{
public int EmpID { get; set; }
public string First { get; set; }
public string Last{ get; set; }
}

Begin the Startup class and modify the ConfigureServices() step as shown below:

public void ConfigureServices
(IServiceCollection services)
{
services.AddControllers()
 .AddJsonOptions(options =>
{
options.JsonSerializerOptions
.PropertyNamingPolicy = null;
});
}

As you can understand, the code does the AddJsonOptions() way to configure this behavior. The PropertyNamingPolicy section of JsonSerializerOptions is set to nothing.

If you need to explicitly set the casing to camel casing then you can print:

options.JsonSerializerOptions.
ropertyNamingPolicy = JsonNamingPolicy.CamelCase;

How camel casing and MVC controllers?

In ASP.NET Core MVC you can use Json() method to serialize data JSON format. Consider the following work that explains how this can be done.

public class HomeController: Controller
{
public IActionResult Index()
 {
List<Employee> empList =
new List<Employee>();
empList.Add(new Employee() 
{ EmployeeID = 1, FirstName = "Nancy",
LastName = "Davolio" });
empList.Add(new Employee()
{ EmployeeID = 2, FirstName = "Andrew",
LastName = "Fuller" });
return Json(empList);
 }
}

The Index() action made a List of Employee objects. The easiest is then serialized to the client handling Json() method.

In order to show MVC to pause using camel casing, you can type this code in the ConfigureServices().

services.AddControllersWithViews()
 .AddJsonOptions(options =>
{
options.JsonSerializerOptions
.PropertyNamingPolicy = null;
});

You run the AddJsonOptions() step on AddControllersWithViews().

You can also replace this behavior for single Json() calls as shown below:

var options = new JsonSerializerOptions()
{
 PropertyNamingPolicy = 
JsonNamingPolicy.CamelCase
};
return Json(empList, options);

How is custom code using JSON serializer?

At times you are required to serialize data yourself via custom code. Basically, you will use JsonSerializer to perform this task. Examine the following code:

public IActionResult Index()
{
List<Employee> empList =
new List<Employee>();
empList.Add(new Employee() 
{ EmployeeID = 1, FirstName = "Nancy", 
LastName = "Davolio" });
empList.Add(new Employee() 
{ EmployeeID = 2, FirstName = "Andrew", LastName = "Fuller" });
string json = JsonSerializer.Serialize(empList);
return Ok(json);
}

If you need JsonSerializer class to do camel casing you can do the serving:

var options = new JsonSerializerOptions()
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};
string json = JsonSerializer.Serialize(empList, options);
return Ok(json);

As you can see, the code makes a JsonSerializerOptions object and sets PropertyNamingPolicy property to JsonNamingPolicy.CamelCase. Next, the Serialize() system is called by giving empList and JsonSerializerOptions objects.

If you have any questions about the above topic or have to get services and consultations and get the best JSON services. Feel free to contact us. AIRO GLOBAL SOFTWARE will be your digital solution. E-mail id: [email protected]

enter image description here Author - Johnson Augustine
Chief Technical Director and Programmer
Founder: Airo Global Software Inc
LinkedIn Profile: www.linkedin.com/in/johnsontaugustine/

enter image description here

One way or another we develop our apps to make cash out of it. Sometimes we sell ads and make users upgrade for a great experience and we have premium content only for paid users.

We should know about each and every piece of information before handling the payment-related stuff. Be prepared before you start to know about Subscriptions In-App Purchase in Flutter.

Before we get into the programming part let’s learn more about in-app purchases and how it is different for both Android and IOS platforms.

What are the types of products in Android and IOS?

There are types of products in both Android and IOS: First Know about the Products in Android:

  • Consumable product: Products like in-game currency are examples of this type of product. Once the user starts to use them, the user can purchase it again.
  • Non-Consumable product: These can be bought only once and it gives a permanent benefit.
  • Subscriptions: These give benefits to the user for a limited period. You can compare Netflix, Spotify subscriptions to these products.

Know about Products in iOS

  • Consumable product.

  • Non-Consumable product.

  • Auto-Renewable Subscriptions: same as android subscriptions.

  • Non-Renewing Subscriptions: It is almost the same as Auto-Renewable Subscriptions.

What are the steps to add a subscription in the Flutter app?

  • First step is we need to Create a Product

    How to create a product for Android:

  • First go to Google Play Console

  • Second step is to click the app for which you want to build a subscription.

  • Third step is to go Inside the menu under Monetize > Products click Subscriptions.

  • Fourth step is to fill the form with the needed details. Here product id is the most essential field. Product id is used to uniquely find each product.

How to create a product for iOS:

  • First you have to Go to App Store Connect.
  • Second step is to click the app for which you want to make a subscription.
  • Third step is to click In the side menu under the in-app purchase section and now click the manage option.
  • Fourth step is to press the plus sign to include new products and select the type of subscription you want.
  • Fifth step is to type the product name and product id. Here product id is the same as android.
  • Sixth step is to select a subscription group and make a new group.
  • Seventh step is to add a subscription group or make a new group.
  • The last step is to Fill every mandatory information. If any given information is missing for the product then the status of the product will be Missing Metadata. Fill every single information until the status changes to Ready to Submit.
  • Second step is to set up testing accounts.

How to setup testing account for Android:

  • Include the tester’s email address in the applications license testers.
  • Include the same used email address in the app’s tester list.

How to setup testing account for IOS:

  • First step is to go to the app store connect.
  • Second step is to go to User and Access.
  • Third step is to find the Tester option under Sandbox. Press on that.
  • Fourth step is to press on the plus sign to include an apple pay sandbox tester.

Need to understand how the purchase of subscription works:

  • The application notifies the billing server that the present user wants to buy a product with id.
  • The billing Server needs the purchase and gives back the response.
  • The response gets at the application through PurchaseUpdateStream.
  • Your application always checks the status of the purchase and takes the action accordingly.
  • If the purchase was correct the application will notify the application’s back end that this user has perfectly purchased a product and this is the shopping token I got from the billing server.
  • The application’s back end will check the purchase with the billing server before giving any advantages to the user. After perfect validation, your app’s back end will mark the present user as a premium user and notify the application.
  • Now the app has to finish the transaction with the billing server. Completion of the transaction is a way of ordering the billing server that you have perfectly delivered the product to the user.
  • Transaction that finished is different for Android and iOS. In Android, you just have to finish the transaction which is successful. In iOS, you have to finish every transaction irrespective of the status of the transaction.
  • Transaction completion is very important because if you don’t finish the transaction in Android, Google will give back the amount of purchase considering that the purchase was failed.
  • In case of application crashes or network problems happening during the transaction when the user opens the application again your app will be notified with all the unfinished transactions through the PurchaseUpdateStream. So, you can continue the plan of purchase of the product.
  • Based on the response received from the app’s back end you will show a special display to the user.

Next step is to integrate in-App purchases with flutter.

To manage our code we will develop one new folder:

class
PaymentService {
/// We want singleton object of ``PaymentService`` so 
create private constructor
 ///
/// Use PaymentService as ``PaymentService.instance``
PaymentService._internal();
static final PaymentService instance = 
PaymentService._internal();
}

Next is to create some variables:

class 
PaymentService
{
/// We want singleton object of ``PaymentService`` so create
private constructor
///
/// Use PaymentService as ``PaymentService.instance``
PaymentService._internal();
static final PaymentService instance =
PaymentService._internal();
/// To listen the status of connection between app and the billing server
StreamSubscription<ConnectionResult>
_connectionSubscription;
/// To listen the status of the purchase made inside or outside of the app (App Store / Play Store)
///
/// If status is not error then app will be notied by this stream
StreamSubscription<PurchasedItem>
_purchaseUpdatedSubscription;
/// To listen the errors of the purchase
StreamSubscription<PurchaseResult>
_purchaseErrorSubscription;
/// List of product ids you want to fetch
final List<String> _productIds = [
'monthly_subscription'
];

/// All available products will be store in this list List _products;

/// All past purchases will be store in this list
List<PurchasedItem> _pastPurchases;
/// view of the app will subscribe to this to get notified
/// when premium status of the user changes
ObserverList<Function> _proStatusChangedListeners =
new ObserverList<Function>();
/// view of the app will subscribe to this to get errors of the purchase
 ObserverList<Function(String)> _errorListeners =
 new ObserverList<Function(String)>();
/// logged in user's premium status
bool _isProUser = false;
bool get isProUser => _isProUser;
}

Want to get the UI latest updates use the below code:

 addToProStatusChangedListeners(Function callback) {
 _proStatusChangedListeners.add(callback);
}
/// view can cancel to _proStatusChangedListeners using this method

removeFromProStatusChangedListeners(Function callback) {

_proStatusChangedListeners.remove(callback);
 }
/// view can subscribe to _errorListeners using this method
addToErrorListeners(Function callback) {
_errorListeners.add(callback);
}
 /// view can cancel to _errorListeners using this method
removeFromErrorListeners(Function callback) {
_errorListeners.remove(callback);
 }

Following code to notify the user:

void _callProStatusChangedListeners() {
_proStatusChangedListeners.forEach((Function callback) {
 callback();
 });
}

 /// Call this method to notify all the subsctibers of _errorListeners
void _callErrorListeners(String error) {
 _errorListeners.forEach((Function callback) {
callback(error);
});
}

Call the interconnection method at the start your app using below code:

 /// with billing server and get all the necessary data
 void initConnection() async {
await FlutterInappPurchase.instance.initConnection;
 _connectionSubscription =
FlutterInappPurchase.connectionUpdated.listen((connected) {});
 _purchaseUpdatedSubscription =
FlutterInappPurchase.purchaseUpdated.listen(_handlePurchaseUpdate);
_purchaseErrorSubscription =
FlutterInappPurchase.purchaseError.listen(_handlePurchaseError);
_getItems();
 _getPastPurchases();
}
 /// call when user close the app
void dispose() {
_connectionSubscription.cancel();
 _purchaseErrorSubscription.cancel();
 _purchaseUpdatedSubscription.cancel();
FlutterInappPurchase.instance.endConnection;
}

Handle purchase errors using the below code:

void _handlePurchaseError(PurchaseResult
purchaseError) {
_callErrorListeners(purchaseError.
message);
}

For handle purchase updates:

void _handlePurchaseUpdate(PurchasedItem productItem) async
{
if (Platform.isAndroid) {
await _handlePurchaseUpdateAndroid(productItem);
 } else {
await _handlePurchaseUpdateIOS(productItem);
}
}

For finish the transaction:

Future<void> 
_handlePurchaseUpdateI
OS(PurchasedItem
purchasedItem) async {
switch (purchasedItem.transactionStateIOS) {
case TransactionState.deferred:
// Edit: This was a bug that was pointed out here : 
https://github.com/dooboolab/flutter_inapp_purchase/issues/234
//
FlutterInappPurchase.instance.finishTransaction(purchasedItem);
break;
case TransactionState.failed:
 _callErrorListeners("Transaction Failed");
FlutterInappPurchase.instance.finishTransaction(purchasedItem);
 break;
case TransactionState.purchased:
await
_verifyAndFinishTransaction(purchasedItem);
break;
case TransactionState.purchasing:
break;
 case TransactionState.restored:
FlutterInappPurchase.instance.finishTransaction(purchasedItem);
break;
default:
}
 }
/// three purchase state 
https://developer.android.com/reference/com/android/billingclient/api/Purchase.PurchaseState
/// 0 : UNSPECIFIED_STATE
/// 1 : PURCHASED
 /// 2 : PENDING
Future<void> 
_handlePurchaseUpdateAndroid(PurchasedItem purchasedItem) async {
switch (purchasedItem.purchaseStateAndroid) {
 case 1:
if (!purchasedItem.isAcknowledgedAndroid) {
 await 
_verifyAndFinishTransaction(purchasedItem);

}
  break;
default:
_callErrorListeners("Something went wrong");
 }
}

For verify purchase is success:

 /// Call API of your back end to verify the receipt
 /// back end has to call billing server's API to verify the purchase token
 _verifyAndFinishTransaction(PurchasedItem purchasedItem) async {
bool isValid = false;
try {
// Call API
isValid = await _verifyPurchase(purchasedItem);
} on NoInternetException {
_callErrorListeners("No Internet");
 return;
} on Exception {
 _callErrorListeners("Something went wrong");
return;
}
 if (isValid) {
 FlutterInappPurchase.instance.finishTransaction(purchasedItem);
 _isProUser = true;
// save in sharedPreference here
_callProStatusChangedListeners();
} else {
_callErrorListeners("Verification failed");
}
}

For get all the available products:

Future<List<IAPItem>> get
products async {
 if (_products == null) {
await _getItems();
}
}
return _products;
}
Future<void> _getItems() async {
List<IAPItem> items =
await 
FlutterInappPurchase.instance.getSubscriptions
(_productIds);
 _products = List();
 for (var item in items) {
this._products.add(item);
}
}

To buy the product:

Future<Null> 
buyProduct(IAPItem item)
async {
try {
await 
FlutterInappPurchase.instance.requestSubscription(item.productId);
 } catch (error) {
 }
}

If you have any doubts about the above topic or have to get services and consultations and get the best Flutter application services. Feel free to contact us. AIRO GLOBAL SOFTWARE will be your strong digital partner. E-mail id: [email protected]

enter image description here Author - Johnson Augustine
Chief Technical Director and Programmer
Founder: Airo Global Software Inc
LinkedIn Profile: www.linkedin.com/in/johnsontaugustine/

How To Use MQTT in PHP?

- Posted in Web Development by

enter image description here

PHP is a globally-used open source to do multiple functions in scripting language, which can be embedded in HTML and is very suitable for Web development. This blog mainly introduces how to make use of the php-mqtt/client client library in PHP projects to make the functions of connection, subscription, unsubscribing, message receiving and sending between Mqtt client and server.

What is MQTT?

Message Queuing Telemetry Transport is a communicative message protocol for restricted networks and IoT machines with extremely high latency. Because Message Queuing Telemetry Transport is concentrated in low bandwidth, high latency environments, it is an ideal protocol for machine-to-machine communication. MQTT is used in IoT and IIoT up to the connection of the cloud ecosystem.

What is PHP?

PHP is a server-side scripting programming language. that is used to create Static websites, Dynamic websites, and Web applications. PHP stands for Hypertext Preprocessor, which earlier stood for Personal Home Pages.

How do we do MQTT clients library selection?

This blog chooses the library php-mqtt/client, which has the highest installs on composer. MQTT communicative messages belong to network communication cases outside the HTTP system. Due to the restriction of PHP characteristics, using the extensions for network controls such as Swoole/Workerman in the PHP device can bring a better experience. The relevant MQTT client libraries are as follows:

  • workerman/mqtt
  • simps/mqtt

How do we do project initialization?

This project uses 7.4.21 for development. Readers can confirm their PHP with the below command.

php --version
PHP 7.4.21 (cli) (built: Jul 12 2021 11:52:30) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
with Zend OPcache v7.4.21, Copyright (c), by Zend Technologies

How to use composer to install php-mqtt/client?

Composer is a dependency management option for PHP, which can control all the dependencies your PHP project requirements.

composer require php-mqtt/client

How is PHP-MQTT usage?

The server access information is as given below:

  • roker: broker.emqx.io
  • TCP Port: 1883
  • SSL/TLS Port: 8883

Import composer autoload file and php-mqtt/client

require('vendor/autoload.php');
use \PhpMqtt\Client\MqttClient;

Set MQTT Broker connection parameters

Set the MQTT Broker communication address, port, and topic. At the same time, we call the PHP rand function to create the MQTT client id.

$server   = 'broker.emqx.io';
$port     = 1883;
$clientId = rand(5, 15);
$username = 'emqx_user';
$password = null;
$clean_session = false;

Write about MQTT connection function?

Use the above units to communicate, and set the communication units through ConnectionSettings, such as:

$connectionSettings  = new ConnectionSettings();
$connectionSettings
->setUsername($username)
->setPassword(null)
 ->setKeepAliveInterval(60)
 ->setLastWillTopic('emqx/test/last-will')
 ->setLastWillMessage('client disconnect')
->setLastWillQualityOfService(1);

How to subscribe?

Program to subscribe to the heading of emqx/test, and configure a callback program for the subscription to process the received message. Here we print out the topic and communication obtained from the subscription:

$mqtt->subscribe('emqx/test', function ($topic, $message) {
printf("Received message on topic [%s]: %s\n", $topic, $message);
}, 0);

How to Publish?

Construct a payload and call the publish function to upload messages to the emqx/test topic. After uploading, the client needs to enter the polling status to process the incoming communications and the retransmission queue:

for ($i = 0; $i< 10; $i++) {
$payload = array(
'protocol' => 'tcp',
'date' => date('Y-m-d H:i:s'),
'url' => 'https://github.com/emqx/MQTT-Client-Examples'
 );
 $mqtt->publish(
 // topic
'emqx/test',
// payload
json_encode($payload),
// qos
0,
 // retain
true
 );
printf("msg $i send\n");
 sleep(1);
}
// The client loop to process incoming messages and retransmission queues
$mqtt->loop(true);

Server connection, message uploading and receiving code.

<?PHP
require('vendor/autoload.php');
use \PhpMqtt\Client\MqttClient;
use \PhpMqtt\Client\ConnectionSettings;
$server   = 'broker.emqx.io';
$port     = 1883;
$clientId = rand(5, 15);
$username = 'emqx_user';
$password = null;
$clean_session = false;
$connectionSettings  = new ConnectionSettings();
$connectionSettings
 ->setUsername($username)
->setPassword(null)
->setKeepAliveInterval(60)
->setLastWillTopic('emqx/test/last-will')
->setLastWillMessage('client disconnect')
->setLastWillQualityOfService(1);
$mqtt = new MqttClient($server, $port, $clientId);
$mqtt->connect($connectionSettings, $clean_session);
printf("client connected\n");
$mqtt->subscribe('emqx/test', function ($topic, $message) {
 printf("Received message on topic [%s]: %s\n", $topic, $message);
}, 0);
for ($i = 0; $i< 10; $i++) {
$payload = array(
'protocol' => 'tcp',
'date' => date('Y-m-d H:i:s'),
'url' => 'https://github.com/emqx/MQTT-Client-Examples'
 );
$mqtt->publish(
 // topic
  'emqx/test',
// payload
 json_encode($payload),
// qos
 0,
 // retain
true
  );
 printf("msg $i send\n");
sleep(1);
}
$mqtt->loop(true);

How to Test?

After executing the MQTT message uploading code, we will view that the client has perfectly connected, and the messages have been upload one by one and received successfully:

php pubsub_tcp.php

If you have any doubts about the above topic or have to get services and consultations and get the PHP and MQTT services. Feel free to contact us. AIRO GLOBAL SOFTWARE will be your strong digital partner. E-mail id: [email protected]

enter image description here Author - Johnson Augustine
Chief Technical Director and Programmer
Founder: Airo Global Software Inc
LinkedIn Profile: www.linkedin.com/in/johnsontaugustine/

enter image description here

CodeIgniter has been created to make testing both the framework and the app as simple as possible. Support for PHPUnit is created in, and the framework provides a number of convenient helper methods to make testing every aspect of your application as painless as possible.

How to install PHPUnit?

CodeIgniter uses PHPUnit as the backbone for all of the testing. There are two ways to enable PHPUnit to use within your system.

Install Composer

The recommended method is to enable it in your project using composer. While it’s possible to install it in the whole world we do not recommend it, since it can cause many issues with other projects on your system as time goes on. Make sure that you installed it. From the project root type the following from the command line:

> composer require --dev phpunit/phpunit

Once that is done, you can execute all of the tests for this project by typing:

> ./vendor/bin/phpunit

Install Phar

The other option is to install the .phar file from the PHP site. This is a foundation file that should be placed within your project.

How to test your application?

The framework has a phpunit.xml.dist file . This enables unit testing of the framework . If you enable your own phpunit.xml, it will override this.

Your phpunit.xml should get out of the system folder, as well as any vendor or ThirdParty directories, if you are working unit testing your application.

In order to take advantage of the more options provided, your tests must extend CIUnitTestCase. All tests are expected to be situated in the tests/app directory by default.

To test the library, you would built a new file at tests/app/Libraries/FooTest.php:

<?PHP
namespace App\Libraries;
use CodeIgniter\Test\CIUnitTestCase;
class FooTest extends CIUnitTestCase
{
public function testFooNotBar()
{
// ...
}
}

To test one of the program, you might enter this code in tests/app/Models/OneOfMyModelsTest.php:

<?php
namespace App\Models;
use CodeIgniter\Test\CIUnitTestCase;
class OneOfMyModelsTest extends CIUnitTestCase
{
 public function testFooNotBar()
{
 // ...
}
}

You can make any directory structure that fits your testing style. When namespacing the classes, remember that the app directory is the main root of the App namespace, so any classes you use must have the correct namespace relative to App.

What is staging?

Most tests need some preparation in order to work correctly. PHPUnit’s TestCase have four methods to help with staging and clean up:

public static function setUpBeforeClass(): void
public static function tearDownAfterClass(): void
public function setUp(): void
public function tearDown(): void

The static methods execute before and after the test case, whereas the local methods work between each test. If you run any of these special functions make sure you run their parent as well so extended cases do not interfere with staging:

public function setUp(): void
{
 parent::setUp();
helper('text');
}

After to these methods, CIUnitTestCase also comes with a property for parameter-free methods you want to execute during set up and tear down:

protected $setUpMethods = [
'mockEmail',
'mockSession',
];
protected $tearDownMethods = [];

You can see by automatically these manage the mocking of intrusive services, but your class may overlap that or provide their own:

class OneOfMyModelsTest extends CIUnitTestCase
{
protected $tearDownMethods = [
 'purgeRows',
];
 protected function purgeRows()
{
 $this->model->purgeDeleted()
 }

What are Traits?

The basic way to encourage your tests is by using traits to consolidate staging across various test cases. CIUnitTestCase will identify any class traits and look for staging methods to execute names for the trait itself.

trait AuthTrait
{
protected setUpAuthTrait()
{
$user = $this->createFakeUser();
$this->logInUser($user);
 }
...
class AuthenticationFeatureTest
{
use AuthTrait;
...

What about Additional Assertions?

CIUnitTestCase provides unit testing that you might find very useful.

assertLogged:

Ensure that something you expected to be signed actually was:

$config = new LoggerConfig();

$logger = new Logger($config);
... do something that you expect a log entry from
$logger->log('error', "That's no moon");
$this->assertLogged('error', "That's no moon");

assertEventTriggered: Make sure that an event you expected to be triggered actually was:

Events::on('foo', function ($arg) use(&$result) {
$result = $arg;
});
Events::trigger('foo', 'bar');
$this->assertEventTriggered('foo');

assertHeaderEmitted:

Make sure that a header or cookie was actually emitted:

$response->setCookie('foo', 'bar');
ob_start();
$this->response->send();
$output = ob_get_clean(); // in case you want to check the actual body
$this->assertHeaderEmitted("Set-Cookie: foo=bar");

assertHeaderNotEmitted:

Make sure that a header or cookie was not emitted:

$response->setCookie('foo', 'bar');
ob_start();
$this->response->send();
$output = ob_get_clean(); // in case you want to check the actual body
$this->assertHeaderNotEmitted("Set-Cookie: banana");

assertCloseEnough:

For extended execution time testing, tests that the absolute difference between expected and original time is within the prescribed tolerance.:

$timer = new Timer();
$timer->start('longjohn', strtotime('-11 minutes'));
$this->assertCloseEnough(11 * 60, $timer->getElapsedTime('longjohn'));

assertCloseEnoughString:

For extended running time testing, tests that the absolute difference between expected and original time, formatted as strings, is within the prescribed tolerance.:

$timer = new Timer();
$timer->start('longjohn', strtotime('-11 minutes'));
$this->assertCloseEnoughString(11 * 60, $timer->getElapsedTime('longjohn'));

getPrivateMethodInvoker:

Install you to call private methods from outside the class. This returns a program that can be called. The first parameter is an instance of the class . The second parameter is the name of the method you want to make a call.

// Create an instance of the class to test
$obj = new Foo();
// Get the invoker for the 'privateMethod' method.
$method = $this->getPrivateMethodInvoker($obj, 'privateMethod');
// Test the results
$this->assertEquals('bar', $method('param1', 'param2'));

getPrivateProperty:

Retrieves the value of a private class property from an instance of a class.

// Create an instance of the class to test
$obj = new Foo();
// Test the value
$this->assertEquals('bar', $this->getPrivateProperty($obj, 'baz'));

setPrivateProperty:

// Create an instance of the class to test
$obj = new Foo();

// Set the value
$this->setPrivateProperty($obj, 'baz', 'oops!');

// Do normal testing...

What are mocking services?

You will often find that you have to mock one of the services defined in app/Config/Services.php to limit your tests to only the code in question while simulating multiple responses from the services. This is especially true when testing controllers and other testing.

injectMock()

This method allows you to define the exact instance that will be returned by the Services class.

public function testSomething()
{
$curlrequest = $this->getMockBuilder('CodeIgniter\HTTP\CURLRequest')
->setMethods(['request'])
->getMock();
 Services::injectMock('curlrequest', $curlrequest);
 // Do normal testing here....
}

reset()

Removes all mocked classes from the class, bringing it back to its actual state.

resetSingle: Delete any mock and shared instances for a single service, by its name. you may identify yourself needing to supply a pre-configured class instance during testing that will be used with Factories. Use the similar injectMock() andreset()` methods like Services, but they take an additional preceding parameter for the component name:

protected function setUp()
{
parent::setUp();
 $model = new MockUserModel();
 Factories::injectMock('models', 'App\Models\UserModel', $model);
}

CITestStreamFilter provides an alternative to these helper methods. You may need to test things that are difficult to test. Sometimes, capturing a stream, like PHP’s own STDOUT, or STDERR, might be useful. An example demonstrating this inside one of your test cases:

public function setUp()
{
 CITestStreamFilter::$buffer = '';
$this->stream_filter = stream_filter_append(STDOUT, 'CITestStreamFilter');
}
public function tearDown()
{
stream_filter_remove($this->stream_filter);
}


public function testSomeOutput()
{
 CLI::write('first.');
 $expected = "first.\n";
$this->assertSame($expected, CITestStreamFilter::$buffer);
}

If you have any doubts about the above topic or have to get services and consultations and get CodeIgniter testing services. Feel free to contact us. AIRO GLOBAL SOFTWARE will be your strong digital partner. E-mail id: [email protected]

enter image description here Author - Johnson Augustine
Chief Technical Director and Programmer
Founder: Airo Global Software Inc
LinkedIn Profile: www.linkedin.com/in/johnsontaugustine/

enter image description here

What is a PHP unit?

PHPUnit is one of the most well-known and optimized unit testing packages of PHP. It is the most relevant choice of many engineers for rectifying various developmental loopholes of the app. Its main action is to perform overall unit testing for apps, therefore, you can test your code every minute. Yet you can also use it for different actions, as it is more flexible to do just more than unit testing. Moreover, it carries all major PHP frameworks including Laravel. Many expert programmers recommend it for all Laravel unit testing processes, because of its optimized standards.

PHPUnit is created with simple assertions, which make it pretty easy for you to test your code successfully. Further, it gives great results when you are testing code components personally, giving you exotic results, so that mistakes can be identified easily. However, this means that testing much more advanced components like controllers, models and form validations can be a bit difficult as well.

How is unit testing with laravel possible?

Laravel is the most popular PHP framework for app development. From the testing perspective, it is also known to be highly popular for its creative testing features. In Laravel, there are two ways to test the application. One is with Unit testing and Feature testing. Unit testing allows you to test your classes models etc, while Feature testing allows you to test your code base.

If you look inside your Laravel installation folder, you can see that there are two test subfolders available. These two subdirectories in hosting for the Laravel project are Unit testing and Feature testing. These are the areas where you will be conducting your app's test, either be Unit testing or Feature testing.

How to create a Laravel unit test case?

When you use PHPUnit, the first step is to create the latest test classes. These test classes are stored in the./tests/ folder of your Laravel app. Each test class is named Test.php inside a directory. As this format helps PHPUnit to find each test class simply, and further avoid any other class that doesn’t reside in the Test.php file. In your latest Laravel app, you will find two files in the ./tests/ directory, one is ExampleTest.php and the other is TestCase.php. TestCase.php file is commonly a bootstrap file that sets the Laravel ecosystem and variety of features within our tests. It makes it very simple to use Laravel features in tests, and also allows a framework for testing assistance. The ExampleTest.php merges an example code test class which contains a basic test case using app testing helpers.

For creating a front test class, you can either create a new file manually or can run the artisan make:test command .

Laravel will build a basic test class that looks like this:

<?PHP
class BasicTest extends TestCase{
 /*** A basic test example
** @return void
*/ public function testExample(){
$this->assertTrue(true);  }
}?>

Though this folder includes a lot of information regarding tests, the most important note, for now, is the testsuite folder definition:

<?xml version="1.0" encoding="UTF-8"?>
<PHPUnit ... >
<testsuites>
<testsuite name="Application Test Demo">
<directory>./tests/</directory>
 </testsuite>
</testsuites>
...</phpunit>

How to write a basic unit test?

After finishing the above-mentioned processes successfully, you can now write the basic unit test case for your Laravel app by directing it to the tests/Feature/ExampleTest.php.

Here, you can write test cases for testing the fundamental specialties of the application.

<?php
namespace Tests\Feature;
use Tests\TestCase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class ExampleTest extends TestCase
{
 /**
* A basic test example.
*
* @return void
*/
public function testBasicTest()
 {
$response = $this->get('/');
$response->assertStatus(200);
}
}

You can use seven of the basic PHPUnit assertions to write tests for your Basket class. These assertions are:

  • assertTrue()
  • assertFalse()
  • assertEquals()
  • assertNull()
  • assertContains()
  • assertCount()
  • assertEmpty()

What is given, when, then in testing?

If you want to test particular actions of your code, then you should follow the intrinsic pattern of Given, When and Then. Given – It states the primary ecosystem setup you would like to test. You can use some data, or can even set up a model factory in this step. When – When refers to a specific function and called at some particular stage of the testing process. Then – In this part, you declare what the result should look like.

How to test a Laravel application?

Unit testing is not the only testing process you will need for your app. Though it is most necessary in most cases and must be an important part of your creating process, it is not necessary that it will complete all your testing needs. Sometimes your application has complex displays, navigation, and forms, and you want to test these particulars too.

This is where Laravel’s test assistance comes into play and makes testing of a few particulars simple just as the Unit testing does.

In past Laravel unit testing examples, we saw the automatic files within the /tests/ directory and left the ./tests/ExampleTest.php file to review at the next stage. So open it now, it should look like this:

<?php
class ExampleTest extends TestCase
{
/**
* A basic functional test example
*
* @return void
*/
public function testBasicExample()
{
$this->visit('/')
->see('Laravel 5.5');
}
}

As you can see, the test in this scene is normally simple and very quick to understand. Without having any prior knowledge about how Laravel test assistance works, you can understand that it outputs some like this:

  • when I visit / (webroot)
  • I should see ‘Laravel 5

When you open the app in your web browser, you will see a splash screen with “Laravel 5” written on it. After successfully passing a test with PHPUnit, it is right to say that the output of this example test is spot-on.

This test ensures that the web page made at the / path, gives output with the text ‘Laravel 5’. Though it looks like an easy test and doesn’t seem much critical, whenever your web app needs to display sensitive information, tests like this can simply avert you from deploying broken apps.

If you have any doubts about the above topic or have to get services and consultations and get the Laravel test services. Feel free to contact us. AIRO GLOBAL SOFTWARE will be your strong digital partner. E-mail id: [email protected]

enter image description here

Author - Johnson Augustine
Chief Technical Director and Programmer
Founder: Airo Global Software Inc
LinkedIn Profile: www.linkedin.com/in/johnsontaugustine/

enter image description here

Testing code is one of the most major parts to understand your app and the behavior of code. All the developer knows how hurtful bugs can be, especially in the creating stage as it takes hours of effort. Testing each stage can be as good as believing in yourself. You write and run your code, without knowing how it actually behaves if some exception occurs, this may cause a problem in production. So, executing test cases plays a major role in SDLC. You give a better life and believe your code with your eyes closed, once your examination coverage is at a good level.

Today, we are going to write an easy test method and execute test code using tools like Xdebug and PHPUnit. PHPUnit is a programmer-based testing framework. This is an excellent testing framework for writing Unit tests for PHP Web Apps. With the help of PHPUnit, we can direct test-driven improvement.

How to install PHPUnit?

wget https://phar.phpunit.de/phpunit-7.5.phar
chmod +x phpunit-7.5.phar
sudo mv phpunit-7.5.phar /usr/bin/phpunit

There are several other possible ways to install PHPUnit. Now, To get our Test Coverage full record we need to install Xdebug:

sudo apt install php-pear
pecl install xdebug
sudo apt-get install php-xdebug

Without making any further delay Let's dive into our easy test stages where we test whether an array is empty:

  • Create a file UnitTest where we will include all testable files
  • In this folder, create a subfolder test
  • Create a new file phpunit.xml
  • In this subfolder and add the below code

    /UnitTest/tests/ /UnitTest/tests/

What are the Basic Conventions to Write Unit Test Case?

Below are some basic conventions and steps for writing tests with PHPUnit:

  • Test File names should have a suffix Test.
  • Same as it, If the class name is MyFirstClass then the test class name will be MyFirstClassTest.
  • Add test as the prefix for method names.
  • All testing types are public.
  • MyFirstClassTest class should be inherited

These are the major instructions for the PHP unit testing framework. The basic configurations and settings are all set up. It is now time to write the prime test case.

How to Write The First Unit Test Case in PHP?

Build a file EmptyTest.php in UnitTest/tests. Add the below code to it.

<?PHP
use PHPUnit\Framework\TestCase;
class EmptyTest extends TestCase
{
 public function testFailure()
{
$this->assertEmpty(['something']);
 }
}
?>

Now, to execute our test code inside terminal type:

phpunit i.e. phpunit tests/EmptyTest.php.

By executing only phpunit, it automatically executes all test file inside UnitTest/tests folder because we have mentioned this directory in phpunit.xml above. We will get our test failure because the value in the array is not empty. In the terminal you are getting like this:

F                                                                   1 / 1 (100%)
Time: 513 ms, Memory: 10.00MB
There was 1 failure:
EmptyTest::testFailure
Failed asserting that an array is empty
/home/anu/myproj/testcase/tests/EmptyTest.php:8

FAILURES!

Tests: 1, Assertions: 1, Failures: 1

Let's pass our above test case and add one more step to test equals.

<?PHP
use PHPUnit\Framework\TestCase;
class EmptyTest extends
TestCase
{

public function

testFailure()
{
$this->assertEmpty([]);
 }
}
?>
<?PHP
use PHPUnit\Framework\TestCase;
class EqualsTest extends TestCase
{
public function testFailure()
{
$this->assertEquals(0,1); //failed asserting 0 and 1 are equal
}
}
?>

It gives an unexpected error when $expected is not the same as $actual. If $expected is the same to $actual then it is true. Don’t forget that the first argument is expected and the other is actual. The above test only walks away if the expected (0) is equal to (1). To pass the above test case just replace 0 with 1 or 1 with 0. Now, execute both test cases. Your both tests must pass:

PHPUnit 7.5.6 by Sebastian Bergmann and contributors.
Runtime:       PHP 7.3.1-1+ubuntu18.04.1+deb.sury.org+1 with Xdebug 2.7.0
Configuration: /home/samrat/myproj/UnitTest/phpunit.xml
..                                                                  2 / 2 (100%)
Time: 200 ms, Memory: 10.00MB
OK (2 tests, 2 assertions)

Let’s see another example in which a developer has built a code to parse the items received in JSON and validate it for the possible use case may be an exception or for other validation instruction.

Let's build an app/item_parser.php file inside the UnitTest directory

<?PHP
namespace App\Parser;
require_once 'exceptions.php';
use App\Exceptions\JsonParseException;
use App\Exceptions\InvalidNumberFormatException;
class ItemsParser {
public static function parse($response){
$jDecode=json_decode($response);
if (JSON_ERROR_NONE !== json_last_error()){
throw new JsonParseException('Error parsing
JSON:'.$response);
}
$jd=$jDecode->_embedded->menu_items;
$parsed = [];
foreach($jd as $key => $item){
$price=$item->price_per_unit;
if (is_string($price)) {
throw new 
InvalidNumberFormatException('Invalid numeric value encountered:'.$price);
}
$parsed[$item->id] = [
"label" => $item->name,
"value" => number_format(($price/100), 2, '.', ' ')
];
}
return $parsed;
}
}
?>

create a class called ItemsParser with a static option called parse that takes one argument called a response, received from JSON data. We have checked for different types of exceptions and returned parsed data as an array.

Let's add some exceptions classes for the above use cases inside the same folder:

<?PHP
namespace App\Exceptions;
class JsonParseException extends
\Exception {}
class InvalidNumberFormatException 
extends \Exception {}
?>

Next in the UnitTest/tests folder, create a new file called ItemsParserTest.php and add the below test code:

<?php
use PHPUnit\Framework\TestCase;
require_once __DIR__ . '/../app/item_parser.php';
use App\Parser\ItemsParser;
class ItemsParserTest extends TestCase
{   
public function test_create_ItemsParser() {
 $ip = new ItemsParser();
$this->assertEquals('App\Parser\ItemsParser',
\get_class($ip));
}
}
?>

Run the above test code, Our test case must pass. By, this we can make sure that ItemParser class is successfully instantiated. As we don't invoke real endpoint. Let's create a fake json data called one.json inside UnitTest/json and test.

{
"_embedded": {
"menu_items": [
{
"id": "1",
"in_stock": null,
"name": "Pizza",
"open": false,
"pos_id": "101",
"price_per_unit": 899
}
]
}
}

Now Let's write another test code to ensure our data is actually parsed the way we aimed it:

<?php
use PHPUnit\Framework\TestCase;
require_once __DIR__ . '/../app/item_parser.php';
require_once __DIR__ . '/../app/exceptions.php';
use App\Exceptions\JsonParseException;
use App\Parser\ItemsParser;
use App\Exceptions\InvalidNumberFormatException;
class ItemsParserTest extends TestCase
{
var $dir = __DIR__ . '/../json/';
 public function test_create_ItemsParser() {
$ip = new ItemsParser();
 $this->assertEquals('App\Parser\ItemsParser', \get_class($ip));
}
 public function     test_parseSingleItem_shouldReturnArrayOneLabelAndValue(){
$items=file_get_contents($this->dir.'one.json');
$expected = ['1' => ['label' => 'Pizza', 'value' => '8.99']];
$this->assertSame($expected, ItemsParser::parse($items));
 }
}
?>

As, we make fake data, and send that data to ItemParser::parse() option. If we now execute our test case we get the data the way we expected.

PHPUnit 7.5.8 by Sebastian Bergmann and contributors.
Runtime:       PHP 7.2.15-0ubuntu0.18.04.1 with Xdebug 2.6.0
Configuration: /home/samrat/myproj/UnitTest/phpunit.xml
..                                                                  2 / 2 (100%)
Time: 377 ms, Memory: 10.00 MB
OK (2 tests, 2 assertions)

Basically, what we did is we send json details and decoupled them on our data only with label and value as keys and returned only data that is needed as an array. Next, Let's test for the array keys we are getting:

<?php
use PHPUnit\Framework\TestCase;
require_once __DIR__ . '/../app/item_parser.php';
require_once __DIR__ . '/../app/exceptions.php';
use App\Exceptions\JsonParseException;
use App\Parser\ItemsParser;
use App\Exceptions\InvalidNumberFormatException;
class ItemsParserTest extends TestCase
{
 var $dir = __DIR__ . '/../json/';
 public function 
test_JsonParser_arrayKey_shouldReturnKey_label_and_value(){
$items=file_get_contents($this->dir.'one.json');
 $itemId='1';
$parsed=ItemsParser::parse($items);
$this->assertArrayHasKey('label',$parsed[$itemId]);
 $this->assertArrayHasKey('value',$parsed[$itemId]);
 }
}
?>

From the above test code, we can make sure that whether we are getting the key we expected that is label and value. What about the wishes we included in our methods, whether they are executed the way we wanted? Well, I am not sure so let's test it. Say, we have some JSON data with price in the string:

{
"_embedded": {
"menu_items": [
{
"id": "1",
"in_stock": 
"name": "Pizza",
"open": false,
"pos_id": "101",
"price_per_unit": "iamstring"
},
{
"id": "2",
"in_stock": 
"name": "Burger",
"open": false,
"pos_id": "101",
"price_per_unit":"gfsgd"
}
]
}
}

How does our test code block respond when we send price as string, well we must be sure our test code handles such kinds of exceptions.

public function
test_stringPriceValueProvided_shouldThrow_InvalidNumberFormatException(){
$items=file_get_contents("stringPrice.json")
 $this->expectException(InvalidNumberFormatException::class);
$parsed=ItemsParser::parse($items);
}

expectException() method is to ensure whether an expected exception is thrown by our code block. Run phpunit and check the above code it must by the way!

Rechange, the ItemParser.php file we have used the number_format function to convert cent price into the dollar. So, Let's enter a test to check whether our price has been perfectly converted.

public function testCent_Conversion_toDollar(){
$items=$this->file_get_contents('one.json');
 $itemId='1';
 $parsed= ItemsParser::parse($items);
$this->assertEquals(8.99,$parsed[$itemId]['value']);
 }

And These tests can go on and on, wouldn't it be nice to get a report or analyzer for our test case. To get a total test coverage report would be best. So, we have written some test code and let's generate our test report. It's easy just type this in terminal: phpunit --coverage-html . In my case phpunit --coverage-html report/. You will get whole report in html format. By the way, we can generate in xml, php, text and many other formats. Just type: phpunit --help for more.

The above test coverage explains, our first example test coverage is complete but ItemParserTest could be great and we only covered some part of our code so let's stick with partially completed. I leave it up to you to make it full. Actually, partially test code coverage can be acceptable coverage in the software world.

We also get the report of where we can do better. Here are some other code coverage statistics:

How about the Conclusion?

This article explains a basic setup that helps you in getting started with PHPUnit for PHP unit testing.

Hope you find this blog helpful. Unit Testing is a vast topic. Here I have given you a brief introduction so that you can start entering your own tests.

If you have any questions about the above topic or have to get services and consultations and get the unit test services. Feel free to contact us. AIRO GLOBAL SOFTWARE will be your strong digital partner.

E-mail id: [email protected]

enter image description here

Author - Johnson Augustine
Chief Technical Director and Programmer
Founder: Airo Global Software Inc
LinkedIn Profile: www.linkedin.com/in/johnsontaugustine/

enter image description here

If you are using mostly open-source in your business, and have few MS SQL server databases, you might want to consider migrating those to MySQL.

Why do you want to consider migrating Microsoft SQL Server to MySQL database?

  • To avoid the License and fees of MS SQL Server. In MySQL, even if you decide to use the MySQL enterprise, it really costs less money.
  • Unlike SQL Server, MySQL supports a wide range of OS including several Linux distros, Solaris and more.
  • To implement a highly structured database infrastructure
  • To take benefit of several advanced features of the MySQL database that have been tested accurately over the years by a huge open source community

We can migrate the MS SQL database to MySQL using the migration module of the “MySQL Workbench” facilities. The easiest way to enable MySQL Workbench is to install “Oracle MySQL for windows”, which enables several MySQL options including the Workbench.

Download and install this My SQL which includes Workbench and other needed connectors and drivers that are most important for the migration.

What are the steps involved in the migration of the MsSql database to MySQL using Workbench?

  • The first step is to take care of prerequisites.
  • The second step is to select the source and target the database
  • The third step is to migrate the objects
  • The final step is data migration

Take care of Prerequisites

Before starting the MySQL database migration, we are required to ensure that ODBC drivers are present for communicating to the source Microsoft SQL Server database.

Check that the max_allowed_packet tool in the MySQL server is required for the largest field to be migrated.

Make sure that we can connect to both the targeted MySQL server database and source Microsoft SQL database with the needed requirements that are required for migrating the data across.

Select Source and Target Database

First, explain the source Microsoft SQL Server database parameter. Click “MS SQL Server” from the database system list. In the tab, select the DSN, and specify the username to the database.

Next, define the target MySQL database connection. Select “Local Instance MySQL” depending on your situation. In the parameters tab, specify the hostname where the MySQL database is executing, the MySQL port, username. If you don’t specify the password, it will promote you.

Once you target the source and destination, all available schemas and databases will be collected. You can click the specific schema that you like to migrate, and you can also specify personal schema mapping to the destination MySQL database.

Migrate the Objects

In this step, the Microsoft SQL Server schema objects, table objects, data types, default values, indexes, primary keys are changed. Please note that view objects, function objects and stored programs are just copied and commented out as we will need to convert those automatically.

Data Migration

In this step, the default copy of data is done from source to destination server for the migrated tables. Please note that using the migration we can only change tables and copy data but cannot convert the triggers and views.

If you have any questions about the above topic or have to get database management services and consultations and get the server hosting services. Feel free to contact us. AIRO GLOBAL SOFTWARE will be your strong digital partner. E-mail id: [email protected]

enter image description here

Author - Johnson Augustine
Chief Technical Director and Programmer
Founder: Airo Global Software Inc
LinkedIn Profile: www.linkedin.com/in/johnsontaugustine/

enter image description here

The floor provides a neat SQLite abstraction for your Flutter apps it is inspired by the Room persistence library. It comes with default mapping between memory objects and database rows while still giving complete control of the database with the use of SQL.

What is Flutter?

The Flutter framework contained both a software development kit and their widget-based user interface library. This library consists stained of various inoperable UserInterface elements, such as sliders and buttons.

Developers who create mobile applications with the Flutter framework will do so using a language called Dart. With a command like JavaScript, Dart is a typed programming language that completely focuses on front-end development.

You can save, query and, remove your Objects in a simple and direct way with the Floor database!

How do we start?

To start with Floor, let’s include these dependencies in pubspec.yaml

dependencies:
 flutter:
sdk: flutter
floor: ^0.14.0
dev_dependencies:
 floor_generator: ^0.14.0
build_runner: ^1.7.3

What about the entity class?

The entity class will always represent database table Columns. The @entity adds the class as a persistent class and you need to include a primaryKey.

// entity/student.dart
import 'package:floor/floor.dart';
@Entity(tableName: 'students')
class Student {
@primaryKey(autoGenerate: true)
final int id;
final String name;
final Float grade;
Person(this.id, this.name, this.grade);
}

What about data access objects?

This component is the most responsible for managing enable to the underlying SQLite database.

You can use the normal SQLite @Query or @insert, @delete and @update.

// dao/student_dao.dart
import 'package:floor/floor.dart';
@dao
abstract class StudentDao {
@Query('SELECT * FROM students')
Future<List<Student>> findAllStudents();
@Query('SELECT * FROM students WHERE id = :id')
Stream<Student> findStudentById(int id);
@insert
Future<void> insertStudent(Student student);
@Query('DELETE FROM students WHERE id = :id')
Future<void> delete(int id);
}

What about a Database?

It has to be an abstract class that will be extends FloorDatabase

// database.dart
// required package imports
import 'dart:async';
import 'package:floor/floor.dart';
import 'package:sqflite/sqflite.dart' as sqflite;
import 'dao/student_dao.dart';
import 'entity/student.dart';
part 'database.g.dart'; // the generated code will be there
@Database(version: 1, entities: [Student])
abstract class AppDatabase extends FloorDatabase {
StudentDao get studentDao;
}
part 'database.g.dart';

make sure to add the above line and it should be equal to your database file name which in our scene is atabase.dart.

How to Build the database?

After that, go to the terminal and execute

flutter packages pub run build_runner build

make sure that you added flutter to your surrounding variables. Now you can easily access your database using :

$Floor +

your database class name which in our scene is AppDatabase

final database = await
$FloorAppDatabase.databaseBuilder('app_database.db').build();
final studentDao = database.studentDao;
final student= Student(1, 'Frank', 99);
await studentDao.insertStudent(student);
final result = await personDao.findPersonById(1);

If you want to generate the Id by default, then you can easily pass null instead of Id in the entity object, i.e:

final student= Student(null, 'Frank', 99);
await studentDao.insertStudent(student);

I hope you enjoyed this nice and easy database.

If you have any doubts about the above topic or have to get services and consultations and get flutter app development company. Feel free to contact us. AIRO GLOBAL SOFTWARE will be your strong digital partner. E-mail id: [email protected]

enter image description here

Author - Johnson Augustine
Chief Technical Director and Programmer
Founder: Airo Global Software Inc
LinkedIn Profile: www.linkedin.com/in/johnsontaugustine/

enter image description here

Let us begin by considering what android architectures existed before MVVM. The first component is Model View Presenter. Though this architecture classifies the business logic from the app’s UI, it is difficult to implement.

In the long run, this can change into high development costs. The second android architecture is MVC. Just like MVP, it is also quite difficult and not suitable for small projects. Google introduced MVVM to resolve these challenges. By separating code into smaller chunks, MVVM simplifies the debugging process.

Through this article, you’ll understand MVVM architecture and implementation. This blog shows how to debug common mistakes resulting from this architecture.

What is MVVM?

The Model is somewhat the same as MVC. we have ViewModels which are going through the view and all the logic is in the ViewModel and no controller is there.

Example: Knockout.js

What is Kotlin?

Kotlin is a static object-oriented programming language that is interoperable with the Java virtual machine, Java libraries and the android.

Kotlin saves time for programmers as the less verbose language provides briefer and less redundant code. Kotlin can be compiled into a javascript text or an LLVM encoder. In many ways, Kotlin is considered a replacement Java. While it is not compatible with code, it is interoperable with Java code and libraries. Kotlin also has its libraries that were built with its community's early development through an API for Android apps.

How to implement MVVM architecture in Android using Kotlin?

  • The first step is to launch Android studio
  • The next step is to create the model
  • The next step is to create the view
  • The next step is to create a recycle view adapter
  • The next step is to create the view model
  • The next step is to create the view model factory
  • The next step is to main activity connecting the code
  • The Final is the result

How to launch Android Studio?

First Launch Android Studio and create a new project. Make sure that you select Kotlin as your programming language.

How to Create the model?

Next is to create the app model. Also referred to as the data class. To avoid misunderstanding, create a package named model inside the java folder. Then, create a class named Blog in the model package.

For simplicity, the class will only have one variable. There is no need to include getters and setters, Kotlin adds them to the class automatically.

Here’s the code for the class. data class Blog(var title: String)

How to Create the View?

The view is what the user displays. The User interface, therefore, needs to be well structured to simplify any confusion and dissatisfaction.

Open the activity_main.xml file and change the Layout from a linear Layout. Set the orientation to vertical, this arranges the User interface components vertically in the Layout. Our app’s first-ever widgets are Edittext, Button, and a RecyclerView.

Make sure all these steps have IDs since they will be vital at a new stage.

How to Create the item_view?

In the Layout, we need to build the design of the element in the RecyclerView. Therefore, build a file named item.xml and include the code sufficient code. The design is easy since the individual can also access one attribute from the data class.

How to Create a RecyclerView Adapter?

A RecyclerView adapter handles the linking of the item.xml layout to the RecyclerView. It also includes a list of items and displays them to the user. The code for the RecyclerView is shown below.

class NoteRecyclerAdapter(val viewModel: MainViewModel, val arrayList:
ArrayList<Blog>, val context: Context):
RecyclerView.Adapter<NoteRecyclerAdapter.NotesViewHolder>() {
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int,
): NoteRecyclerAdapter.NotesViewHolder {
var root =
LayoutInflater.from(parent.context).inflate(R.layout.item,parent,false)
return NotesViewHolder(root)
}
override fun onBindViewHolder(holder: NoteRecyclerAdapter.NotesViewHolder,
position: Int) {
holder.bind(arrayList.get(position))
}
override fun getItemCount(): Int {
if(arrayList.size==0){
Toast.makeText(context,"List is empty",Toast.LENGTH_LONG).show()
}else{
}
return arrayList.size
}
inner  class NotesViewHolder(private val binding: View) :
RecyclerView.ViewHolder(binding) {
fun bind(blog: Blog){
binding.title.text = blog.title
binding.delete.setOnClickListener {
viewModel.remove(blog)
notifyItemRemoved(arrayList.indexOf(blog))
}
}
}
}

How to Create the ViewModel?

Create a package ViewModel. Inside this file, built a Kotlin class and name it MainViewModel. The class should extend the Android ViewModel. You might face failure if you failed to include lifecycle dependencies from Jetpack.

The MainViewModel will have mutable live data that holds the array list. It’s vital to use LiveData since it notifies the UserInterface in case of any data change. The MainViewModel is shown below.

class MainViewModel: ViewModel() { var lst = MutableLiveData<ArrayList>() var newlist = arrayListOf() fun add(blog: Blog){ newlist.add(blog) st.value=newlist } fun remove(blog: Blog){ newlist.remove(blog) lst.value=newlist } }

How to Create the ViewModel Factory?

The purpose of a ViewModel factory is to the ViewModelchange. This prevents the app from destroying in case an activity is not found.

The syntax for our MainViewModelFactory is shown below:

class MainViewModelFactory(): ViewModelProvider.Factory{
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
    if(modelClass.isAssignableFrom(MainViewModel::class.java)){
        return MainViewModel() as T
    }
    throw IllegalArgumentException ("UnknownViewModel")
}

How is MainActivity connect the code?

We have built the model, ViewModel, ViewModelfactory, and RecyclerView. These variables need to be instantiated in the MainActivity for the application to execute.

Beginning by showing the RecyclerView and instantiating it. Set out the layout manager for the RecyclerView to LinearLayoutManager. The MainActivity file contains three major methods: initialiseAdapter,observeData, and addData. the initialiseAdapter method assigns a ViewManager to the RecyclerView.

The observeData looks for changes in the viewmodel and send them to the RecyclerAdapter. The addData method takes in the user’s input and updates the list.

class MainActivity : AppCompatActivity() {
private var viewManager = LinearLayoutManager(this)
private lateinit var viewModel: MainViewModel
private lateinit var mainrecycler: RecyclerView
private lateinit var but: Button
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    mainrecycler = findViewById(R.id.recycler)
    val application = requireNotNull(this).application
    val factory = MainViewModelFactory()
    viewModel = ViewModelProviders.of(this,factory).get(MainViewModel::class.java)
    but = findViewById(R.id.button)
    but.setOnClickListener {
        addData()
    }

    initialiseAdapter()
}
private fun initialiseAdapter(){
    mainrecycler.layoutManager = viewManager
    observeData()
}

fun observeData(){
    viewModel.lst.observe(this, Observer{
        Log.i("data",it.toString())
        mainrecycler.adapter= NoteRecyclerAdapter(viewModel, it, this)
    })
}


fun addData(){
    var txtplce = findViewById<EditText>(R.id.titletxt)
    var title=txtplce.text.toString()
    if(title.isNullOrBlank()){
        Toast.makeText(this,"Enter value!",Toast.LENGTH_LONG).show()
    }else{
        var blog= Blog(title)
        viewModel.add(blog)
        txtplce.text.clear()
        mainrecycler.adapter?.notifyDataSetChanged()
    }
 }

}

What are the Results?

If there were no mistakes in your code, it should compile and show the User interface in the image below. Whatever you type in the EditText should display in the recycler view once you select the submit button.

If you have any doubts about the above topic or have to get services and consultations and get MVVM architecture and android development using Kotlin. Feel free to contact us. AIRO GLOBAL SOFTWARE will be your strong digital partner.

E-mail id: [email protected]

enter image description here Author - Johnson Augustine
Chief Technical Director and Programmer
Founder: Airo Global Software Inc
LinkedIn Profile: www.linkedin.com/in/johnsontaugustine/

enter image description here

If you have to make a flutter app and are ready to release it on the Apple Store, then you are in the perfect place. In this blog, you will learn the process of how to publish the flutter app on the Apple store. There are some efficient points that you should always remember before publishing the app to the Apple store. Do you know that Apple is very restrictive about user privacy and UI design?. Don’t worry about that, We are going to cover the common problems that a new developer does during the publishing of their first iOS app. If you want to build a flutter app with perfect user design visit a flutter app development company for great works.

What is flutter?

Flutter is a UI toolkit for building fast, beautiful, natively compiled applications for mobile, web, and desktop with one programing language and single codebase. Flutter is a cross-platform development framework that has the ability to write one code and can deploy on different platforms. Actually, it saves a lot of time and effort for developers.

What are the steps to release the flutter ios app on the apple store?

  • First, you have to create an Apple Developer Account
  • Then you should Register Bundle Identifier
  • Next, you have to Get App icon and App screenshot ready
  • Then the next step is app Store Connect Listing Process
  • The last and final step isOpen Project on Xcode and Build

How to create an app developer account?

First, you go to the apple developer account official registration website and build an Apple developer account. Do not forget that an Apple developer account is associated with your email ID. So, choose the correct email ID and keep it a secret. Apple developer accounts have an annual fee that you should have to pay.

Ok, when you are going to publish an app for your user. it is a good exercise to create a separate account for them to avoid problems in the future.

How to register a bundle identifier?

After you register for the developer account, the first most important thing you need to do is register a Bundle ID. Every iOS app is associated with a Bundle ID, which is a rare identifier registered with Apple.

  1. On the official Apple developer account select “Certificates Identifiers and Profiles”. On the left side, the menu selects “Identifiers”.
  2. Click “+” to create a Bundle ID. Select “App ID” on the next following page and select continue.
  3. Select App type and then select “App” and click continue.
  4. On the following page select “Register an App ID” – Add a short description and select Bundle ID as Explicit and type an “App Package Name”
  5. On the next following page, confirm the information given and select Register to register your Bundle ID.

How to create an app icon and screenshot?

Ok now you have a bundle ID, it’s time to start a flutter project to fulfill the Apple instructions. We need to build multiple app icons for different devices. There are various tools available to build iOS icons like app icon generators, Just put a 1024×1024 px image and it will give you all of the apple icons. Now, you can download the zip file and extract it. Next, you can found that a file named “AppIcon.appiconset” inside the “Assets. cassettes” folder. Copy this file and open the flutter project on your Android studio. Select the iOS file in the project directory called your_project_name/ios/Runner/Assets.cassettes/AppIcon.appiconset. Paste and change the copied folder in the given location.

You can change the screen by removing “LauncherImage” with “LaunchImage.images”. Apple has provided the instructions on its official page, Please take an effort to read it.

How to do the app store connect listing process?

Next, you have to go through the apple store connection and select "my App." Select on the “+” icon to create the App. On the pop-up window, write the App name, select language, select the Bundle ID that you made in the last step, and write SKU. Please click on the full access radio button and select “Create”.

Now, on the next following page fill in all of the information. Please be careful when putting the screenshot. Following are the screenshot image dimensions:

  • app screenshot 6.5 display – 1242×2688, 2688×1242, 1284x 2778
  • app screenshot 5.5 display – 1242x 2208, 2208x 1242
  • app screenshot 12.9 3rd. – 2048×2732, 2732x 2048
  • app screenshot 12.9 2nd. – 2048×2732, 2732x 2048

Please Don’t forget the screenshot images should not contain the “flutter debug” tag . You can remove the flutter debug tag by writing the below code in the app.

MaterialApp( debugShowCheckedModeBanner: false,)

How to open the project on Xcode and build?

O the time has arrived to publish the app on Apple Connect. Open flutter project in Android studio, and select tool/firebase/ open ios module on XCode. Your flutter project has been perfectly exported into XCode. The first test app is running correctly or not in Xcode. Connect your iPhone device by a USB cable, and select the “RUN” on the top of the XCode. If there are any mistakes when running Xcode, then close the window, and execute it on Android studio to make the correction in the code.

Once you run the code successfully, On the Xcode window, Navigate to your target’s on settings in Xcode:

  1. In the main sidebar, click the Runner target.
  2. Select the General tab. There, you can change the app name. Do not forget, the bundle identifier should be the same that you have built in the early stage.
  3. Look through the deployment info section, and click device.
  4. If you are using Xcode for the first time, then it will promote you to log in with your Developer ID. Just sign in and, then, click TEAM as your developer account. Then check to automatically manage sign-in.
  5. Rest forms are automatically filled for you; you don’t need to make any changes.
  6. Go to Product/Destination/Build.
  7. Go to Product/Archive. Now you will see a pop-up window. Select the validate app and keep continuing until you get a message that notifies you that it was successful.
  8. Once the app gets validated, select Distribute App and the same pop-up window will appear. Once you get to a correct release of the app on the apple store, that means your build is ready to publish.
  9. It will take 10-20 minutes to appear to build on the apple store connect.
  10. So you are ready to “Submit for review”. Select it; if you forgot any field to be filled then you will get the notification that will appear on top beside the “submit for review” button. Fill in all the details, and submit the app.

You will get an email notification whenever the review has been changed by the Apple team.

If you have any queries about the above topic or have to get services and consultations and get flutter app development solutions. Feel free to contact us. AIRO GLOBAL SOFTWARE will be your strong digital partner. E-mail id: [email protected]

enter image description here

Author - Johnson Augustine
Chief Technical Director and Programmer
Founder: Airo Global Software Inc
LinkedIn Profile: www.linkedin.com/in/johnsontaugustine/