Subscribe

Tag: FOSSAISA

Dynamic Table Views are used at places where there may be any kind of reusability of cells. This means that there would exist cells that would have the same UI elements but would differ in the content being displayed. Initially the Settings Controller was built using UICollectionViewController which is completely dynamic but later I realized that the cells will remain static every time so there is no use of dynamic cells to display the UI hence, I switched to static table view cells. Using Static Table View is very easy. In this blog, I will explain how the implementation of the same was achieved in SUSI iOS app.

Let’s start by dragging and dropping a UITableViewController into the storyboard file.

The initial configuration of the UITableView has content as Dynamic Prototypes but we need Static cells so we choose them and make the sections count to 5 to suit our need. Also, to make the UI better, we choose the style as Grouped.

Now for each section, we have the control of statically adding UI elements so, we add all the settings with their corresponding section headers and obtain the following UI.

After creating this UI, we can refer any UI element independently be it in any of the cells. So here we create references to each of the UISlider and UISwitch so that we can trigger an action whenever the value of anyone of them changes to get their present state.

To create an action, simply create a function and add `@IBAction` in front so that they can be linked with the UI elements in the storyboard and then click and drag the circle next to the function to UI element it needs to be added. After successful linking, hovering over the same circle would reveal all the UI elements which trigger that function. Below is a method with the @IBAction identifier indicating it can be linked with the UI elements in the storyboard. This method is executed whenever any slider or switch value changes, which then updates the UserDefaults value as well sends an API request to update the setting for the user on the server.

Meilix is a lubuntu based script. It uses Travis to compile and deploy the iso as Github Release. Normally Travis took around 17-21 minutes to build the script and then to deploy the iso on the page. It is quite good that one gets the iso in such a small interval of time but if we would able to decrease this time even more then that will be better.

The idea behind reducing the time of Meilix building is to parallely run the tests which are independent to each other. So here we run the build.sh and aptRepoUpdater.sh parallely to reduce the time upto some extent.This pictures denotes that both the tests are running parallely and Github Releases is waiting for them to get complete successfully to deploy the iso.

Here we included a job section in which we wrote the test which Travis has to carry out parallely. This will run both the script at the same time and can help to reduce the time.
After both the script run successfully then Github Release the iso.

Here we can see that we are only able to save around 30-40 seconds and that much matters a lot in case if we have more than 1 build going on the same time.

In Android, loading heavy and high resolution images is a difficult task. For instance, if we try to load a photo clicked at a resolution four times that of the screen and try to load it in an imageview, it may result in an app’s crash due to the OutOFMemory exception. It happens because at the run time of our application some limited memory is allocated to our application and if we exceed that by loading a high quality images. To make a perfect gallery application, one must take care of all the possible causes for application crashes. In Phimpme Android, we have done this with the help of Glide library with some other tweaks to help catch all possible causes for the OutOfMemory exceptions. In this tutorial, I will be discussing how we have displayed heavy images with the help of Glide library and other tweaks to avoid the above mentioned exception.

Step 1:

To avoid the OutOFMemory exception, first we have to add the below line of code in the AndroidManifest.xml file.

android:largeHeap=”true”

What this piece of code does is that it increases the amount of heap memory that is allocated at the time of run time of the application. Hence, more heap memory, less chance of running out of memory.

Step 2:

To load the images into the image view we can make use of the Glide library as it is the most recommended way to do it according to the Google’s Android developer page to cache bitmaps. The below code helps us to load the image in the imageView using a pager adapter.

This is the way we have done it in the Phimpme Android application using the Glide library. We are loading the image as a bitmap and by preferring the bitmap RGB565 as it consumes 50% less memory than the RGB8888 model which may be the type of the original image. Of course the image quality will seem bit less but it is not noticeable until we zoom in to full extent.

The next thing we are doing is caching the image in the memory using the below line of code using Glide library.

.diskCacheStrategy(DiskCacheStrategy.SOURCE)

As caching images offers faster access to the images. It also helps in avoiding the OutOfMemory crashes when we are using a large list of images. Link to cache images without using the Glide library is mentioned in the resources section below. After this, we are loading the image in the PhotoView which is a module we are using in the Phimpme Android application, which extends to the imageView and comes with many zooming images functionalities.

This is how we have implemented the loading of images in the gallery view in Phimpme Android application so that it can handle resolution of any sizes without running out of memory. To get the full source code on how to load high resolution images, please refer to the Phimpme Android repository.

One of the important features of SUSI Web Chat is that the state of the application is maintained upon logout-login and across all clients. The web chat application provides various settings to a logged in user and each user has his own preferences. So all the settings chosen accordingly by the user must be stored on the server so that whenever a user logs in we pull the users data from the server and initialise the application according to his chosen settings and whenever settings are changed we update them on the server. This helps us maintain the state of the application specific to a given user and also across all clients.

The flow behind the implementation is:

The client fetches the settings upon login and initialises the app accordingly.

Whenever user settings are changed, the client updates the changed settings on the server so that it can be accessed by other clients as well and so, the state is maintained across all chat clients

How is this implemented?

We use UserPreferencesStore to store all the settings, and Actions to push and pull user data from the server and update the UserPreferencesStore.

Initialising the User Settings

Whenever the app is initialised, getSettings() function is called first which checks if the user is logged in or not. If the user is not logged in then it returns, else an ajax call is made to the server to get the user settings from the server.

The endpoint used to fetch User Settings is :

BASE_URL+'/aaa/listUserSettings.json?access_token=ACCESS_TOKEN'

where BASE_URL is either the standard server i.e http://api.susi.ai/ or the custom server user used while logging in.

The server returns a JSON object with the existing settings stored for that user

The UserPreferenceStore has a _defaults object which stores all the user settings and is initialised with default values. The store listens to ActionTypes.INIT_SETTINGS event which is triggered by initialiseSettings and the settings are updated in the UserPreferenceStore.

Once the settings are updated in UserPreferencesStore, the corresponding changes are emitted which trigger the update of all the components using the values present in UserPreferenceStore.

Pushing the User Settings to Server

Whenever the user changes any settings, apart from updating them locally within the UserPreferenceStore, we also have to push the changes to the server.

When user settings are changed, we first find out only those settings which have been changed and send these changed settings to the UserPreferencesStore to update _defaults through settingsChanged action which calls the dispatcher using SETTINGS_CHANGED action type to pass the data to UserPreferencesStore.

where BASE_URL is either the standard server i.e http://api.susi.ai/ or the custom server user used while logging in.

Here, the access_token is also passed in the server call as it is needed by the server to distinguish between logged in and anonymous users. The access_token is stored in cookies when a user logs in and is accessed from cookies whenever required.

This is how user specific data is maintained on the server and is pushed and pulled from the server to maintain the state of the chat app upon login-logout and also across all chat clients without using any local database specific to the clients.

In PSLab we communicate with PSLab Hardware device, to exchange data, i.e we give a command or instruction and it responses accordingly. So this giving and receiving is in terms of packed byte string. Thus, we need some solid knowledge to pack and unpack data. In python communication library, there is struct module available. In JAVA we can use NIO’s ByteBuffer or implement our own functions. In this blog post I discuss both methods.

In Python we have struct module for packing data in byte strings. As different languages interpret data types differently like Java takes 4 bytes for int and C++ takes 2 bytes for int. To send and receive data properly, we pack data in a byte string and unpack on other side with it’s data type properties. In PSLab, we have to communicate with device for various applications like getting calibration data during power up time as raw data doesn’t make much sense until calibration is applied on it.

You also need to take care of order of sequence of bytes like there are generally two types of order in which a sequence of bytes are stored in memory location:

Big – Endian: In which MSB is stored first.

Source: Wikipedia

Little – Endian: In which LSB is stored first.Source: Wikipedia

In Python

The standard sizes and format characters of particular data type can be seen in the image below.

Note: Make sure the bytes array that you provide has same number of bytes as that of the data type that you are trying to unpack. For example: if you want int, bytes array should have 4 bytes as int type in JAVA has 4 bytes. If you want short, bytes array should have 2 bytes as short type in JAVA has 2 bytes.

In Angular, we can use the hidden attribute, to hide and show different components of the page. This blog explains what the hidden attribute is, how it works and how to use it for some common tasks.
In Susper, we used the [hidden] attribute for two kinds of tasks.

To hide components of the page until all the search results load.

To hide components of the page, if they were meant to appear only in particular cases (say only the first page of the search results etc).

Let us now see how we apply this in a html file.
Use the [hidden] attribute for the component, to specify a flag variable responsible for hiding it.
When this variable is set to true or 1, the component is hidden otherwise it is shown.
Here is an example of how the [hidden] attribute is used:

Note that [hidden] in a way simply sets the css of the component as { display: none }, whereas in *ngIf, the component is not loaded in the DOM.
So, in this case unless Display(‘all’) returns true the component is not even loaded to the DOM but if [hidden] is set to true, then the component is still present, only not displayed.
In the typescript files, here is how the two tasks are performed:
To hide components of the page, until all the search results load.

The component is hidden when the query request is just sent. It is then kept hidden until the results for the previously sent query are available.

2. To hide components of the page, if they were meant to appear only in particular cases.
For example, if you wish to show a component like Autocorrect only when you are on the first page of the search results, here is how you can do it:

The Open Event Android project helps event organizers to generator Apps (apk format) for their events/conferences by providing api end point or zip generated using Open Event server. In this android app data is fetched from the internet using network calls to the Open Event server and the data of the event is stored in a database. It is difficult to debug an app with so many network calls and database connectivity. A way to approach this is using Stetho which is very helpful tool for debugging an app which deals with network calls and database.

Using Chrome Developer Tools

1. Open Inspect window

Run stetho initialized app on device or emulator then start Google chrome and type chrome://inspect. You will see you device with your app’s package name. Click on “inspect”2. Network Inspection

Go to Network tab. It will show all network calls. With almost all info like url(path), method, returned status code, returned data type, size, time taken etc.

You can also see preview of image and preview, response of returned json data by clicking on Name.

3. SQLite Database

Go to “Resources” tab and select “Web SQL”. You will see database file(.db). By clicking on database file you will see all tables in that database file. And by clicking on table name you will see data in row-column format for that table.

4. Run queries on SQLite database

Same as above go to “Resources” tab and select “Web SQL”. You will see database file(.db). By clicking on database file you will see console on right side, where you can run queries on SQLite database. Example,

SELECT*FROMtracks;

5. Shared Preferences Inspection

Go to “Resources” tab and select “Local Storage”. You will show all files that your app used to save key-value pairs in shared preference and by clicking on file you will see all key-value pairs.

6. Element(View/Layout) Inspection

Go to “Elements” tab. You will see top layout/view in view hierarchy. By clicking it you will see child layout/view of that layout/view. On hover on layout/view you view will be inspected in your device/emulator.

In this blog the most important have been put forward, but there are still some nice stuff available,like:

An integration with JavaScript Console : Enables JavaScript code execution that can interact with the application

Dumpapp : It allows an integration higher than the Developer Tools, enabling the development of custom plugins.

By now, you must have realized that stetho can significantly improve your debugging experience. To learn more about stetho, refer to