Felgo 2.17.0 introduces Firebase Cloud Storage to store local files in the cloud easily & fast. You can use it to create photo or document sharing apps without any server-side code, or even the next Facebook? It also adds downloadable resources at runtime to reduce initial package size, or to load specific resources only on demand. FileUtils give you convenient access to the native device file system. You can check out two new app demos for using C++ with QML, use new Qt modules with Felgo Live and much more. This is a big update, don’t miss it!
New Firebase Storage to Upload Local Files to the Cloud
With the new FirebaseStorage item you can upload files to the Firebase Cloud Storage. It uploads local files to the cloud file system and returns the public download URL. With Firebase, you can create content sharing apps like Facebook or Snapchat without additional server-side code.
Examples for local files you can upload are:
- Pictures captured with the camera using NativeUtils::displayCameraPicker().
- Local pictures selected with NativeUtils::displayImagePicker().
- Project assets using relative URLs with Qt::resolvedUrl().
- Local files on the file system obtained with one of the FileUtils functions.
- Videos, audio files, etc…
Here is a code example, that shows how to upload an image taken with the camera. After the image is uploaded, we display it in the app.
NOTE: This example uses a public Firebase storage instance, don’t upload any sensitive data!
import QtQuick 2.0
import Felgo 3.0
App {
NavigationStack {
Page {
title: "Firebase Storage"
FirebaseStorage {
id: storage
config: FirebaseConfig {
id: customConfig
projectId: "v-play-live-client-test-db"
databaseUrl: "https://v-play-live-client-test-db.firebaseio.com"
storageBucket: "v-play-live-client-test-db.appspot.com"
//platform dependent - get these values from the google-services.json / GoogleService-info.plist
apiKey: Qt.platform.os === "android" ? "AIzaSyD3Pmw89NHhdG9nGIQWwaOB55FuWjcDSS8" : "AIzaSyCheT6ZNFI4mUwfrPRB098a08dVzlhZNME"
applicationId: Qt.platform.os === "android" ? "1:40083798422:android:ed7cffdd1548a7fa" : "1:40083798422:ios:ed7cffdd1548a7fa"
}
}
AppFlickable {
anchors.fill: parent
Column {
width: parent.width
anchors.margins: dp(12)
AppButton {
text: "Capture image + upload"
onClicked: nativeUtils.displayCameraPicker()
}
AppText {
id: status
text: "Idle"
}
// this will display the image after it's uploaded
AppImage {
id: img
width: parent.width
fillMode: AppImage.PreserveAspectFit
autoTransform: true
}
}
}
}
}
Connections {
target: nativeUtils
onCameraPickerFinished: {
if(accepted) {
//picture taken with camera is stored at path - upload to Firebase Storage
storage.uploadFile(path, "test-image" + Date.now() + ".png", function(progress, finished, success, downloadUrl) {
if(!finished) {
status.text = "Uploading... " + progress.toFixed(2) + "%"
} else if(success) {
img.source = downloadUrl
status.text = "Upload completed."
} else {
status.text = "Upload failed."
}
})
}
}
}
}
Download Resources at Runtime
DownloadableResource allows downloading app and game assets on demand during runtime. You no longer need to include all resources like images or videos in the app binary. This results in smaller downloads from the app stores. Cut down your 500MB training app to e.g. only 30MB, and let the user download your workout videos on demand!
The most popular use cases for downloadable packages are:
- You want to keep your app store binary as small as possible for the first download, to increase the download numbers of your app or game with a smaller download size.
- You want to download additional content packages after in-app purchases.
- Keep your initial app size below the store limits:
- On Google Play, your initial apk size must be below 100MB, after that you need to use Android expansion files. To avoid that, you can just use DownloadableResource and download the additional files at a later time.
- On iOS, your initial binary size limit is 150MB for mobile network downloads. If your binary is bigger, the user can only download your app over WiFi. Downloading additional resources later also helps you to avoid this limit.
- With the Felgo DownloadableResource component, you can create a cross-platform solution to work with downloadable resources, that works for both iOS AND Android. It even works on Desktop too, with a single source code for all platforms! This way, you do not need to deal with Android expansion files and can create a working solution for all platforms instead.
Here is a small example how you could use it: it downloads and extracts a zip archive including an image to the default location after 5 seconds. Then it replaces the placeholder image with the downloaded image:
import Felgo 3.0
import QtQuick 2.0
import Felgo 3.0
App {
// uncomment this to remove the resources on startup, so you can test the downloading again
//Component.onCompleted: resource1.remove()
// after 5 seconds, we download the resources
Timer {
running: true
interval: 5000
onTriggered: {
resource1.download()
}
}
NavigationStack {
Page {
title: "Downloadable Resource"
DownloadableResource {
id: resource1
extractAsPackage: true // true for zip archives
source: "https://felgo.com/web-assets/girl.zip"
}
AppImage {
width: parent.width
fillMode: AppImage.PreserveAspectFit
// as long as the resource file is not available, we use a placeholder image
// (the example placeholder is actually also from a web url, to be usable with the web editor)
// if the resource is available, we get the extracted file url and set it as new image source
// on your next app start (or live reload) the resource will be available immediately and not downloaded again
source: resource1.available ? resource1.getExtractedFileUrl("girl.jpg") : "https://felgo.com/web-assets/balloon.png"
}
}
}
}
You have full information about the download, with properties like status, progress and available. You know exactly when resources are available or when to show a loading indicator.
DownloadableResource can load files from any HTTP(S) web addresses. You can add a secret to protect and restricts downloads to your app or game only. You can download single files or entire .zip-archives, which are automatically extracted.
Once a resource is downloaded, you can use it like any other asset. On your next app start, the resource will be available right away.
FileUtils Class for Cross-Platform Native File Access
You can use the new FileUtils context property to open, read, copy or delete files and folders on any device.
This is an example to download a PDF file and then open it with the native PDF viewer application, using FileUtils::openFile():
import Felgo 3.0
import QtQuick 2.0
import Felgo 3.0
App {
id: app
// uncomment this to remove the resources on startup, so you can test the downloading again
//Component.onCompleted: pdfResource.remove()
NavigationStack {
Page {
title: "Download PDF"
Column {
anchors.centerIn: parent
AppButton {
text: "Download / Open"
onClicked: {
if(pdfResource.available) openPdf()
else pdfResource.download()
}
}
AppText {
text: "Status: " + pdfResource.status
}
}
}
}
DownloadableResource {
id: pdfResource
source: "http://www.orimi.com/pdf-test.pdf"
storageLocation: FileUtils.DocumentsLocation
storageName: "pdf-test.pdf"
extractAsPackage: false
// if the download is competed, available will be set to true
onAvailableChanged: if(available) openPdf()
}
function openPdf() {
// you can also open files with nativeUtils.openUrl() now (for paths starting with "file://")
//nativeUtils.openUrl(pdfResource.storagePath)
// with Felgo 2.17.0 you can also use fileUtils.openFile()
fileUtils.openFile(pdfResource.storagePath)
}
}
Two New App Examples How to Integrate C++ with QML
You can check out and copy parts from two brand-new app demos that show how to integrate C++ with QML!
Exposing a C++ Class to QML
The first example shows the different forms of C++ and QML integrations. This example is the tutorial result from How to Expose a Qt C++ Class with Signals and Slots to QML.
Path to the app demo: <Path to Felgo>/Examples/Felgo/appdemos/cpp-qml-integration
Display Data from C++ Models with Qt Charts
The second example shows how to combine a C++ backend that provides the model data for a frontend created in QML. The data is displayed with QML with Qt Charts for both 2D and 3D charts. It also includes shader effects, because, why not?
Path to the app demo: <Path to Felgo>/Examples/Felgo/appdemos/cpp-backend-charts-qml
Live Client Support for Bluetooth, NFC and Pointer Handlers
The Felgo Live Client now supports the Qt modules for Bluetooth, NFC and Pointer Handlers.
Network Adapter Selection in Live Server
You can now change the used network adapter in the Live Server. This fixes a possible issue that the mobile Live Client stalls in the “Connected – Loading Project” screen. If you also face this issue, here is how to fix it.
Open the settings screen from the lower left corner of your Live Server:
Now you can change the selected network adapter:
This IP is sent to the Live Client to establish the connection. You can try to select different adapters, the IP of the Live Server and Live Client should be in the same network.
More Features, Improvements and Fixes
- Create feature-rich Augmented Reality (AR) apps & games with our new Wikitude Plugin. You will read more on this amazing addition in another blog post coming soon. Stay tuned!
- You can now set a timeout for your Felgo Multiplayer games using the new property VPlayMultiplayer::socketTimeoutMs. This is useful to prevent clients with slow connections from slowing down the entire game.
- Navigation drawer entries add setting the color of the text, icon and background in default, pressed and active state. To do so, the SimpleRow::style offers the additional selectedTextColor and activeBackgroundColor properties. In addition, the text and icon of tabs for TabControl or AppTabButton may now use a different color while being pressed.
- Users of your app or game including Felgo Game Network can now delete their account with a simple button found in their user profile. To deactivate this feature in your app, you can set the SocialView::deleteAccountEnabled or the VPlayGameNetworkView::deleteAccountEnabled property to false. If you hide the button or use a customized profile, you can still provide this feature with the VPlayGameNetwork::deleteUser() function.
- TexturePackerAnimatedSpriteVPlay gains some improvements: You can now change the current frame while the animation is paused (i.e. if paused is true and running is also set to true). The overall performance also increased, as frames are no longer re-drawn if the animation is not running or paused.
You can do this either by assigning currentFrame or by calling advance(). - Selecting an image on iOS with NativeUtils::displayCameraPicker() or NativeUtils::displayImagePicker() now also loads photos saved as Apple’s new HEIC image file format.
- The Publishing Felgo Games & Apps guide lists additional notes about Google Play Privacy Guidelines.
- New convenience properties for setting density-independent fontSize with the App::sp() function for AppText::fontSize, AppTextEdit::fontSize and AppTextInput::fontSize.
- Fixes a potential crash and function evaluating warnings during object destruction if a Navigation and NavigationStack is used from within a Loader item.
How to Update Felgo
Test out these new features by following these steps:
- Open the Felgo SDK Maintenance Tool in your Felgo SDK directory.
- Choose “Update components” and finish the update process to get this release as described in the Felgo Update Guide.
If you haven’t installed Felgo yet, you can do so now with the latest installer from here. Now you can explore all of the new features included in this release!
For a full list of improvements and fixes to Felgo in this update, please check out the change log!
More Posts Like This
How to Make Cross-Platform Mobile Apps with Qt – Felgo Apps
Release 2.16.1: Live Code Reloading with Custom C++ and Native Code for Qt
Release 2.16.0: iPhone X Support and Runtime Screen Orientation Changes
Release 2.15.1: New Firebase Features and New Live Code Reloading Apps | Upgrade to Qt 5.10.1 & Qt Creator 4.5.1