Skip navigation
All Places > AppStudio for ArcGIS > Blog
1 2 3 Previous Next

AppStudio for ArcGIS

83 posts

1. Introduction

 

 

This blog is about the Javascript "for of" loop and the Javascript destructuring assignment.

 

These are part of ECMAScript 6 features that were included in the ECMAScript 7 update of AppStudio 3.3 and Qt 5.12.1.

 

We explore how these features may help with your AppStudio apps.



2. The "for of" loop

 

 

Traditionally, to loop through an array we need to use an index variable (e.g. i):

 

var census = [
    { country: "France", population: 66.99 },
    { country: "Australia", population: 24.6 },
    { country: "United States", population: 327.2 }
]
for (var i = 0; i < census.length; i++) {
    var item = census[i]
    console.log( item.country, item.population )
}

 

 

In ECMAScript 6, we can use "for of" loop to make this easier:

 

let census = [
    { country: "France", population: 66.99 },
    { country: "Australia", population: 24.6 },
    { country: "United States", population: 327.2 }
]
for ( let item of census ) {
    console.log( item.country, item.population )
}

 

 

The "for of" loop is new in ECMAScript 6 and created specifically for looping through arrays and, in general, Javascript iterators.

 


3. Unpacking object values

 

 

Since we know each item have country and population fields, we can use the new ECMAScript destructuring assignment operator to extract it:

 

let census = [
    { country: "France", population: 66.99 },
    { country: "Australia", population: 24.6 },
    { country: "United States", population: 327.2 }
]
for ( let item of census ) {
    let { country, population } = item
    console.log( country, population )
}

 

 

We can even mix destructuring assignment with "for of":

 

let census = [
    { country: "France", population: 66.99 },
    { country: "Australia", population: 24.6 },
    { country: "United States", population: 327.2 }
]
for ( let { country, population } of census ) {
    console.log( country, population )
}

 

 

You can get creative by combining this with arrow functions:

 

let census = [
    { country: "France", population: 66.99 },
    { country: "Australia", population: 24.6 },
    { country: "United States", population: 327.2 }
]
let orderByPopulationDesc = (a, b) => -(a.population - b.population)
for ( let { country, population } of census.sort( orderByPopulationDesc ) ) {
    console.log( country, population )
}



4. Unpacking arrays values

 

 

Similarly, you can unpack arrays using the following destructuring assignment syntax:

 

let [ year, month, day ] = [ "2019", "11", "07" ]
console.log(year) // 2019
console.log(month) // 11
console.log(day) // 07

 

 

 

5. Unpacking regular expression capture groups

 

 

When you use "str.match" with regular expression you get an array of strings. You get additional strings in the array for each capture group. You need to process the array to extract each capture group, e.g.

 

let str = "2019-11-07"
let m = str.match( /(\d{4})-(\d{2})-(\d{2})/ )
console.log( m.length ) // 4
console.log( m[0] ) // 2019-11-07
console.log( m[1] ) // 2019
console.log( m[2] ) // 11
console.log( m[3] ) // 07

 

 

The Javascript destructuring assignment here helps eliminate the need for having an intermediate array variable. The code becomes much shorter and clearer:

 

let str = "2019-11-07"
let [ , year, month, day ] = str.match(/(\d{4})-(\d{2})-(\d{2})/)
console.log( year ) // 2019
console.log( month ) // 11
console.log( day ) // 07

 

 

 

6. Using destructuring assignment with SQL

 

 

In the following example, we see that the destructuring assignment is useful in unpacking results from SQL queries:

 

db.open()
db.query( "CREATE TABLE IF NOT EXISTS countries (country TEXT, population NUMBER)" )
db.query( "INSERT INTO countries VALUES ( 'France', 66.99 )" )
db.query( "INSERT INTO countries VALUES ( 'Australia', 24.6 )" )
db.query( "INSERT INTO countries VALUES ( 'USA', 327.2 )" )
let q = db.query( "SELECT * FROM countries" )
for ( let ok = q.first() ; ok ; ok = q.next() ) {
    let { country, population } = q.values
    console.log( country, population )
}
q.finish()
db.close()

 

 

We can use "for of" syntax here if we make use of Javascript iterator and Javascript generator syntax:

 

function* queryIterator(q) {
    for ( let ok = q.first() ; ok ; ok = q.next() )
        yield q.values
}

db.open()
db.query( "CREATE TABLE IF NOT EXISTS countries (country TEXT, population NUMBER)" )
db.query( "INSERT INTO countries VALUES ( 'France', 66.99 )" )
db.query( "INSERT INTO countries VALUES ( 'Australia', 24.6 )" )
db.query( "INSERT INTO countries VALUES ( 'USA', 327.2 )" )
let q = db.query( "SELECT * FROM countries" )
for ( let { country, population } of queryIterator( q ) ) {
    console.log( country, population )
}
q.finish()
db.close()

 

 

We will talk more about Javascript iterators and Javascript generators in a future blog.

 

 

7. Conclusion

 

 

This blog introduces Javascript "for of" loop and Javascript destructuring assignments.

 

These are some of the new Javascript ECMAScript 7 syntax improvements in AppStudio 3.3 and Qt 5.12.1 that can help you improve your code readability, clarity by helping you write shorter, easier to maintain code.

 

These syntax improvements complement other Javascript improvements, such as Javascript iterators, Javascript generators and Javascript promises.

 

We will introduce Javascript iterators and Javascript generators in a future blog.

 

We will revisit Javascript promises and how they fit with all these Javascript syntax improvements.

Introduction

 

 

If you're a parent to daughters you may know what I mean when I talk about obsessions with Unicorns. When we walk pass any book or toy featuring unicorns the our girls' eyes light up with that mandatory question, "can we buy that?". My response is "No!". Please, no more, no, N-O, No!

 

This blog is really about TextInput validators:

 

  • InputMask
  • IntValidator
  • DoubleValidator
  • RegExpValidator
  • InputValidator (in this example, we will show you how to say "No" to unicorns!)

 

The first 4 is from Qt's runtime. The last is from AppStudio's AppFramework.

 

 

InputMask

 

 

TextField {
    inputMask: "999-AAA"
    placeholderText: qsTr("Type in a license plate of the pattern 999-AAA")
    text: "123-XYZ"
    color: acceptableInput ? "green" : "red"
    selectByMouse: true
}

View full InputMaskTest.qml on GitHub Gist.

 

 

InputMask is a property on TextInput components such as TextField. It allows us to quickly define acceptable text input. In the above example we allow 6 character license plates that begin with 3 digits, followed by a dash and finishing with 3 characters. When acceptable input is entered the text field changes from "red" to "green" and the user can submit the input.

 

The InputMask has the following features:

  • When the field is "empty" you'll see placeholders for symbols like hyphen ('-'), you will not see the placeholder text
  • When you type, you do not need to type the fixed symbols, e.g. hyphen ('-')
  • The code is very short

 

 

https://doc.qt.io/qt-5/qml-qtquick-textinput.html#inputMask-prop

https://doc.qt.io/qt-5/qlineedit.html#inputMask-prop

 

 

IntValidator

 

 

TextField {
    validator: IntValidator {
        bottom: 25
        top: 75
    }
    placeholderText: qsTr("Type in an integer between 25 and 75")
    text: "34"
    color: acceptableInput ? "green" : "red"
    selectByMouse: true
}

View full IntValidatorTest.qml on GitHub Gist.

 

 

IntValidator is a QML component that can be assigned as a TextInput validator. It allows us to quickly define acceptable numerical input. In above example we allow any integer between 25 and 75. When acceptable input is entered the text field changes from "red" to "green" and the user can submit the input.

 

The IntValidator has the following features:

  • When the field is empty you can see the placeholder text
  • You cannot type more than the number of characters hinted by the IntValidator (e.g. in the above example you cannot type more than two digits)

 

https://doc.qt.io/qt-5/qml-qtquick-intvalidator.html

 

 

DoubleValidator

 

 

TextField {
    validator: DoubleValidator {
        bottom: 25.0
        top: 75.0
    }
    placeholderText: qsTr("Type in a number between 25.0 and 75.0")
    text: "34.5"
    color: acceptableInput ? "green" : "red"
    selectByMouse: true
}

View full DoubleValidatorTest.qml on GitHub Gist.

 

 

DoubleValidator is a QML component that can be assigned as a TextInput validator. It allows us to quickly define acceptable numerical input. In above example we allow any number between 25.0 and 75.0. When acceptable input is entered the text field changes from "red" to "green" and the user can submit the input.

 

The DoubleValidator has the following features:

  • When the field is empty you'll see the placeholder text
  • You can type in any length (because decimal points are allowed)

 

https://doc.qt.io/qt-5/qml-qtquick-doublevalidator.html

 

 

RegExpValidator

 

 

TextField {
    validator: RegExpValidator {
        regExp: /[0-9]{3}-[A-Za-z]{3}/
    }
    placeholderText: qsTr("Type in a license plate of the pattern 999-AAA")
    text: "123-XYZ"
    color: acceptableInput ? "green" : "red"
    selectByMouse: true
}

View full RegExpValidatorTest.qml on GitHub Gist.

 

 

RegExpValidator is a QML component that can be assigned as a TextInput validator. It allows us to quickly define acceptable input. In the above example, we allow for license plates that begin with a 3 digit number, followed by a dash and ending with 3 letters.

 

RegExpValidator has the following features:

  • When the field is empty you'll see the placeholder text (different than InputMask)
  • You must type the hyphen, it won't be automatically typed for you (different than InputMask)
  • The regular expression is significantly more complex to implement and maintain

 

 

https://doc.qt.io/qt-5/qml-qtquick-regexpvalidator.html

 

 

InputValidator

 

 

TextField {
    validator: InputValidator {
        validate: function (input, position) {
            if (input.match(/unicorn/)) {
                return InputValidator.Invalid
            }

            while (input.match(/canine/)) {
                input = input.replace(/canine/, 'dog')
                position -= 6
                position += 3
            }

            let state = InputValidator.Intermediate
            if (input.endsWith('.')) {
                state = InputValidator.Acceptable
            }

            return { input, position, state }
        }
    }
    placeholderText: qsTr("Type in a sentence ending with a fullstop. Avoid using 'unicorn' and 'canine'!")
    text: "A dog is man's best friend."
    selectByMouse: true
}

View full InputValidatorTest.qml on GitHub Gist.

 

 

InputValidator is a QML component that can be assigned as a TextInput validator. It allows us to supply a Javascript function to be the validator. The Javascript function receives both the original string and position as input. It can return an input state (InputValidator.Invalid, InputValidator.Intermediate or InputValidator.Acceptable). It can also return an object that contains an updated version of the string, position and state. Returning an updated string allows us to implement auto correction. In the above example we forbid the user from typing in "unicorn". It's not allowed! We also forbid the user from typing "canine". If they attempt to type "canine" it gets auto corrected as "dog". The sentence will never be full accepted until the user finishes it with a full stop ".".

 

InputValidator has the following features:

  • When the field is empty you'll see the placeholder text
  • You can prohibit certain input (e.g. we can come up with a word blacklist, e.g. censor offensive words)
  • You can correct / fix input (i.e. implement auto correct)
  • You have full control over the experience
  • Takes more effort to implement your rules

 

 

https://doc.arcgis.com/en/appstudio/api/reference/framework/qml-arcgis-appframework-inputvalidator/

 

 

References

 

 

 

 

Send us your feedback to appstudiofeedback@esri.com

 

Become an AppStudio for ArcGIS developer! Watch this video on how to sign up for a free trial.

 

Follow us on Twitter @AppStudioArcGIS to keep up-to-date on the latest information and let us know about your creations built using AppStudio to be featured in the AppStudio Showcase.

 

The AppStudio team periodically hosts workshops and webinars; please click on this link to leave your email if you are interested in information regarding AppStudio events.

The AppStudio team is hard at work on the next version of AppStudio for ArcGIS (version 4.0). As always there will be technical updates to the software, but with this new version there will also come some significant changes to how we license the software.

 

More details about the new technical features and capabilities coming with AppStudio 4.0 are detailed in this blog post, but here is an overview of the highlights.

  • New 3D Scene Viewer template
  • AppStudio extension for Visual Studio Code (open VS Code from AppStudio, write QML)
  • Support for opening a permission dialog while app is running
  • Preview file before sharing
  • Change language while app is running
  • Updates to JavaScript environment (ECMAScript 7)

If you want access to the AppStudio 4.0 beta visit the AppStudio for ArcGIS Early Adopter Community.

 

Licensing Changes

 

AppStudio is a powerful suite of tools that provides our users an easy to use, yet extremely robust cross-platform app development experience. We want more ArcGIS users to experience the full power of AppStudio, and have access to more templates, layouts, samples, and tools. To give access to more of what AppStudio has to offer, we have decided to make some changes to the license levels.

 

Name Change

First things first, we are changing the name of the licensing levels

 

Original NameNew Name
AppStudio for ArcGIS BasicAppStudio for ArcGIS
AppStudio for ArcGIS StandardAppStudio for ArcGIS Developer Edition

 

Just as before, every ArcGIS organization member with a user type of Creator or GIS Professional will have access to AppStudio for ArcGIS (we’ve dropped “Basic” from the name). If you have an AppStudio for ArcGIS Standard license it will be renamed to AppStudio for ArcGIS Developer Edition. We are also working on making an easier experience to purchase and provision an AppStudio Developer Edition license to the ArcGIS organization of your choice.

 

 

What comes with an AppStudio for ArcGIS license?

 

Previously, the AppStudio Basic license lets you create a native app from one of three templates on appstudio.arcgis.com. This online template experience offered minimal configuration options and required that maps and data be public. At version 4.0 all AppStudio for ArcGIS licenses now includes the AppStudio Desktop application. AppStudio Desktop lets you configure an app from a template, build an app from a layout, or add functionality to an app using code from one of our 70+ live samples. Speaking of code... also included is the ability to write custom code for your app using Qt Creator (installed with desktop) or Microsoft Visual Studio Code (using a new AppStudio extension).

 

After you have created an app using AppStudio Desktop you can upload it to your ArcGIS organization and share it with others in your org using AppStudio Player. An AppStudio app stored in ArcGIS Online is just another item in your organization. And just as you share data, maps, and web apps with others, you can share your AppStudio apps and then run the app using AppStudio Player (more about AppStudio Player below).

 

Note: The app building experience on appstudio.arcgis.com will be retired on August 15th, 2019, see the Q&A below for more information.

 

What comes with an AppStudio for ArcGIS Developer Edition license?

 

The Developer Edition license adds a few key components for more advanced developers or those who want to distribute their apps as a standalone installed app via a public app store or an enterprise deployment. The Developer Edition includes a set of Enterprise templates such as Survey123, AuGeo, and AppStudio Player. Access to the AppStudio cloud Make service is also included with the Developer Edition so you can generate app installation files for iOS, Android, Windows, Mac, and Linux.

 

This table highlights the capabilities of AppStudio editions at version 4.0:

AppStudio
for ArcGIS
AppStudio
Developer Edition
Download and use AppStudio DesktopXX
Convert your ArcGIS web maps into mobile appsXX
Build apps with no coding, using configurable app templatesXX
Extend apps built using the configurable app templatesXX
Create custom apps using your developer skillsXX
Share apps within your ArcGIS organization using AppStudio PlayerXX
Use Cloud Make to build install executables
(Android, iOS, Windows, OS X Linux)
X
Publish to the Apple and Google Play app storesX
Use Mobile Device Management (MDM) systems to share in an EnterpriseX
Access to AppStudio enterprise app templates
(Survey123, QuickCapture, AuGeo, more...)
X
In the future - Create add-ins for Survey123 for ArcGISX

 

We are excited about these new changes to AppStudio and the opportunity to share more of the great tools in AppStudio with a larger audience. We understand that these changes may be disruptive for some of our existing users who have been using the web experience to build apps. Please reach out to us (appstudiofeedback@esri.com) so we can better help you through this license transition.

 

Below is a Q&A to help with some of the common questions we think people might have. If you have other questions, please leave them in the comments section below.

 

Thank You – The AppStudio team


Q & A


What will happen to the app building experience on appstudio.arcgis.com website?

The template based app building tools on appstudio.arcgis.com will be shutdown August 15th, 2019 with the release of AppStudio 4.0. Going forward you will use the tools in AppStudio Desktop to configure an app based on one of the standard templates (Map Viewer, Map Tour, Quick Report). AppStudio Desktop offers many more settings for these templates, so you have more control configuring the look and feel of your app... without writing any code. Some of the settings you can configure in AppStudio desktop include the app color, text color, custom fonts, feedback email, offline map package, and more.

If you have already created apps using the website tools those apps will not go away, you can download and further customize those apps using AppStudio Desktop.


What AppStudio license level has access to generate a build? (access to cloud Make)

A significant change in the licensing is that to generate a standalone install build (suitable for submitting to the app stores) for an app will require an AppStudio Developer Edition license.
Those users who have created apps from the website experience using an AppStudio Basic license will no longer have access to generate a standalone build of their app after August 15th, 2019.


How do I share my app with others using AppStudio Player for ArcGIS?

AppStudio for ArcGIS Player is an amazing tool that can transform how you distribute apps in your organization. Using AppStudio Player is like having a private app store, which you control. You can determine who has access to what apps in your organization and when they get updated.

Here how it works:
1. Create an app using AppStudio Desktop
2. Using AppStudio Desktop upload your app to ArcGIS Online or Enterprise
3. In your portal set the sharing property to share your app with others in your ArcGIS organization. Share it with a group of users, the entire organization, or even the public.
4. The end user of the app downloads AppStudio Player onto their device from the app stores or from the AppStudio website.
5. They login using their username/password for their ArcGIS organization.
6. Next, they download the shared app to the device
7. Now they can run the app as a native application right within AppStudio Player

We are excited to announce the release of AppStudio for ArcGIS 4.0 Beta.  Downloads are available through the Early Adopter Community. We encourage you to participate in the beta program to try out new features, enhancements and report bugs. Your feedback will greatly help us improve AppStudio and deliver a stable, high-performance product to everyone.

 

 

New licensing model

We want more ArcGIS users to experience the full power of AppStudio, and have access to more templates, layouts, samples, and tools. To give access to more of what AppStudio has to offer, we have decided to make some changes to the license levels with the AppStudio 4.0 release.  The changes include:

  • License level name change
    • AppStudio for ArcGIS
    • AppStudio for ArcGIS Developer Edition
  • AppStudio by default now includes the ability to make changes to any app or sample or template and upload to the Player (Previously this required a full standard license).
  • Retiring web-based app building tools on appstudio.arcgis.com
  • Cloud Make service will only be included with AppStudio Developer Edition

 

We are excited about these new changes to AppStudio and the opportunity to share more of the great tools in AppStudio with a larger audience.  We understand that these changes will impact the workflow of some of our existing AppStudio users. Please read this blog post for full details on the new licensing changes:
BLOG: Licensing changes coming in AppStudio for ArcGIS 4.0

 

New 3D Scene Viewer template

We released the 3D Scene Viewer as a sample app in the last release – thank you for all of the great feedback and suggestions. With this release, the 3D Scene Viewer has received many new features, enhancements, UI updates, and more customization options. We are excited to publish it as a configurable template app. Please try out this new template app and let us know what do you want to see in the future release in the comment below or email appstudiofeedback@esri.com.  

 

Notice that Support for Mobile Scene Packages coming soon

 

 

   3D Scene Viewer template

 

AppStudio for ArcGIS extension for Visual Studio Code

Visual Studio Code, an alternative code editor to Qt Creator, has been supported since the last release. We have continued our work on Visual Studio Code integration and have simplified the process of opening the AppStudio project in Visual Studio Code.  A new Editor session has been added in AppStudio Preferences, allowing you to choose Qt Creator or Visual Studio Code as your default code editor. Once your default is set, clicking on the Edit button in the side panel will open your AppStudio in the desired code editor. Please refer to this documentation for using the AppStudio for ArcGIS extension for Visual Studio Code.

 

 

 

Support for opening permission dialog prompt

We are excited to introduce the new Permission singleton and PermissionDialog QML component in the AppFramework Platforms plugin. The Permission singleton can query the permission status. The PermissionDialog component provides the ability to open a dialog prompt to ask for the camera, microphone, storage (Android), location, or background location permission on mobile devices. It can also open the device settings if the user declines the permission prompt.

Note: API references of these new features and enhancements are available in the Qt Creator Help documentation included with the AppStudio Desktop 4.0 (Beta) install.    

 

                                                                           Permission Dialog Sample

 

Notice that a Permission Dialog sample app is available in AppStudio Desktop. You can download the sample app here: AppStudio Desktop 4.0 beta > New App > search for Permission Dialog.

 

Support for previewing and sharing files

We have been actively listening to feedback and suggestions from the community and are happy to announce support for one of the most requested features - previewing and sharing files. We have enhanced the AppFramework clipboard.share(fileURL) method to open an appropriate user interface for a specific file (PDF, image, audio, video, and more), allowing you to preview and share the file.

 

 

                                                                      Share text, URL, or file sample

 

 

Support for changing languages when the app is running

Previously, the language of a localized AppStudio app would be based on the device language. With this release, you can now change app language inside of the app without changing the device language. This is huge as now you can also test your apps without changing phone OS locale and also have the ability to provide the option in UI to switch between languages.

 

Internationalization sample

 

 

Others:

  • Upgraded Qt to version 5.12.3
  • We have ended support for creating Android x86 apps.
  • AppStudio 4.0 will be the last version to support Android 4.4.

 

Getting Started

The beta program is open to anyone – join the Early Adopter Community today to gain access to the latest versions of AppStudio 4.0 Beta.

 

  • AppStudio Desktop- You can download the beta version of AppStudio Desktop 4.0 here.
  • AppStudio Player (iOS)- AppStudio Player 4.0 (Beta) is available via Apple's TestFlight. Please click on this link to download.
  • AppStudio Player (Android) - AppStudio Player 4.0 (Beta) is available via the Android Beta Program. Please go to this link to download.

 

You are now all set to start testing the AppStudio 4.0 Beta!

 

Feedback

Your feedback is much appreciated and will help us to improve the final release of AppStudio for ArcGIS 4.0. For bugs or other issues you may find, please submit a bug report or join the beta forum to provide feedback. You can also send us an email at appstudiofeedback@esri.com.

 

The AppStudio for ArcGIS 4.0 final release is scheduled for late August.  We want to thank everyone who contributes to this release in advance, and we wish you happy testing!

 

Become an AppStudio for ArcGIS developer! Watch this video on how to sign up for a free trial.

 

Follow us on Twitter @AppStudioArcGIS to keep up-to-date on the latest information and let us know about your apps built using AppStudio to be featured in the AppStudio Showcase.

 

The AppStudio team periodically hosts workshops and webinars; please click on this link to leave your email if you are interested in information regarding AppStudio events.

SQuan-esristaff

Sorting QML ListModels

Posted by SQuan-esristaff Employee Jun 19, 2019

1. Introduction

 

 

This blog post discusses sorting the QML ListModel. It's one of my favourite problems to solve. The blog also talks about a Sorting Cities sample app. That sample app implements and demonstrates the QML ListModel sort. The rest of the blog explains how the function works.

 

 

2. Sorting Cities sample app

 

 

 

 

The Sorting Cities sample app is an AppStudio 3.3 app. It comes with five U.S. cities. The user can sort them by city name or by distance to ESRI. The sort order can be either ascending or descending.

 

Item {
    ColumnLayout {
        anchors.fill: parent
        anchors.margins: 10 * AppFramework.displayScaleFactor

        spacing: 10 * AppFramework.displayScaleFactor

        ListView {
            id: listView
            Layout.fillWidth: true
            Layout.fillHeight: true
            model: ListModel {
                id: listModel
                Component.onCompleted: {
                    add( "Hawaii", 21.289373, -157.917480 )
                    add( "Los Angeles", 34.052235, -118.243683 )
                    add( "New York City", 40.730610, -73.935242 )
                    add( "Redlands", 34.0555700, -117.1825400 )
                    add( "Seattle", 47.608013, -122.335167 )
                }
                function add(city, lon, lat) {
                    const esri = QtPositioning.coordinate( 34.0572522, -117.1945814 )
                    const coord = QtPositioning.coordinate( lon, lat )
                    const distance = coord.distanceTo( esri )
                    append( { city, coord, distance } )
                }
            }

            delegate: ItemDelegate {
                text: `${city} ${(distance / 1000).toFixed(2)} km`
            }
        }

        Button {
            text: qsTr("  City  ")
            onClicked: listModelSort( listModel,
                                      (a, b) => a.city.localeCompare(b.city) )
        }

        Button {
            text: qsTr("  City (Desc)  ")
            onClicked: listModelSort( listModel,
                                      (a, b) => - a.city.localeCompare(b.city) )
        }

        Button {
            text: qsTr("  Distance to Esri  ")
            onClicked: listModelSort( listModel,
                                      (a, b) => (a.distance - b.distance) )
        }

        Button {
            text: qsTr("  Distance to Esri (Desc)  ")
            onClicked: listModelSort( listModel,
                                      (a, b) => - (a.distance - b.distance) )
        }
    }

    function listModelSort(listModel, compareFunction) {
        let indexes = [ ...Array(listModel.count).keys() ]
        indexes.sort( (a, b) => compareFunction( listModel.get(a), listModel.get(b) ) )
        let sorted = 0
        while ( sorted < indexes.length && sorted === indexes[sorted] ) sorted++
        if ( sorted === indexes.length ) return
        for ( let i = sorted; i < indexes.length; i++ ) {
            listModel.move( indexes[i], listModel.count - 1, 1 )
            listModel.insert( indexes[i], { } )
        }
        listModel.remove( sorted, indexes.length - sorted )
    }
}

View the full SortingCities.qml on Github Gist.

 

 

3. ListModel vs Array

 

 

If you compare the ListModel QML Type with the Javascript Array type, you'll find that Array has better methods. In particular, Array has a sort method whilst ListModel does not.

 

When you assign an Array to a QML visual component, e.g. ListView, the Array behaves like a scalar value. If you were to push new records onto the Array the ListView will not update. There is no property binding between pushes to the Array and the ListView. To refresh the ListView you need to reassign the Array every time the Array changes. This will cause the ListView to repaint. This could lead to bad user experience. For instance, I may be writing an application that collates results from an online search. The results may arrive through a series of NetworkRequests to REST API end points. Each update will cause the ListView to repaint and scroll back to the top. This will be particularly annoying to the user if the user was already reading and scrolling through the results.

 

The experience is different with ListModels. When you assign a ListModel to a ListView you don't need to assign it again. When you append new records to the ListModel, the ListView will receive sufficient change notification and will automatically update to reflect that new records have arrived. If the ListModel were to change whilst the user was reading and scrolling through the ListView, the current scrolled position and the selected item will be unchanged. The user would not experience any negative user experience with the ListView.

 

In short, for good user experience, we prefer ListModels over Arrays.

 

 

4. Compare Functions as Arrow Functions

 

 

Array sort (and QML ListModel sort) requires a compare function. A compare function takes any two elements from the Array (or ListModel) and returns an integer. It can be negative, zero or positive. For example, if one wanted to compare any two numbers, one could write the following compare function:

 

function compareNumbers( a, b ) {
    return a - b
}

 

If a was greater than b then the function would return a positive number.

If a was the same as b then the function would return zero.

If a was less than b then the function would return a negative number.

 

Then, you would use the compare function as follows:

 

function compareNumbers( a, b ) {
    return a - b
}

let numbers = [ 5, 2, 11, 3, 7 ]
numbers.sort( compareNumbers )
console.log( numbers ) // [ 2, 3, 5, 7, 11 ]

 

If your compare function is simple, you can inline it with your sort call, i.e.

 

let numbers = [ 5, 2, 11, 3, 7 ]
numbers.sort( function compareNumbers( a, b ) { return a - b } )
console.log( numbers ) // [ 2, 3, 5, 7, 11 ]

 

In AppStudio 3.3, Qt 5.12.1 you can use the ECMAScript 6 arrow function syntax, i.e.

 

let numbers = [ 5, 2, 11, 3, 7 ]
numbers.sort( (a,b) => a - b )
console.log( numbers ) // [ 2, 3, 5, 7, 11 ]

 

You'll see the arrow function syntax allows us to omit the 'function' keyword, the function's name and the 'return' keyword. We make this choice if we believe such a choice improves our code readability and maintainability.


In the Sorting Cities sample app, I used the arrow function syntax for all 4 buttons, e.g.

 

Button {
    text: qsTr("  City  ")
    onClicked: listModelSort( citiesListModel,
                              (a, b) => a.city.localeCompare(b.city) )
}

 

 

5. Implementing listModelSort

 

 

There are plentiful sorting algorithms out there. Whilst we can implement one in QML / Javascript, I don't think this is a good idea. We would be implementing a sort algorithm that we would required to maintain. One of the best algorithms out there, Quicksort, is complex to transcribe correctly. Also such an implementation would be executing entirely in Javascript and will not be leveraging much from native code.


Instead, I wanted to leverage from Array sort's implementation. In a nutshell, the algorithm would be:

 

  1. Copy items from the QML ListModel to an Array
  2. Perform an Array sort
  3. Copy the resultant items from the sorted Array back to the QML ListModel

 

Turns out, we can optimized the above technique by not copying the items but linking to them via an index. i.e. The Array would be a set of integer indexes and we just be traversing it as a on the fly lookup into the QML ListModel.

 

Let's begin by creating an indexes Array the exact same size as our ListModel with numbers ranging from 0 to N - 1:

 

let indexes = [ ...Array(listModel.count).keys() ]

 

Then, we use Array's sort method to reorder the indexes Array. We use an arrow function to pick any two entries from the QML ListModel and feed them to the user supplied compare function:

 

indexes.sort( (a, b) => compareFunction( listModel.get(a), listModel.get(b) ) )

 

This reorders the indexes Array. We can now use this sorted Array to traverse the ListModel in sorted order.

 

Whilst we can stop here, I wanted to go further and use theses indexes to rearrange the QML ListModel.

 

for ( let i = 0; i < indexes.length; i++ ) {
    listModel.move( indexes[i], listModel.count - 1, 1 )
    listModel.insert( indexes[i], { } )
}
listModel.remove( 0, indexes.length )

 

The above loop iterates through the items in the ListModel in sorted order. For each item, we move it to the end of the ListModel in sorted order. Once all the items have been moved, we delete the empty holes left behind by the move. It's a heavy handed approach. In my final version I made an optimization that reduces the amount moving and deletion.

 

 

The animation above helps you visualize sorting the cities based on their distance to ESRI. We see it quickly identifies the sort order as Redlands, Los Angeles, Seattle, New York City and Hawaii. The records are tagged by an index 0...4. Next, the sorted records are moved, one by one, to the end, then the sorted records are moved back to the top deleting the temporary empty holes.

 

 

6. Closing Remarks

 

 

For good user interfaces I recommend storing your content in ListModels instead of Arrays. This is so that updates to the content will not interrupt the user experience.


Whenever you can, leverage from an existing implementation (e.g. Array sort) rather than implement your own. You minimize your coding effort and future maintenance efforts.

 

The ECMAScript 6 arrow function syntax can help you express simple sorting compare functions. Otherwise, if they're complex, then, then you should use a named compare function.

 

 

7. References

 

 

 

Send us your feedback to appstudiofeedback@esri.com

 

Become an AppStudio for ArcGIS developer! Watch this video on how to sign up for a free trial.

 

Follow us on Twitter @AppStudioArcGIS to keep up-to-date on the latest information and let us know about your creations built using AppStudio to be featured in the AppStudio Showcase.

 

The AppStudio team periodically hosts workshops and webinars; please click on this link to leave your email if you are interested in information regarding AppStudio events.

1. Javascript Promise

 

 

AppStudio 3.3, Qt 5.12.1 and ECMAScript 7 (which includes ECMAScript 6) introduced native Javascript Promises.

 

This blog is to give you a brief overview of what Promises are and how they matter to AppStudio and QML. This blog isn't a comprehensive guide to Promises. There already is a lot of content on the internet. I recommend you seek them out.

 

Promises is a Javascript coding pattern for working with asynchronous tasks.

 

AppStudio (and QML) has signals and slots for working with asynchronous tasks. If your applications are written and easy to maintain then you probably don't need to look into Promises right now.

 

However, if your applications are complex with business logic spanning over a complex sequence of signals and slots then buying into Promises may be the key to reduce code complexity.

 

Note that the ArcGIS.AppFramework.Promises module is being deprecated in favour of native Javascript Promises. We advise discontinuing using ArcGIS.AppFramework.Promises module and begin removing them from your existing AppStudio apps.

 

 

2. Promise Download Sample

 

 

Let's look at an AppStudio app that simulates downloading content from the internet.

 

 

When the Button is clicked, we simulate 3 concurrent downloads. The downloads will finish 0-1000ms after the Button's onClicked handler has finished. Each download's success/failure will be independent of each other.

 

    Button {
      text: qsTr("Test Promise timeout")
      onClicked: {
        download( "GET", "https://community.esri.com/groups/appstudio" )
          .then( (message) => { console.log( message ) } )
          .catch( (error) => { console.log( error ) } )
        download( "GET", "https://appstudio.arcgis.com" )
          .then( (message) => { console.log( message ) } )
          .catch( (error) => { console.log( error ) } )
        download( "GET", "https://community.esri.com/groups/survey123" )
          .then( (message) => { console.log( message ) } )
          .catch( (error) => { console.log( error ) } )
      }
    }

    function download( method, url ) {
      return new Promise( (resolve, reject) => {
        if (Math.random() < 0.30)
          setTimeout( reject, Math.floor(1000 * Math.random()), `Download failure ${url}` )
        else
          setTimeout( resolve, Math.floor(1000 * Math.random()), `Download success ${url}` )
      } )
    }

View the full PromiseTimeout.qml on GitHub Gist.

 

Some key features of Promises:

 

  • The task begins as soon as new Promise() { ... } is called.
  • The task is defined as (resolve, reject) => { /* body */ } where either resolve(data) or reject(error) will be called when the task completes.
  • Use then() method to supply your success handler.
  • Use catch() method to supply your failure handler.

 

You may be thinking "This looking confusing" and "Do I need this?". I ask you to consider this: the Button's onClick handler fully describes 3 download tasks and what to do when each of them finishes. It describes this all this in one place, in the one function. If you didn't use Promises, we would have to create numerous signals and slots and spread the implementation throughout the application.

 

 

3. Promise chaining

 

 

Promise chaining is a coding pattern where you want to run your asynchronous tasks sequentially. You may need to do this if you wish to use the output of one task as an input to the next.

 

 

When the Button is clicked, we want to start the download of 3 web pages, one after the after. If downloads are successful, you will see the web page's title. If any task fails, we do not continue downloading. (N.B. here, the download function is real. The download function returns the web page's title).

 

    Button {
      text: qsTr( "Test Promise chaining" )
      onClicked: {
        download( "GET", "https://community.esri.com/groups/appstudio" )
        .then( (data) => {
          console.log( data.title )
          return download( "GET", "https://appstudio.arcgis.com" )
        } )
        .then( (data) => {
          console.log( data.title )
          return download( "GET", "https://community.esri.com/groups/survey123" )
        } )
        .then( (data) => {
          console.log( data.title )
        } )
        .catch( (error) => { console.log( error ) } )
      }
    }

View the full PromiseChaining.qml on GitHub Gist.

 

However, due to the https://bugreports.qt.io/browse/QTBUG-71329, Promise chaining doesn't work in AppStudio 3.3, Qt 5.12.1. Please vote to have it fixed! Because of the bug, the app does not run correctly:

 

 

 

4. Promise nesting (alternative to Promise chaining)

 

 

Since Promise chaining doesn't work in AppStudio 3.3, Qt 5.12.1 let's explore some alternatives. This one demonstrates Promises nesting where each subsequent task is nested in the success of the previous task. (N.B. here the download function returns an object containing the status, responseText, and title).

 

    Button {
      text: qsTr( "Test Promise nesting" )
      onClicked: {
        download( "GET", "https://community.esri.com/groups/appstudio" )
        .then( (data) => {
          console.log( data.title )
          download( "GET", "https://appstudio.arcgis.com" )
          .then( (data) => {
            console.log( data.title )
            download( "GET", "https://community.esri.com/groups/survey123" )
            .then( (data) => {
              console.log( data.title )
            } )
            .catch( (error) => { console.log( error ) } )
          } )
          .catch( (error) => { console.log( error ) } )
        } )
        .catch( (error) => { console.log( error) } ) 
      }
    }

View the full PromiseNesting.qml on GitHub Gist.

 

This implementation works, but it is extremely ugly. It is infamously known as callbackhell. You see each subsequent task incurs another level of indentation and another copy of the error handler.

 

 

5. Promise async/await (alternative to Promise chaining)

 

 

async/await is another alternative to Promise chaining. The main characteristic is the use of the new async and await keywords and that the main body reads sequentially and elegantly.

 

    Button {
      text: qsTr( "Test Promise async/await" )
      onClicked: {
        (async () => {
          try {
            console.log( ( await download( "GET", "https://community.esri.com/groups/appstudio") ).title)
            console.log( ( await download( "GET", "https://appstudio.arcgis.com") ).title)
            console.log( ( await download( "GET", "https://community.esri.com/groups/survey123" ) ).title)
          } catch ( error ) {
            console.log( error )
          }
        } )()
      }
    }

View the full PromiseAsyncAwait.qml on GitHub Gist.

 

Unfortunately, this feature didn't make it to AppStudio 3.3, Qt 5.12.1. Help get this into a future release of AppStudio by voting for it at https://bugreports.qt.io/browse/QTBUG-58620.

 

 

6. Promise async/await Babel (alternative to Promise chaining)

 

 

Generator functions made it into AppStudio 3.3, Qt 5.12.1. We can use https://babeljs.io/ to convert the async/await into Generator functions. This version works in AppStudio 3.3, Qt 5.12.1. Here's the converted output:

 

    Button {
      text: qsTr( "Test Promise async/await (Babel)" )
      onClicked: {
        _asyncToGenerator( function*() {
          try {
            console.log( ( yield download( "GET", "https://appstudio.arcgis.com" ) ).title )
            console.log( ( yield download( "GET", "https://community.esri.com/groups/appstudio" ) ).title )
            console.log( ( yield download( "GET", "https://community.esri.com/groups/survey123" ) ).title )
          } catch ( error ) {
            console.log( error )
          }
        } )()
      }
    }

View the full PromiseBabel.qml on GitHub Gist.

 

While waiting for the async/await feature to be implemented, I think the above syntax is compelling.

It is extremely close to async/await syntax and, I think, is significantly better than Promise chaining.

 

To make it work, _asyncToGenerator() and asyncGeneratorStep() functions are required.

 


7. Promise.all and Promise.race

 

 

Promise.all is a special Promise that succeeds by waiting for every sub Promise to succeeds else it fails to report the error from the first failing sub Promise.

 

 

Promise.race is a special Promise in that we are only interested in the first sub Promise that finishes the race. We aren't interested in the completion of the subsequent Promises. We will be notified of the success message or failure error of that first sub Promise.

 

Surprisingly, no matter how many times you try, you find the AppStudio Home Page always wins the race.

 

 

Why is the second Promise always succeeding in the race? That's because the community GeoNet page takes longer to load!

 

 

8. Closing remarks

 

 

I hope this blog helps gives a good overview ofPromises and why they matter in your AppStudio apps.

 

Promises, while new in AppStudio 3.3, Qt 5.12.1 is a feature that other Javascript developers have already been enjoying for some time now.

 

Promises, I believe, work very well with Qt's signal and slot mechanism taking it to a whole new level.

 

Promise chaining and async/await functions do not work. We need your help to make AppStudio come closer to parity with other Javascript developer environments by voting on getting these two bugs fixed:

 

 

Whilst we wait for async/await functions, I highly recommend you use https://babeljs.io/ to get async/await features today.

 

 

9. References

 

 

 

Send us your feedback to appstudiofeedback@esri.com

 

Become an AppStudio for ArcGIS developer! Watch this video on how to sign up for a free trial.

 

Follow us on Twitter @AppStudioArcGIS to keep up-to-date on the latest information and let us know about your creations built using AppStudio to be featured in the AppStudio Showcase.

 

The AppStudio team periodically hosts workshops and webinars; please click on this link to leave your email if you are interested in information regarding AppStudio events.

1. Introduction

 

This blog talks about implementing your own setTimeout() function in AppStudio.

 

The blog also highlights ECMAScript 6 and ECMAScript 7 support in Qt 5.12.1 and AppStudio 3.3 features: arrow functions (my favourite), property shorthand, rest parameters and spread syntax.

 

setTimeout() is a function which executes another function or specified piece of code after waiting for the specified time delay in milliseconds.

 

The following will execute the following 4 console.log() after waiting 0 - 1000 milliseconds (determined by a random function). Each timer starts simulatenously but their completion times are random making the 4 console.log() appearing in random jumbled order.

 

    setTimeout( () => console.log("Hello"), randomDelay() )
    setTimeout( (a) => console.log(a), randomDelay(), 1 )
    setTimeout( (a, b) => console.log(a, b), randomDelay(), 21, 22 )
    setTimeout( (a, b, c) => console.log(a, b, c), randomDelay(), 31, 32, 33 )

 

randomDelay() is a function that computes a random time delay from the range of 0 – 1000 milliseconds:

 

    function randomDelay() {
        return Math.floor(1000 * Math.random())
    }

 

Here is the console output:

 

 

 

2. AppStudio implementation

 

setTimeout() is a part of other Javascript development environments, e.g. in Web development and Node.js. It exists globally on the window object.

 

However, in Qt and AppStudio, there isn’t an equivalent window object or setTimeout() function.

 

To bring over such a capability you need to implement it yourself.

 

Here is a sample AppStudio app that includes a simple implementation of setTimeout(). Everytime the button is clicked the 4 setTimeout() functions are triggered with the 4 resulting console.log() appearing in random order.

 

import QtQuick 2.12
import QtQuick.Controls 2.5
import ArcGIS.AppFramework 1.0

App {
    id: app

    width: 400 * AppFramework.displayScaleFactor
    height: 640 * AppFramework.displayScaleFactor

    StackView {
        id: stackView

        anchors.fill: parent

        initialItem: Item {
            Button {
                text: qsTr("Test")
                onClicked: {
                    setTimeout( () => console.log("Hello"), randomDelay() )
                    setTimeout( (a) => console.log(a), randomDelay(), 1 )
                    setTimeout( (a, b) => console.log(a, b), randomDelay(), 21, 22 )
                    setTimeout( (a, b, c) => console.log(a, b, c), randomDelay(), 31, 32, 33 )
                }
            }
        }
    }

    function randomDelay() {
        return Math.floor(1000 * Math.random())
    }

    function setTimeout(func, interval, ...params) {
        return setTimeoutComponent.createObject(app, { func, interval, params } )
    }

    function clearTimeout(timerObj) {
        timerObj.stop()
        timerObj.destroy()
    }

    Component {
        id: setTimeoutComponent
        Timer {
            property var func
            property var params
            running: true
            repeat: false
            onTriggered: {
                func(...params)
                destroy()
            }
        }
    }
}

 

Disclaimer: this is a minimal implementation of setTimeout() not a fully functioning implementation. It is here for the purposes of this blog, specifically to talk about aspects of ECMAScript. If you want to use this implementation you will need to adapt it accordingly.

 

This implementation of setTimeout() returns a Timer object (instead of a timerId). When the time delay specified in milliseconds has been reached the nominated Javascript function is triggered with the parameters you supplied to setTimeout(). If you wish to abort the action, you can passed the Timer object to the clearTimeout() function.

 

 

This implementation will now be deconstructed:

  • Global functions in AppStudio
  • ECMAScript 6 Arrow Functions
  • ECMAScript 6 Property shorthand
  • ECMAScript 6 Rest parameter and Spread syntax

 

3. Global functions in AppStudio

 

Functions implemented in the top level component (here, it was App) will be seen by all child components. In this example, we have a StackView which means, all pages that are pushed to the StackView will have access to the setTimeout() function.

 

4. Arrow functions

 

The first parameter to setTimeout() refers to a function or code. In our examples, we have been using the ECMAScript 6 arrow function syntax for anonymous functions. e.g. the arrow function (a, b, c) => console.log(a, b, c) appears in the following snippet:

 

setTimeout( (a, b, c) => console.log(a, b, c), randomDelay(), 31, 32, 33)

 

When used appropriately, arrow functions can help improve code readablity and maintainability.

 

For comparison, let's look at equivalent implementation to the above arrow function.

 

 

4.1 Original Anonymous functions

 

Prior to ECMAScript 6, we could always do anonymous functions, but the syntax was somewhat cumbersome with the required use of the function keyword:

 

setTimeout( function (a, b, c) { console.log(a, b, c) }, randomDelay(), 31, 32, 33 )

 

 

4.2 Using a named function

 

Sometimes, to avoid the use of the anonymous function syntax, I find it better to name things clearly and space out my code for increase readability and maintainability:

 

function testFunction(a, b, c) {
    console.log(a, b, c)
}

setTimeout(testFunction, randomDelay(), 31, 32, 33)

 

4.3 Calling console.log directly

 

For completeness, we recognize that console.log, is, itself, a function reference, so, we can supply this directly to the setTimeout() function.

 

setTimeout(console.log, randomDelay(), 31, 32, 33)

 

 

5. Property shorthand syntax

 

ECMAScript 6 introduces a property shorthand syntax for object creation.

In the following snippets, compare the code for both obj1 and obj2.

They both yield the same value, but the code for obj2 is much shorter and easier to read.

 

 

var x = 11
var y = 22
var z = 33
var obj1 = { x: x, y: y, z: z } // obj1 = { x: 11, y: 22, z: 33 }
var obj2 = { x, y, z } // obj2 = { x: 11, y: 22, z: 33 }

 

We used the shorthand syntax to simplify the following

 

setTimeoutComponent.createObject(app, { func:func, internval:interval, args:args } )

 

into:

 

setTimeoutComponent.createObject(app, { func, interval, args } )

 

 

6. Rest parameter and Spread syntax

 

ECMAScript 6 also introduces rest parameters and spread syntax.

We used it in the declaration of the setTimeout function to pick up all remaining parameters as an array.

 

function setTimeout(func, interval, ...params) {

 

when called with:

 

setTimeout( (a, b, c) => console.log(a, b, c), randomDelay(), 31, 32, 33)

 

results in:

 

func = (a, b, c) => console.log(a, b, c)
interval = randomDelay()
params = [ 31, 32, 33 ]

 

When calling func we passed the parameters using the spread syntax,  i.e.

 

func(...params)

 

which passes the parameter array as individual parameters to the function, i.e.

 

func(31, 32, 33)

 

which ultimate calls

 

console.log(31, 32, 33)

 

Closing Remarks

 

This blog discusses an AppStudio implementation of setTimeout(). It was used as a way to give you a glimpse of some of the new ECMAScript 6 features, i.e. arrow functions, property shorthand and rest parameters and spread syntax which you can utilize in your AppStudio apps.

 

I plan to talk about Promises in ECMAScript 6 and AppStudio in a future blog. That blog will reuse the setTimeout() function and arrow functions introduced here.

 

In the meantime, please help us improve Promises in AppStudio by voting on fixing Promise chains bug https://bugreports.qt.io/browse/QTBUG-71329 and by voting on implementing async/await support in https://bugreports.qt.io/browse/QTBUG-58620

 

 

References

 

 

Send us your feedback to appstudiofeedback@esri.com

 

Become an AppStudio for ArcGIS developer! Watch this video on how to sign up for a free trial.

 

Follow us on Twitter @AppStudioArcGIS to keep up-to-date on the latest information and let us know about your creations built using AppStudio to be featured in the AppStudio Showcase.

 

The AppStudio team periodically hosts workshops and webinars; please click on this link to leave your email if you are interested in information regarding AppStudio events.

1. Introduction

 

This amazing clipart can be produced with a surprising short amount of code:

 

 

 

Text {
    text: "\u{1f304}"
    font.pointSize: 128
}

View EmojiSunrise.qml on GitHub Gist.

 

This blog talks about Unicode and the wonderful emojis and cliparts that are hidden within. It also covers some new syntax introduced in AppStudio 3.3, Qt 5.12.1 and ECMAScript 7 (which includes ECMAScript 6).

 

2. Use Unicode Clipart to rapidly create UI

 

You can use Unicode emojis and clipart in Buttons and MenuItems:

 

import QtQuick 2.7
import QtQuick.Controls 2.2
import ArcGIS.AppFramework 1.0

App {
    id: app
    width: 400 * AppFramework.displayScaleFactor
    height: 640 * AppFramework.displayScaleFactor

    Button {
        id: menuButton
        anchors.right: parent.right
        anchors.margins: 10
        text: "\u{2630}"
        onClicked: menu.open()
    }

    Menu {
        id: menu
        x: menuButton.x + menuButton.width - menu.width
        y: menuButton.y + menuButton.height
        MenuItem { text: "\u{1f4c2}  Open" }
        MenuItem { text: "\u{1f4be}  Save" }
        MenuItem { text: "\u{1f5a8}  Print" }
        MenuItem { text: "\u{2702}  Cut" }
        MenuItem { text: "\u{1f4cb}  Paste" }
        MenuItem { text: "\u{1f4c5}  Calendar" }
        MenuItem { text: "\u{2699}  Settings" }
        MenuItem { text: "\u{1f6aa}  Exit" }
    }
}

 

 

 

You can use emojis to improve text shown to the user:

 

import QtQuick 2.7
import ArcGIS.AppFramework 1.0

App {
    id: app
    width: 520 * AppFramework.displayScaleFactor
    height: 640 * AppFramework.displayScaleFactor

    ListView {
        anchors.fill: parent
        model: [
            '  \u{2139}  "Do. Or do not. There is no try." — Yoda',
            '  \u{26a0}  "It’s not wise to upset a Wookiee." - Han Solo',
            '  \u{1f534}  "It’s a trap!" - Admiral Ackbar'
        ]
        delegate: Text { text: modelData }
    }
}

 

 

3. Where is the list of emojis?

 

Using the String.fromCodePoint(codePoint) you can display any Unicode characters base on its code point number. You can use this code pattern to iterate code points searching for interesting emojis and clipart. The following shows the emojis and clipart from 1F300 to 1F3FF.

 

import QtQuick 2.7
import ArcGIS.AppFramework 1.0

App {
    id: app
    width: 520 * AppFramework.displayScaleFactor
    height: 640 * AppFramework.displayScaleFactor

    property int startCodePoint: 0x1f300
    property int endCodePoint: 0x1f3ff
    property int codePoint: startCodePoint

    Text {
        anchors.centerIn: parent
        text: String.fromCodePoint(codePoint)
        font.pointSize: 64
    }

    Timer {
        id: animTimer
        repeat: true
        running: true
        interval: 100
        onTriggered: codePoint = (codePoint < endCodePoint) ? codePoint + 1 : startCodePoint
    }
}

 

You can also use online lists to search for Unicode emojis and clipart, i.e. "sunrise over mountains" can be found in the following lists:

 

https://unicode.org/emoji/charts/full-emoji-list.html#1f304

https://emojipedia.org/sunrise-over-mountains/

 

Some interesting Unicode blocks are 2600 - 2BFF and 1F300 - 1F8FF.

 

For a listing of Unicode blocks refer to: https://en.wikipedia.org/wiki/Unicode_block

 

4. Character vs Code Point

 

A character is represented internally as a 16 bit number which means there can be a total of 65536.

 

Unicode allows for 17 planes, each of 65,536 characters. This gives a total of 1,114,112 possible characters (i.e. 0x to 0x10ffff).

 

If a Unicode Code Point is within a 16 bit number, it will only require 1 character to represent, otherwise, we will need two characters.

 

For instance, in AppStudio 3.2, Qt 5.11.2 and ES 5, we needed two characters to represent the sunrise over mountains emoji, i.e. "\ud83c\udf04".

 

The code point syntax "\u{1f304}" in AppStudio 3.3, Qt 5.12.1 and ECMAScript 7 (which includes ECMAScript 6) is new. It actually expands into the two characters that make it. The String.fromCodePoint() function is also new.


"\u{1f304}" === String.fromCodePoint(0x1f304)

 

we can always convert code point back into their numbers with:

 

"\u{1f304}".codePointAt(0) === 0x1f304

 

We can also convert code points to characters:

 

"\u{1f304}".length === 2
"\u{1f304}".charCodeAt(0) === 0xd83c
"\u{1f304}".charCodeAt(1) === 0xdf04
"\u{1f304}" === "\u{d83c}\u{df04}"

 


 

5. Caveats

 


5.1 Not all clipart is available or consistent cross platform

 


When viewing Unicode clipart on Windows 10 you find a set of Mahjong tiles at 1F000 - 1F02B. You might be inclined to use them in a Mahjong app:

 

 

However, when you check on other platforms, you may quickly change your mind. On Linux, we get the complete set of clipart, but, in black and white. On macOS, all of the characters appear black and white except for Mahjong Red Dragon appears in colour. On iOS, only the Mahjong Red Dragon appears whereas all other characters are unavailable. On Android, only the Mahjong Red Dragon tile is available there too. Also note the appearance of the no data tile is different on every platform.

 

On Linux:

 

 

On macOS:

 

 

On iOS:

 

 

On Android:

 

 

5.2 Issue with some CodePoints on Buttons

 

In the following code snippet we try to render the same text in Text and Button components:

 

import QtQuick 2.7
import QtQuick.Controls 2.2
import ArcGIS.AppFramework 1.0

App {
    id: app
    width: 520 * AppFramework.displayScaleFactor
    height: 640 * AppFramework.displayScaleFactor

    Column {
        Text {
            text: "\u{263a} \u{1f304} "
            font.pointSize: 32
        }

        Button {
            text: "\u{263a} \u{1f304} "
            font.pointSize: 32
            font.capitalization: Font.MixedCase
        }
    }
}

 

we see that the smiley and the face emoji renders okay on both the Text and the Button

 

 

However, the Button requires a workaround that disables the material design capitalization on Buttons. This is due to a bug in Qt 5.12.x reported in https://bugreports.qt.io/browse/QTBUG-75559. Help get this bug fix by voting on it.

 

 

Summary

 

You can find a lot of clipart or emojis that help deliver high visual impact for little expense in code.

 

Caveats are not every platform offers the same set of clipart or emojis nor are they consistent in appearance on the ones that they do offer.

 

Cross platform testing is essential.

 

 

References:

 

Send us your feedback to appstudiofeedback@esri.com

 

Become an AppStudio for ArcGIS developer! Watch this video on how to sign up for a free trial.

 

Follow us on Twitter @AppStudioArcGIS to keep up-to-date on the latest information and let us know about your creations built using AppStudio to be featured in the AppStudio Showcase.

 

The AppStudio team periodically hosts workshops and webinars; please click on this link to leave your email if you are interested in information regarding AppStudio events.

AppStudio Player for ArcGIS is a great testing tool, it lets you instantly view AppStudio apps on a real device without requiring a full build and deployment cycle. But did you know that you can also use Player to distribute apps into your organization? And the source code of Player is available as an enterprise template in AppStudio Desktop. You can easily customize Player by configuring properties in the App Settings tool, or by editing the source code. Over the past releases, we have exposed more configuration options, such as the ability to change portal URL, branding color, and Font file, hiding certain pages, and more to help you rebrand Player easier and faster without writing any code.

 

 

Why distribute apps using Player? 

Getting your app prepared for app stores is not a trivial process, with numerous steps and prerequisites involved. On top of that, it takes time for your app to be approved, and the app approval process can be a little tricky because of restrictive submission policies and need to keep updated with the latest store review guidelines and design criteria. However, if you don’t intend to make an app publicly available, and they will only be used by members of your organization, you can use AppStudio Player as your own “enterprise app store”.  Just as you can share maps and data stored in your ArcGIS Organization (ArcGIS Online or Enterprise) with others, you can also share apps built with AppStudio.  The end user can simply log in to AppStudio Player, download and use the app on their device.  This is a safe and efficient solution for distributing apps without publishing to app stores, and it gives the app developer control of how the app is distributed.

 

As was mentioned early the source code for AppStudio Player is included with AppStudio as an Enterprise Templates, this means you can create your own version of Player to distribute in your organization.  There are many reasons you might want to customize player; somewhat an app that includes their own branding (colors, logos, etc.), you may want to remove some of the default feature and tools, and others might go as far as adding completely new functionality through code.

 

Here are some key points we want you to remember:

  • It’s easy to customize Player
  • Support for ArcGIS Online and Enterprise
  • Simple process to install a customized Player over-the-air through a hyperlink
  • Utilize Groups to share apps with organization members
  • Any ArcGIS User Types with essential app bundle can log into Player
  • Includes support for iOS, Android, Windows, MacOS and Linux platforms

 

 

The goal of this tutorial

In this blog, we are going to configure the Player for the City of Cilantro with the following changes:

  • Changing app icon and title
  • Changing branding colors
  • Changing onboarding images and messages
  • Hiding the Skip button on the onboarding page
  • Hiding the Samples page
  • Hiding Capabilities, Devices, and Licensing sections in the App Details page
  • Hiding Scan QR code, Diagnostics, and Remote Console options in the side menu
  • Hiding the Dark Mode option in the App Settings tool

 

The final app will look like the images below.

 

Time: 15 minutes

 

Note: An AppStudio Standard License is required for this tutorial. If you don't have one, please follow this video to register a trial account. 

      

How to configure AppStudio Player?

 

Step 0. Downloading AppStudio Desktop and attached resources folder

 

Step 1. Creating a new app using the Player enterprise template

  • Open AppStudio Desktop
  • Click on the “New App” button
  • Go to the Enterprise tab
  • Double click on the Player (3.3 Template) thumbnail to create a new Player enterprise template app
  • Click on the Edit Title icon on the side panel to rename the app to “The City of Cilantro"

                   

 

Step 2. Registering your application

To allow users to sign in to your app with OAuth 2.0 (a standardized authorization framework), you will need to register your app to generate an ArcGIS Client ID (or App ID). To do this:

 

  • Select your app and click on the Upload button to upload your app to ArcGIS Online or ArcGIS Enterprise
  • Click on the Settings tool on the side panel
  • Click on the Licensing from the left-hand side navigation menu
  • Click on the Register button and Apply button

                         

 

Step 3. Configuring Player Enterprise Template

 

  1. Select the app you have created from Step 1, then click on the Settings tool.
  2. Click on the Resources from the left-hand side navigation menu and change the App Icon into the Icon - City of Cilantro.png from the attached resources folder.                                                                                                                                         
  3. Click on the Advanced from the left-hand side navigation menu and add “Cilantro” in the Short Name field.                             
  4. Click on the Properties from the left-hand side navigation menu, and then Enterprise tab.
  5. If you have a portal, you can add your own portal URL and name in the Portal URL and Portal name You can skip this step if you don’t have a portal                                                                                                                                                    
  6. Go to the Onboarding tab and turn off the Show Skip button. Select the onboarding_Cilantro.png image from the attached resources folder as the Onboarding image one and enter “The City of Cilantro” into the Onboarding messages one field. Provide your own images and messages for the rest onboarding pages.                                                                               
  7. Go to the General tab, enter the hex code of the brand color #f15a24. Turn off Show Sample Page and Show Capabilities, Devices, and Licensing sections.
  8. Go to Side Menu, turn off all the properties and enter a preferred email into the Feedback.                                                         
  9. Click on the Apply button and run the app to see if your customized Player recognizes your settings.

Note: Please do not download and test your configured Player in AppStudio Player. If you wish to test on a mobile device, use the Make to create app installation files. This requires an Apple Developer account if you are going to create a build for iOS.

Step 4 Editing Player’s source code

 

If you wish to customize Player further, you can edit the source code of the Player by clicking on the Edit icon in the side panel to open the Qt Creator IDE. Then expand the MyPlayer folder on the left-hand panel to open the structure of the Player app. You can navigate to the desired files and modify the source code. 

   

 

We hope you find this blog helpful. We want to hear from you and continue to improve Player’s configuration experience to make it as easy as possible. Don't hesitate to email your feedback to appstudiofeedback@esri.com

 

 

Become an AppStudio for ArcGIS developer! Watch this video on how to sign up for a free trial.

 

Follow us on Twitter @AppStudioArcGIS to keep up-to-date on the latest information and let us know about your creations built using AppStudio to be featured in the AppStudio Showcase.

 

The AppStudio team periodically hosts workshops and webinars; please click on this link to leave your email if you are interested in information regarding AppStudio events.

1. Mary had a little lamb

 

AppStudio 3.3 is based on Qt5.12.1 which includes a new JavaScript engine supporting ECMAScript 6 and ECMAScript 7. In this blog we will be looking at multiline string literals, specifically, different ways of realizing the following nursery rhyme:

 

Mary had a little lamb, little lamb, little lamb
Mary had a little lamb
Whose fleece was white as snow.

 

2. The 1 liner example

 

var str = "Mary had a little lamb, little lamb, little lamb\nMary had a little lamb\nWhose fleece was white as snow.\n"

 

The above code gives us what we want. A 3 line rhyme stored in a string. It's short, but, it is hard to read and maintain. The newline \n character makes reading the first word in the following sentence awkward.

 

3. String lists

 

var list = [ "Mary had a little lamb, little lamb, little lamb",
             "Mary had a little lamb",
             "Whose fleece was white as snow." ]
var str = list.join("\n") + "\n"

 

Using a staging list means we don't need to remember to put \n to break every line. It's looks nicer in code and easier to maintain the rhyme since we can now split the code over multiple lines. It does suffer from the fact that we need to ensure the syntax of lists is correct (i.e. the commas needed to be correctly placed). It has the advantage that we can make use of array functions such as appending to the end of the list. The joining line does look awkward but it's always the same pattern so you'll get used to it. Because we are using join, we must remember to append the last \n.

 

4. Using the files

 

var str = app.folder.readTextFile("rhyme.txt")

 

By storing strings in files, we can dramatically reduce the code that appears in your program. This reduces error significantly, and, maintenance on your rhyme can be done in a regular text edit without worrying about the Javascript side of things.

 

5. ECMAScript 6 multiline string

 

var str = `Mary had a little lamb, little lamb, little lamb
Mary had a little lamb
Whose fleece was white as snow.
`

As of AppStudio 3.3 (and Qt 5.12.x) we can now use backticks ` to surround a multiline string element. This is incredibly easy to read and maintain. Backticks also introduces a new feature called expression interpolation. Here's a simple example involving our poem:

 

var name = 'Mary';
var str = `${name} had a little lamb, little lamb, little lamb
${name} had a little lamb
Whose fleece was white as snow.
`

 

Here's a more extended form which includes operators:

 

var customer = { name: "Foo" }
var card = { amount: 7, product: "Bar", unitprice: 42 }
var str = `Hello ${customer.name},
want to buy
${card.amount} ${card.product} for
a total of
${card.amount * card.unitprice} bucks?`

 

References

 

 

Send us your feedback to appstudiofeedback@esri.com

 

Become an AppStudio for ArcGIS developer! Watch this video on how to sign up for a free trial.

 

Follow us on Twitter @AppStudioArcGIS to keep up-to-date on the latest information and let us know about your creations built using AppStudio to be featured in the AppStudio Showcase.

 

The AppStudio team periodically hosts workshops and webinars; please click on this link to leave your email if you are interested in information regarding AppStudio events.

We are pleased to announce the release of AppStudio for ArcGIS version 3.3. This release includes many exciting new features and enhancements to help you write apps faster and easier than ever. Please click on this link to learn what's new.  

 

Bug Fixes and Enhancements

 

 

Salesforce ID
Synopsis
BUG-000089678
AppStudio for ArcGIS app is German yet Map Tour Templates are in English
BUG-000092273
Title for Make tool is not localized (AppStudio)
BUG-000092436
MOR_I18N: "Sign In" string is not correctly centered / truncated on some languages
BUG-000117083
In AppStudio for ArcGIS Desktop, when the app auto-signs in using Enterprise logins while accessing a secured service, the Map Viewer template returns the error "Client_id not specified".
BUG-000119230
Android build fails in AppStudio for ArcGIS (Desktop Edition) when a valid Java KeyStore (JKS) is supplied with Cloud Make.
BUG-000120353
AppStudio for ArcGIS Map Viewer applications fails to load secured maps using Portal for ArcGIS.
ENH-000089904
AppStudio for ArcGIS app is German yet Map Viewer Templates are in English
ENH-000089905
AppStudio for ArcGIS app is German yet Quick Report Templates are in English
ENH-000096403
Enable the ability in AppStudio for ArcGIS app to access and use the GPS while the screen is locked or if another app is currently enabled in the app stack on the device.
ENH-000118292
Unable to add more than one feature layer in AppStudio Quick Report template

The AppStudio Framework (AppFramework) provides QML components used when creating apps in AppStudio for ArcGIS. AppFramework library of components is unique in that it has features and capabilities that are neither natively provided by the underlying Qt framework nor the ArcGIS Runtime but are necessary and commonly used for developing apps. We are excited to share new features and enhancements added to AppStudio 3.3 beta release with you in this blog post.

 

Support for AppConfig and Enterprise Mobile Management (EMM)

We have included a new AppFramework.Management plugin to support Enterprise Mobile Management (EMM), which allows you to manage and secure your apps and data across mobile devices. Please check this blog post for more information.

 

Browser View Component Enhancements:

We have introduced BrowserView component in the previous release, which brings you a full Safari web browser experience for iOS devices, we have been continuing working on BrowserView to support Chrome web browser experience for Android. Besides, you can customize the native browser view (Safari and Chrome) by changing the background and controls color with newly introduced primaryColor and forgroundColor properties in the BrowserView component. The following code snippet demonstrates how to define the BrowserView component and invoke a browser view.

 

 

import ArcGIS.AppFramework.WebView 1.0

Button {
   anchors.centerIn: parent
   text: qsTr("Open BrowserView")
   onClicked: {
   browserView.show()
     }
  }

BrowserView {
  id: browserView
  anchors.fill: parent
  primaryColor:"#8f499c"
  foregroundColor: "#f7d4f4"
  url: "https://www.esri.com/en-us/arcgis/products/appstudio-for-arcgis"
   }

  

Browser View Sample

Browser View Sample is available on AppStudio Desktop and AppStudio Player. To find this sample in AppStudio Desktop, first, launch AppStudio Desktop > click on the New App button > click on Search icon > type Browser View. You can also find the Browser View sample in the AppStudio Player, launch Player on your mobile device > go to Samples page > search for Browser View. 

                

                                                  Browser View Sample (available on AppStudio Desktop and Player)

 

Support for changing status bar color and theme 

We have introduced a new StatusBar component in ArcGIS.AppFramework.Platform plugin, which provides you access to manage the appearance of the status bar such as changing status bar color and theme color. In addition, we have also created a new AppLayout component, which can handle various heights of the status bar across devices especially devices with a notch. It should be used along with the StatusBar component.  You will need to set your App object as the contents of the delegate property within an AppLayout object. The sample code below demonstrates how to use AppLayout component.

 

import ArcGIS.AppFramework.Platform 1.0
AppLayout {
    width: 480
    height: 640
    delegate: App {
        id: app
           ...
    }
}

 

Note: Status bars are not displayed by default on these devices; it first has to be enabled by setting the property display.statusBar to true in the app's appinfo.json

 

                           

                                                    Status bar sample (available on AppStudio Desktop and Player)

 

 

DocumentDialog component enhancements

DocumentDialog component was introduced from the last release, it allows access your device's native document picker and returns a selected file path. With AppStudio 3.3 beta, we have improved the DocumentDialog preference by adding restrictions while selecting files only available on the device's local storage. 

 

Note: You will need to declare your app needs storage permission for Android when using DocumentDialog to access external resources and information. AppFramework provides a FileFolder component, which can invoke storage permission dialog. For example, you can include the following code into your app.

 

// Show storage permission pop-up on Android 
FileFolder {
        id: fileFolder
        path: AppFramework.userHomePath    }
 
    Component.onCompleted: {
        fileFolder.makeFolder()
    }

 

Also, please don’t forget to enable external storage capability in the AppStudio Desktop > Settings first.

DocumentDialog Sample 

We have implemented the Document Dialog feature into an existing "Edit Feature Attachments" sample app. When you try to add a new attachment, a native document picker will open, which is invoked by the DocumentDialog from AppFramework Platform plugin.

 

                             

                                               Edit Feature Attachment sample (available on AppStudio Desktop and Player)

 

                                                       

 

AppFramework.checkCapability enhancements

AppFramework.checkCapability() now supports BackgroundLocation as a capability to determine whether it is enabled in runtime.

 

You can try above new features and enhancements from AppFramework with AppStudio Desktop and Player version 3.3 beta, AppStudio Desktop 3.3 beta is available at Early Adopter Community and AppStudio Player 3.3 beta is available at Apple's TestFlight and Android Beta Program.

 

The API References of above new features and enhancements are available at Qt Creator help documentation included with the AppStudio Desktop 3.3 (Beta) install.      

 

We hope you enjoy all the new features and enhancements added to the AppFramework. For bugs or other issues, you may find, please submit a bug report or join the beta forum to provide feedback. You can also send us an email to appstudiofeedback@esri.com.

 

Become an AppStudio for ArcGIS developer! Watch this video on how to sign up for a free trial.

 

Follow us on Twitter @AppStudioArcGIS to keep up-to-date on the latest information and let us know about your creations built using AppStudio to be featured in the AppStudio Showcase.

 

The AppStudio team periodically hosts workshops and webinars; please click on this link to leave your email if you are interested in information regarding AppStudio events.

Managing the safety and security of mobile devices, apps and data in your enterprise network is now more important than ever. With AppStudio 3.3 Beta we have added support for managed app configuration, also known as AppConfig, when managing and deploying your apps through your Enterprise Mobility Management solution.

  

What are EMMs and MDMs?

Enterprise Mobility Management (EMM) is a set of people, processes and technology focused on securely and efficiently managing systems and devices (desktop, server, and mobile). This includes setting policies, pre-configuring settings, applying restrictions, deploying apps, and setting profiles and assignment policies to deliver apps to your managed devices. The management of mobile devices is one of the many components available as part of an EMM solution.

  

There are a number of Mobile Device Management (MDM) solutions that can help you implement your EMM solution for managing your enterprise mobile devices, and these MDM solutions include support for what is known as Mobile Application Management (MAM). Here are just a few of the available MDM solutions that many of the Esri apps have already been tested and deployed with: VMware AirwatchMicrosoft Intune, MobileIron Cloud, Samsung Knox, Citrix XenMobile, IBM MaaS360, Cisco Meraki.

  

What is managed app configuration?

Managed app configuration allows apps to be remotely configured through an EMM solution. In order to use managed app configuration, the app must be installed on the device and managed via an MDM solution. While managed app configuration is a feature supported by most of the popular MDM providers, it's best to check with your provider if this feature is supported.
  
In general, MDM providers support AppConfig using key-value pairs. In AppStudio we are following the guidelines found within the AppConfig community's xml standard specification for iOS, Windows, MacOS and Linux. On Android, we support Android's Restriction Manager xml spec.
  
Note: Currently, managed app configuration in AppStudio is only supported on iOS and Android platforms.
  
Adding managed app configuration settings in your MDM

Below is an example of how to set the key-value pairs when creating an assignment, from within the VMware AirWatch MDM console:

  

  

How to read the managed app configuration settings in an AppStudio app

In AppStudio 3.3 beta we have added a new plugin called AppFramework.Management which needs to be imported for your apps to read the settings provided by the MDM. This plugin contains a ManagedAppConfiguration singleton component that provides access to policyDefaults, which are the default key-value pairs the app honors and policySettings which is the list of configured key-value pairs the MDM provides.

  

Defaults

In order to specify the defaults that your app supports, you can use the following new appinfo properties:
  
"management": {
        "android": {
            "restrictionFile": "restrictions.xml"
        },
        "configurationSchema": "specfile.xml"
    },
  
Settings
To make reading policy defaults and settings easier, we have also provided two new helper methods: value and defaultValue. They work by fetching either the default value of the app or the settings value that the MDM has provided with the given key.
  
For instance, this is how your AppStudio app would read the portalUrl and portalName keys specified by the MDM in the above example:
  
Connections {
        target: ManagedAppConfiguration
        onPolicySettingsChanged : {
            portalName.text = ManagedAppConfiguration.value("portalName", false, "ArcGIS");
            portalUrl.text = ManagedAppConfiguration.value("portalUrl", false, "www.arcgis.com");
        }
        onPolicyDefaultsChanged : {
            defaultPortalName.text = ManagedAppConfiguration.defaultValue("portalName");
            defaultPortalUrl.text = ManagedAppConfiguration.defaultValue("portalUrl"); 
        }
    }
Note: AppStudio for ArcGIS 3.3 beta downloads are available through the Early Adopter Community.  
Using the sample app
A new sample app called "Managed App Config" which demonstrates all of the above configurations is now available for you to try. You can find this sample app in the latest AppStudio Desktop edition:
  
1.   Launch AppStudio Desktop
2.   Select New App
3.   Select the Search Icon
4.   Type: Managed App Config
5.   Select the "Managed App Config" sample
  
                                                                         Managed App Config sample app 
  
Please try out this new feature with your favorite MDM provider and give us your feedback by leaving your comments below or email us at appstudiofeedback@esri.com.
  
To find out more about Esri’s ongoing efforts to support our customers implementing EMM solutions, you may also be interested in reading about Mobile Application Management and Esri’s Field Apps. Additionally, for more information about Esri's approach to Mobile Application Management, please read our ArcGIS Secure Mobile Implementation Patterns on the ArcGIS Trust website.

Templates downloaded from AppStudio desktop have been updated to work with the AppStudio 3.3 beta. The AppStudio website will be updated when version 3.3 goes final. These updates include:

 

  •       Quick Report supports multiple feature layers
  •       All templates now supports Qt 5.12
  •       Support for Hindi language for all templates
  •       Bug fixes and minor UI improvements

  

Quick Report

 

  • Quick Report now supports multiple feature layers (configurable with AppStudio Desktop only) from a single feature service in the template. This has been one of the top enhancement requests over the past year. When configuring multiple feature layers, you can now have a mix and match of different geometry types. For example, you can configure one or more point feature layers, polyline and/or polygon feature layers in the same app while allowing end users to collect desired field data across different layers or geometries on the fly.

 

      How to configure multiple feature layers? -  First, you need to configure multiple feature layer IDs in the        AppStudio desktop template app Settings. E.g. in the wildfire feature service (currently the default feature service for       the template) if you want to include all three layers, you need to add the Layer IDs as “0,1,2” in the AppStudio       Desktop > Settings > Form > Layer IDs of the feature service field (see screenshot below). 

 

 

 

      When you run the app, you will see a new Report Galley page (see screenshot below), which includes the                      configured feature layer options in it. You are allowed to add as many layer IDs as you want as long as they are       hosted under the same feature  service. This will work with both secured and public feature services.

 

 

  • Known issues – If you experience crash right after submitting the report in your existing Quick report application based on version 3.2 template or before, please update your app using the Quick Report 3.3 template code. 

 

Map Viewer

 

  • Bug fixes and enhancements
  • Known issues – If you experience crash when accessing web maps in your existing Map Viewer application within the latest AppStudio 3.3 Desktop or Player, please update your app using the Map Viewer 3.3 template code. As this issue has been fixed.

 

Map Tour

 

  • Number of bug fixes and small improvements have been made under the hood.

 

 

Please feel free to test and provide your feedback through the GeoNet or emailing the team at appstudiofeedback@esri.com.

 

 

Become an AppStudio for ArcGIS developer! Watch this video on how to sign up for a free trial.

 

Follow us on Twitter @AppStudioArcGIS to keep up-to-date on the latest information and let us know about your creations built using AppStudio to be featured in the AppStudio Showcase.

 

The AppStudio team periodically host workshops and webinars; please click on this link to leave your email if you are interested in information regarding AppStudio events.

We are excited to announce the beta release of AppStudio for ArcGIS 3.3.  Downloads are available through the Early Adopter Community.  We encourage you to participate in the beta program to try out new features, enhancements, and report bugs.  Your feedback is greatly appreciated, as it helps us improve AppStudio and deliver a stable and high-performance product for everyone. 

 

Highlights of this beta release include:

 

Upgraded Xcode to 10.1

The Apple App Store has announced that all new apps and app updates submitted to the App Store will need to be built with Xcode 10 or above starting from March 2019. We are aware of this change and have upgraded our build environment to Xcode 10.1 in this beta release to make sure you can continue to upload your app to the Apple App Store successfully.  

 

Support for building Android 64-bit apps

The Android NDK has also been upgraded from version 10 to 18, to support building Android 64-bit (ARMv8) apps. This will not only bring better performance to your app by taking advantage of the ARMv8 architecture but also helps you prepare for the future requirement to provide 64-bit versions to the Google Play Store starting August 2019  Currently, you can build an Android 64-bit app using the AppStudio Desktop Make tool, and we will support this on the AppStudio website in the final 3.3 release.

 

Upgraded Qt to version 5.12

The underlying Qt framework has been upgraded to version 5.12.0, which allows you to take advantage of new features, enhancements, and bug fixes added to Qt 5.12.0

 

Support for App Configuration and Enterprise Mobile Management (EMM)

This has been one of the most popular requested features, and we are excited to release a new AppFramework.Management plugin to support Enterprise Mobile Management (EMM) software to read and overwrite certain provided default settings for iOS and Android devices, this allows you to manage and secure your apps and data across mobile devices. We will share more information about managed app configuration support in coming blogs.

 

AppStudio for ArcGIS Extension for Visual Studio Code 

You can now try the AppStudio for ArcGIS extension for Visual Studio Code as an alternative for using Qt Creator. AppStudio Desktop is still used to create new apps, but you can edit, upload and run your AppStudio apps from within Visual Studio Code. To learn more see this documentation on the Early Adopter Community.

 

Other New Features and Enhancements:

  • Browser View support for Chrome experience on Android devices.
  • checkCapability() now supports checking whether the background location capability is enabled.
  • iOS minimum supported version has been changed from iOS 10 to iOS 11.
  • Better experience to Register Client ID when the App is not yet uploaded.

 

Note: API references of new features and enhancements are available at Qt Creator Help documentation included with the AppStudio Desktop 3.3 (Beta) install.    

 

Deprecations

The ArcGIS.AppFramework.Controls and ArcGIS.AppFramework.Promises modules are in the process of being deprecated. We advise that you discontinue using these plugins and begin to remove them from your existing AppStudio apps. You can use JavaScript Promises to replace ArcGIS.AppFramework.Promises.    

 

A more comprehensive list of new features and enhancements can be found in the Early Adopter community website

 

Getting Started

The beta program is open to anyone – join the Early Adopter Community today to get access to the latest versions of AppStudio 3.3 beta.

 

  • AppStudio Desktop - You can download the beta version of AppStudio Desktop 3.3 here.
  • AppStudio Player (iOS) - AppStudio Player is available via Apple's TestFlight. Please click on this link to download AppStudio Player 3.3 (Beta).
  • AppStudio Player (Android) - AppStudio Player is available via Android Beta Program. Please go to this link to download.

You are now all set to start testing the AppStudio 3.3 Beta!

 

Feedback

Your feedback is greatly appreciated and will help us to improve the final release of AppStudio for ArcGIS 3.3. For bugs or other issues, you may find, please submit a bug report or join the beta forum to provide feedback. You can also send us an email to appstudiofeedback@esri.com.

 

The final release is scheduled for April.  We want to thank everyone who contributes to AppStudio for ArcGIS 3.3 in advance and we wish you happy testing!

 

Become an AppStudio for ArcGIS developer! Watch this video on how to sign up for a free trial.

 

Follow us on Twitter @AppStudioArcGIS to keep up-to-date on the latest information and let us know about your creations built using AppStudio to be featured in the AppStudio Showcase.

 

The AppStudio team periodically hosts workshops and webinars; please click on this link to leave your email if you are interested in information regarding AppStudio events.