Code on demand with REST

Code on demand

In the paper Architectural Styles and the Design of Network-based Software Architectures by Roy Thomas Fielding, REST is defined. Today, when people think of REST, they often associate it with CRUD operations, more or less. However, one of the properties defined in the paper is ‘Code on Demand,’ where the client can request a script or binary from the server (similar to what happens when a browser requests JavaScript files to extend the behavior of a web page).

It’s nice, but it’s not exclusive to the web world. Take a look at this example in Qt:

import QtQuick
import QtQuick.Controls 2.5

Page {
    id: page
    Button {
        text: "load"
        anchors.bottom: parent.bottom
        anchors.horizontalCenter: parent.horizontalCenter
        onClicked: {
            loader.source = new URL("https://server/test.qml")
        }
    }

    Loader {
        id: loader
        anchors.verticalCenter: parent.verticalCenter
        anchors.horizontalCenter: parent.horizontalCenter
    }
}

When you click the button, we load:

import QtQuick
import QtQuick.Controls 2.5

Item {
    anchors.fill: parent

    Column {
        anchors.fill: parent
        TextField {
            width: dp(100)
            placeholderText: "Write here"
        }
        Button {
            text: "Ok"
            onClicked: {
            }
        }
    }
}

I think that the power of code on demand is sometimes underrated, yet we have the tools to leverage it. Please try to use it in a real case.

Qml – Copy And Paste

Sometimes in mobile applications is helpful can copy text between applications (i.e. wifi password or simply text). With a simple Text is impossible to do the copy action; it is possible using the QClipBoard, so we have to use a bit of C++.

In my example, we see how to copy the text from a ListItem and past where we want. Start looking at the Qml code:

App {
    NavigationStack {

        Page {
            title: qsTr("Main Page")

            AppToolTip {
                 id: copyTip
                 text: "Copied"
            }

            AppListView {
                id: listView
                anchors.fill: parent

                delegate: SimpleRow {
                    item: modelData
                    showDisclosure: false
                    onSelected: {
                        copyTip.target = listView.currentItem
                        clipboard.setText(detailText)
                        copyTip.open()
                    }
                }

                model: [
                    { text: "WIFI ID",
                        detailText: "MyWifi" },
                    { text: "WIFI PASSWORD",
                        detailText: "1234562"}
                ]
            }
        }
    }
}

First, in the example I used https://www.felgo.com but you can use also simple Qml. In the code, we define a ListView with a simple model that has two fields: text and detailText. The delegate is SimpleRow that show these two pieces of information (you can use your custom delegate if you prefer).

In the code you can find an AppTooltip that we use to show a “Copied” message after we copied the text.

How do we copy the text? Simple we call the function setText of the clipboard object.

What’s a clipboard?

#ifndef MOBILECLIPBOARD_H
#define MOBILECLIPBOARD_H

#include <QObject>

class MobileClipBoard : public QObject
{
    Q_OBJECT
public:
    explicit MobileClipBoard(QObject *parent = nullptr);
    Q_INVOKABLE void setText(const QString &from);
    Q_INVOKABLE QString text();
};

#endif // MOBILECLIPBOARD_H

In the class MobileClipBoard we have two methods invocable from the Qml side. Let’s see what those methods do:

#include <QClipboard>
#include <QApplication>
#include "mobileclipboard.h"

MobileClipBoard::MobileClipBoard(QObject *parent) : QObject(parent)
{

}

void MobileClipBoard::setText(const QString &from)
{
    QClipboard *clipboard = QApplication::clipboard();
    clipboard->setText(from);
}

QString MobileClipBoard::text()
{
    QClipboard *clipboard = QApplication::clipboard();
    return clipboard->text();
}

In the setText get the reference to the system clipboard and set the text in the clipboard.

The text() method simple return the text within the system clipboard.

The last point, bind the C++ world with the Qml side:

 MobileClipBoard clipboard;

felgo.qmlEngine()->rootContext()->setContextProperty("clipboard", &clipboard);

We declare a MobileClipboard and pass it to the root QQmlContext, so it can be used in the Qml side.

You can find the code here https://github.com/niqt/mobileclipboard

Note: English is not my native language, so I’m sorry for some errors. I appreciate it if your correct me.

QML vs SwiftUI (Part 3)

In this article we’ll see the different use of the lists that is a very most used components in the mobile apps. We starting with SwiftUI, code the example show how create a simple list and the right swipe action to delete a row.

struct ContentView: View {
    @State var names = ["Albert", "Tom", "Jeff", "Jennifer", "Steve", "Bob"]
    var body: some View {
        List {
            ForEach(names.indices, id: \.self) { index in
                Text(self.names[index]) // Delegate
            }
            .onDelete { (indexSet) in
                self.names.remove(atOffsets: indexSet)
            }
        }
    }
}



The list is created with the keyword List, with For each for every elements of the array names is created an object Text that show the single name. If the model is more complex that a simple list of name and we have to show also an image we can add in the For each block the Image object.

The instruction “id: .self” is necessary to identify every single row in unique way, in this case this identifier is the index of the array. Other important keyword is “@State” with this we say to SwiftUi to monitoring the variable names and update the ui when it changes.

In the on Delete function we do the action the we want doing the right swipe, in this case delete the element. Before to switch to QML, we see an example a bit more complex:

struct People: Identifiable {
    var id = UUID()
    var name: String
    var image: String
}struct ContentView: View {
    @State var peoples = [People(name:"Albert", image: "albert.png"), People(name: "Tom", image: "tom.png"),People(name: "Jeff", image:"jeff.png"),People(name: "Jennifer",image: "jennifer.png"), People(name: "Steve", image: "steve.png"), People(name: "Bob", image: "bob.png")]
    var body: some View {
        List {
            ForEach(peoples, id: \.id) { people in
                HStack {
                    Text(people.name)
                    Image(people.image)
                }
            }
            .onDelete { (indexSet) in
                self.peoples.remove(atOffsets: indexSet)
            }
        }
    }
}



In this case we have the struct People that implements the protocol Identifiable, so we have am unique identifier for any instance of the struct. In the ForEach we now use it do identify the row also added a horizonthal stack to create a row with text and image. Now see that same example in QML:

ListView {
    id: listView
    anchors.fill: parent
    model: ListModel {
        ListElement { img: "bob.png"; name: "Bob" }
        ListElement { img: "jennifer.png"; name: "Jennifer" }
        ListElement { img: "tom.png"; name: "Tom" }
        ListElement { img: "denise.png"; name: "Denise" }
    }
    delegate: SwipeDelegate {
        id: swipeDelegate
        text: model.name
        width: parent.width
        
        ListView.onRemove: SequentialAnimation {
            PropertyAction {
                target: swipeDelegate
                property: "ListView.delayRemove"
                value: true
            }
            NumberAnimation {
                target: swipeDelegate
                property: "height"
                to: 0
                easing.type: Easing.InOutQuad
            }
            PropertyAction {
                target: swipeDelegate
                property: "ListView.delayRemove"
                value: false
            }
        }
        
        contentItem: Item {
            RowLayout {
                Text {
                    text: swipeDelegate.text
                    font: swipeDelegate.font
                    elide: Text.ElideRight
                    visible: swipeDelegate.text
                    horizontalAlignment: Text.AlignLeft
                    verticalAlignment: Text.AlignVCenter
                }
                Image {
                    source: model.img
                    visible: swipeDelegate.text
                    horizontalAlignment: Text.AlignLeft
                    verticalAlignment: Text.AlignVCenter
                }
            }
        }
        
        swipe.right: Label {
            id: deleteLabel
            text: qsTr("Delete")
            color: "white"
            verticalAlignment: Label.AlignVCenter
            padding: 12
            height: parent.height
            anchors.right: parent.right
            
            SwipeDelegate.onClicked: listView.model.remove(index)
            
            background: Rectangle {
                color: deleteLabel.SwipeDelegate.pressed ? Qt.darker("tomato", 1.1) : "tomato"
            }
        }
    }
}



In this case the QML is a bit more complex because we have to customize the label to have the same look & feel of iOS but in QML we don’t need to use any “@State” keyword to force the gui update.

At the end I think that it’s simple for QML developer to use SwiftUI, a lot of things are similar and both the languages ​​are declaratives. Instead I think that for iOS developer is not simple to use both, is necessary more experience in the declarative world.

QML vs Swift (part 2)

In this part we’ll see how use the Button in both the languages.

In QML we define the button in this way:

Button {  text: "A button"  id: control  onClicked: {
   // Your action  }}



Where in the “text” property we set the label of the button and in the onClicked is executed what we need when the button is tapped/clicked. Instead in SwiftUI we have:

Button(action: {       // Your action
      }){
        Text("button")
             
      }



For the SwiftUI button the code to execute when the user clicks the button go in the action block. Instead for the property about the text can be changed modifying the properties of the object Text. A example to customization the button with QML:

Button {
    text: "A button"
    id: control

    onClicked: {
        
    }
    contentItem: Text {
            text: control.text
            font: control.font
            opacity: enabled ? 1.0 : 0.3
            color: control.down ? "#17a81a" : "#21be2b"
            horizontalAlignment: Text.AlignHCenter
            verticalAlignment: Text.AlignVCenter
            elide: Text.ElideRight
    }
    
    background: Rectangle {
        implicitWidth: 100
        implicitHeight: 25
        border.width: control.activeFocus ? 2 : 1
        border.color: "#888"
        radius: 40
        gradient: Gradient {

            orientation: Gradient.Horizontal
            GradientStop { position: 0 ; color: control.pressed ? "red" : "red" }
            GradientStop { position: 1 ; color: control.pressed ? "blue" : "blue" }
        }
    }
}



To change the properties of the text we must assign an Text Object to the contenrItem (in this case QML and SwiftUI are similar) and to change the bacground we can assign a rectangle with solid color or with gradient. It’s possible also use other object (i.e. image) for the background. A example to customization the button with SwiftUI:

Button(action: {}) {
            Text("Button")
                .fontWeight(.bold)
                .font(.title)
                .padding()
                //.background(Color.red)
                .background(LinearGradient(gradient: Gradient(colors: [Color.red, Color.blue]), startPoint: .leading, endPoint: .trailing))
                .cornerRadius(40)
                .foregroundColor(.white)
                .padding(10)
        }



In SwiftUI we change the background color (solid or not) modifying only the properties of the Text object because the Text object is used to “show” the button. If we want use an image for the button we must replace the Text object with the Image object.

QML VS. SwiftUI (part 1)

In this series I’ll show the difference between QML and SwiftUI. Both are declarative language, the first on is part of the Qt cross-platform library, the second is from Apple, introduced in the last summer.

The idea that is at the base of these languages is simplify the design of the GUI, with the dream that the designer can draw the interface with tools as Photoshop, Sketch or gimp and with some plugin have the code in some programming language, for both the languages we have some attempt in this direction. Done this introduction, let’s start to see a bit of code.

// QML TEXT
import QtQuick 2.12
import QtQuick.Window 2.12Window 
{
   title: qsTr("Hello World")   
   Text {     
       id: name     
       text: qsTr("text")     
       anchors.verticalCenter: parent.verticalCenter
       anchors.horizontalCenter: parent.horizontalCenter     
       font.family: "Helvetica [Cronyx]"    
    }
}



In the previous code, we show a the text “text” centered vertically and horizontally in window. To default in QML the object are positioned in the left/top corner.

In SwiftUI we have:

import SwiftUI

struct ContentView: View {
    var body: some View {
           Text("Hello, World!")
           .fontWeight(.bold)
    }
}



In SwiftUI the widgets are showed already centered in the View, so we have not specify the alignment how in QML, but if we want the Text in the left/top corner we must specify:

import SwiftUI

struct ContentView: View {
    var body: some View {
        VStack {
            HStack{
                Text("Hello, World!")
                .fontWeight(.bold)
                Spacer()
            }
            Spacer()
        }
    }
}



In the HStack (horizontal stack) we have the Text and the Spacer that fill the space not covered from the Text, so the Text is pushed on the left, in dual way for the Vertical Stack (VStack) the Spacer push on top the HStack.

The first visible difference between QML and SwiftUI is how the properties are set for the objects, in QML we have propertyName: value within the {} block of the element, instead in SwiftUI ther properties are set with .property after the {} block (when present).