<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Olanrewaju Olakunle</title>
    <description>The latest articles on DEV Community by Olanrewaju Olakunle (@cdfcreator).</description>
    <link>https://dev.to/cdfcreator</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F567145%2F4afd8f2f-395e-4780-93a9-68ff4558cb05.jpeg</url>
      <title>DEV Community: Olanrewaju Olakunle</title>
      <link>https://dev.to/cdfcreator</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/cdfcreator"/>
    <language>en</language>
    <item>
      <title>Building a Cross-Platform eBook App in SCADE</title>
      <dc:creator>Olanrewaju Olakunle</dc:creator>
      <pubDate>Wed, 02 Aug 2023 15:18:49 +0000</pubDate>
      <link>https://dev.to/cdfcreator/building-a-cross-platform-ebook-app-in-scade-2hkf</link>
      <guid>https://dev.to/cdfcreator/building-a-cross-platform-ebook-app-in-scade-2hkf</guid>
      <description>&lt;p&gt;This tutorial aims at introducing mobile developers to developing a cross-platform e-reader app solely using Swift and SCADE.&lt;/p&gt;

&lt;p&gt;The user interface of the eBook is inviting, and accessing it is quite simple. On the home page, it shows you four categories of books to make a selection from. Its navigation bar at the bottom also allows for an easy transition from one page to another. Users can also search for books and check out their overviews offline before proceeding to read the books online within the app.&lt;/p&gt;

&lt;p&gt;Most importantly, in this tutorial, we will detail the step-by-step method of building this eBook app with SCADE. This is an excellent attempt to start with if you're new to SCADE development.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fmFXvakK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/89v2jgqyahghe8k6uogu.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fmFXvakK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/89v2jgqyahghe8k6uogu.gif" alt="Image description" width="222" height="480"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--l2dxNRu4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x4knnfkpeda7xghmbadm.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--l2dxNRu4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x4knnfkpeda7xghmbadm.gif" alt="Image description" width="228" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Download and install SCADE on your machine. You can find SCADE's latest version &lt;a href="https://www.scade.io/download/"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Learn how to create a SCADE project from scratch and give it any name of your choice.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In the event that you are absolutely uninitiated with the framework, click &lt;a href="https://docs.scade.io/docs/installation"&gt;here&lt;/a&gt; to install SCADE on your computer using the official documentation, and click &lt;a href="https://docs.scade.io/docs/getting-started"&gt;here&lt;/a&gt; to learn how to create your first project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;Place the images in this &lt;a href="https://github.com/scadedoc/UgExamples/tree/master/SimplyE/Assets"&gt;link&lt;/a&gt; into the Assets folder of your newly created project.&lt;/p&gt;

&lt;p&gt;Additionally, create a folder named &lt;strong&gt;managers&lt;/strong&gt; inside the project's root folder to hold all the necessary resources, including the classes (&lt;code&gt;Book class&lt;/code&gt;, &lt;code&gt;Genre class&lt;/code&gt;, and &lt;code&gt;CategoryManager&lt;/code&gt;) and API callers that are required to complete the app's development.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step One: Let´s build our manager folder
&lt;/h2&gt;

&lt;p&gt;Now, create the following three files inside the &lt;strong&gt;managers&lt;/strong&gt; folder:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8WY-hGED--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m7e9cisuyo2wvwtjstte.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8WY-hGED--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m7e9cisuyo2wvwtjstte.png" alt="Image description" width="557" height="155"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Make sure to create the &lt;code&gt;Genre class&lt;/code&gt;, &lt;code&gt;Book class&lt;/code&gt; and &lt;code&gt;TrendingBookResponse struct&lt;/code&gt; with each of them with their much-needed inheritance inside the &lt;code&gt;Book.swift&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Check this link in the project folder to see the &lt;a href="https://github.com/scadedoc/UgExamples/blob/master/SimplyE/Sources/SimplyE/managers/Book.swift"&gt;full code&lt;/a&gt; of the code snippet given below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cBLPyrKU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zkx2abdqymgdendswpvh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cBLPyrKU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zkx2abdqymgdendswpvh.png" alt="Image description" width="605" height="696"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The next thing is to connect our &lt;strong&gt;Book class model&lt;/strong&gt; to the API callers in the &lt;code&gt;ApiCaller.swift&lt;/code&gt; file to generate data for each of our four book categories (such as Adventurous Books, Fantasy Books, Horror Books, and Health Books) and searched books.&lt;/p&gt;

&lt;p&gt;View the &lt;a href="https://github.com/scadedoc/UgExamples/blob/master/SimplyE/Sources/SimplyE/managers/APICaller.swift"&gt;full code&lt;/a&gt; for the provided code snippet:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oUuAicJM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0bznu0htkh065srlt5vx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oUuAicJM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0bznu0htkh065srlt5vx.png" alt="Image description" width="800" height="722"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create inside the &lt;code&gt;CategoryManager.swift&lt;/code&gt; file a &lt;code&gt;CatalogManager class&lt;/code&gt; to house the &lt;code&gt;loadDataAsync&lt;/code&gt; and &lt;code&gt;fetchGenre&lt;/code&gt; methods that we'll use in loading our books images and connect book categories data to our main view (&lt;code&gt;main.page&lt;/code&gt;) respectively.&lt;/p&gt;

&lt;p&gt;Check out the &lt;a href="https://github.com/scadedoc/UgExamples/blob/master/SimplyE/Sources/SimplyE/managers/CategoryManager.swift"&gt;full code&lt;/a&gt; for the code snippet provided below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GX2W5o7X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zn8spqj2ysgyno8b5sqa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GX2W5o7X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zn8spqj2ysgyno8b5sqa.png" alt="Image description" width="800" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lastly, in this step, all the necessary methods we want for easy back-and-forth navigations of various pages of our app project are created inside the &lt;code&gt;Navigation.swift&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Check out the &lt;a href="https://github.com/scadedoc/UgExamples/blob/master/SimplyE/Sources/SimplyE/managers/Navigation.swift"&gt;complete code&lt;/a&gt; of the &lt;code&gt;Navigation.swift&lt;/code&gt; file's code sample supplied below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7GPBAw1R--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0bmtsm552kdm5i3ghrgk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7GPBAw1R--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0bmtsm552kdm5i3ghrgk.png" alt="Image description" width="800" height="1130"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step Two: Design the Launch Screen
&lt;/h2&gt;

&lt;p&gt;Create another folder named login inside the root folder of the project. The login folder is where we are going to be putting the newly created &lt;code&gt;login page&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8hwqvm57--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qytnggpg9w95jsx82lcf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8hwqvm57--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qytnggpg9w95jsx82lcf.png" alt="Image description" width="588" height="158"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We'll configure the &lt;code&gt;login page&lt;/code&gt; inside the &lt;code&gt;start.swift&lt;/code&gt; file to be the first screen visible to the users when the application's launched.&lt;/p&gt;

&lt;p&gt;We designed the login page to display a logo sitting centrally on an orange background, while some data for the next pages are being fetched:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ID8BIeiv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iy9sfmue09ufuw3dxuna.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ID8BIeiv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iy9sfmue09ufuw3dxuna.png" alt="Image description" width="800" height="520"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next is to write the logic that will make this page work. Inside the &lt;code&gt;Login.page.swift&lt;/code&gt; file, we created the &lt;code&gt;postDisplayActions()&lt;/code&gt; method to help users automatically navigate to the main page from the login page whenever the app is launched. &lt;/p&gt;

&lt;p&gt;That's not all, to make &lt;code&gt;postDisplayActions()&lt;/code&gt; method effective, we ensured that it's called inside the &lt;code&gt;show()&lt;/code&gt; method and not inside the &lt;code&gt;load()&lt;/code&gt;method:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--C5EWUveY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o8jog7ail0qtg142shod.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--C5EWUveY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o8jog7ail0qtg142shod.png" alt="Image description" width="742" height="733"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step Three: Build the Main Page
&lt;/h2&gt;

&lt;p&gt;Let’s build our main page. The main page is divided into three rows. The first row is occupied by the &lt;code&gt;heroImage&lt;/code&gt; and it works by randomly displaying the images of all books in each book category at a time. &lt;/p&gt;

&lt;p&gt;This &lt;code&gt;heroImage&lt;/code&gt; is given a &lt;code&gt;300 height&lt;/code&gt;. The &lt;code&gt;ctrlListBookCatalog&lt;/code&gt; in the second row is a List-Control designed to accommodate all our four book categories. The &lt;code&gt;toolBar&lt;/code&gt;, set to the far end of the page, is set to help users navigate to the &lt;code&gt;Search page&lt;/code&gt; and &lt;code&gt;More page&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lg2y0fmp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sqbdveof8df4xpjdheli.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lg2y0fmp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sqbdveof8df4xpjdheli.png" alt="Image description" width="800" height="520"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Below you have the &lt;code&gt;MainPageAdapter class&lt;/code&gt; that binds data from the model to the &lt;code&gt;ctrlListBookCatalog&lt;/code&gt; and &lt;code&gt;heroImage&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We also have to initialize the &lt;code&gt;items&lt;/code&gt; property of the &lt;code&gt;ctrlListBookCatalog&lt;/code&gt; with data from every book category method declared inside the &lt;code&gt;MainPageAdapter class&lt;/code&gt; so that all the visual controls defined inside the &lt;code&gt;ctrlListBookCatalog element&lt;/code&gt;, via the &lt;code&gt;elementProvider object&lt;/code&gt;, can display data assigned to them in the way they are configured. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;heroImage&lt;/code&gt; is defined inside the &lt;code&gt;showRandomBook() method&lt;/code&gt; to depend on the random image data assigned to &lt;code&gt;selectedBook variable&lt;/code&gt; from &lt;code&gt;randomBooks array&lt;/code&gt;. Finally, we have to call the &lt;code&gt;showRandomBook() method&lt;/code&gt; inside the &lt;code&gt;onEnter() method&lt;/code&gt; so that &lt;code&gt;heroImage&lt;/code&gt; can change to a different book image anytime a user enters the main page.&lt;/p&gt;

&lt;p&gt;Check out the &lt;a href="https://github.com/scadedoc/UgExamples/blob/master/SimplyE/Sources/SimplyE/main.page.swift"&gt;complete code&lt;/a&gt; for the code snippet provided below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VBpAAPFu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ohceua7hm721tip8t9nc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VBpAAPFu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ohceua7hm721tip8t9nc.png" alt="Image description" width="800" height="1421"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step Four: Let's work on the Book's Pages
&lt;/h2&gt;

&lt;p&gt;Once more, we'll create a new folder called &lt;code&gt;book pages&lt;/code&gt; inside the project's root folder. This newly created folder will have a subset of folders that includes the &lt;code&gt;bookDetail page&lt;/code&gt;, &lt;code&gt;bookWebview page&lt;/code&gt;, and &lt;code&gt;search page&lt;/code&gt;. Then, we'll create a page each into these subsets and call it &lt;code&gt;BookDetail.page&lt;/code&gt;, &lt;code&gt;bookWebview.page&lt;/code&gt;, and &lt;code&gt;search.page&lt;/code&gt; respectively:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--P78xoIof--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8a6orrm7lpy60fuu05oh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P78xoIof--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8a6orrm7lpy60fuu05oh.png" alt="Image description" width="321" height="266"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4a. Design and define the Logic for BookDetail.page
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;BookDetail.page&lt;/code&gt; is designed into a &lt;code&gt;navigationBar&lt;/code&gt;, &lt;code&gt;listBookDetails&lt;/code&gt;, &lt;code&gt;viewBookDescription&lt;/code&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;the &lt;code&gt;navigationBar&lt;/code&gt; contains a &lt;code&gt;backButton&lt;/code&gt; and a &lt;code&gt;detailsLabel&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;listBookDetails&lt;/code&gt; is set up to retain vital information about a book, including the book's cover image, title, author, page count, read-book button, etc.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;viewBookDescription&lt;/code&gt; is intended to only hold each book's overview and description labels&lt;/li&gt;
&lt;li&gt;Three  &lt;code&gt;toolBarItems&lt;/code&gt; created inside the  &lt;code&gt;toolBar&lt;/code&gt; allow users to go to the search page, the More page, or return to the main page.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BFM-PsHd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z7qdujenmuull3sb9rha.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BFM-PsHd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z7qdujenmuull3sb9rha.png" alt="Image description" width="800" height="520"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We declared a &lt;code&gt;book&lt;/code&gt; named variable of the type &lt;code&gt;Book&lt;/code&gt; class inside the &lt;code&gt;BookDetailPageAdapter&lt;/code&gt; class in the &lt;code&gt;BookDetail.page.swift&lt;/code&gt; file. The &lt;code&gt;show()&lt;/code&gt; method uses the &lt;code&gt;book&lt;/code&gt; variable as a medium to pass data to all the needed properties on the &lt;code&gt;BookDetail.page&lt;/code&gt;. However, if we don't downcast the &lt;code&gt;data&lt;/code&gt; parameter of the &lt;code&gt;show()&lt;/code&gt; method as an object of the &lt;code&gt;Book&lt;/code&gt; model and also assign it to the &lt;code&gt;data&lt;/code&gt; parameter of &lt;code&gt;super.show()&lt;/code&gt;, these properties won't display their respective assigned values on the &lt;code&gt;BookDetail.page&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;View the &lt;a href="https://github.com/scadedoc/UgExamples/blob/master/SimplyE/Sources/SimplyE/books%20page/BookDetail.page.swift"&gt;full code&lt;/a&gt; for the provided code snippet:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VP-O0p9X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2az0lum3171sliprab4q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VP-O0p9X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2az0lum3171sliprab4q.png" alt="Image description" width="745" height="745"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4b. Set up the bookWebView.page and provide its logic
&lt;/h3&gt;

&lt;p&gt;Only two rows make up the &lt;code&gt;BookDetail.page&lt;/code&gt;, which contains the &lt;code&gt;navigationBar&lt;/code&gt; and &lt;code&gt;webView&lt;/code&gt; controls:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The &lt;code&gt;navigationBar&lt;/code&gt;, which contains a &lt;code&gt;doneButton&lt;/code&gt;, &lt;code&gt;titleLabel&lt;/code&gt; and a &lt;code&gt;reloadButton&lt;/code&gt;, occupies the first row&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;doneButton&lt;/code&gt; is for returning to the books' detail page while the &lt;code&gt;reloadButton&lt;/code&gt; is for reloading the webpage of a book&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;webView&lt;/code&gt; control holds the second. We'll be using this &lt;code&gt;webView&lt;/code&gt; to load our books webpages whenever a user clicks on the &lt;code&gt;readBookButton&lt;/code&gt; on the &lt;code&gt;BookDetail.page&lt;/code&gt;:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--p-G_RRK8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k95gq05qzkorgvfirjk8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--p-G_RRK8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k95gq05qzkorgvfirjk8.png" alt="Image description" width="800" height="520"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As we did for the &lt;code&gt;BookDetail.page.swift&lt;/code&gt; file, we will also use the &lt;code&gt;show()&lt;/code&gt; method inside the &lt;code&gt;bookWebView.page.swift&lt;/code&gt; file. This simply means we'll need to connect the &lt;code&gt;webView&lt;/code&gt; control to books' webpage data inside the &lt;code&gt;show()&lt;/code&gt; method in order to successfully load the webpages of our books inside our app when a user clicks the &lt;code&gt;readBookButton&lt;/code&gt; on the &lt;code&gt;BookDetail.page&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pC7g3K9Y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uzywwrmuggnnkud5lils.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pC7g3K9Y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uzywwrmuggnnkud5lils.png" alt="Image description" width="800" height="956"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4c. Establish the search.page's layout and logic.
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;search.page&lt;/code&gt; is divided into four rows, with the &lt;code&gt;horizontalTextboxView&lt;/code&gt; in the first row, the &lt;code&gt;searchLabelTitle&lt;/code&gt; in the second, the &lt;code&gt;ctrlListBooks&lt;/code&gt; in the third, and the &lt;code&gt;toolBar&lt;/code&gt; in the fourth, respectively:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The &lt;code&gt;horizontalTextboxView&lt;/code&gt; houses the &lt;code&gt;textbox&lt;/code&gt; control that listens to text changes when typing text into the keyboard to search for a particular book.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;ctrlListBooks&lt;/code&gt; loads all books in every category before it then loads the results of the related searched book in the &lt;code&gt;textbox&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;toolBarItems&lt;/code&gt; generated inside the &lt;code&gt;toolBar&lt;/code&gt; enable users to return to the &lt;code&gt;main page&lt;/code&gt; as well as access the &lt;code&gt;More page&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9E-cl-WH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5s6qxhv0k6gmotbjfl4u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9E-cl-WH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5s6qxhv0k6gmotbjfl4u.png" alt="Image description" width="800" height="520"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We are going to use the &lt;code&gt;elementProvider&lt;/code&gt; object to access and assign values to all the listed elements inside the &lt;code&gt;ctrlListBooks&lt;/code&gt;. That's not all, there is also a need to initialize the &lt;code&gt;items&lt;/code&gt; property of the &lt;code&gt;ctrlListBooks&lt;/code&gt; with the results of all the books categories API data so that we can have a list of all our books categories on the &lt;code&gt;ctrlListBooks&lt;/code&gt; of the &lt;code&gt;search.page&lt;/code&gt; during launch time. &lt;/p&gt;

&lt;p&gt;Secondly, we also need to call the &lt;code&gt;onTextChanged()&lt;/code&gt; method on the &lt;code&gt;textbox&lt;/code&gt; control on the &lt;code&gt;search.page&lt;/code&gt; so as to listen and use its &lt;code&gt;textbox.text&lt;/code&gt; to fetch searched book results from the &lt;code&gt;getBook()&lt;/code&gt; method and add the results to the &lt;code&gt;items&lt;/code&gt; property of the &lt;code&gt;ctrlListBooks&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Check out the &lt;a href="https://github.com/scadedoc/UgExamples/blob/master/SimplyE/Sources/SimplyE/books%20page/search%20page/search.page.swift"&gt;full code&lt;/a&gt; for the code snippet shown below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Le4I6kZf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fr52dylgwkmmkzl5wj56.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Le4I6kZf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fr52dylgwkmmkzl5wj56.png" alt="Image description" width="671" height="1415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Now you can run the app and enjoy the newly built eBook app using SCADE! This is just a little bit of what you can do with SCADE.&lt;/p&gt;

&lt;p&gt;The full source code of this tutorial can be found &lt;a href="https://github.com/scadedoc/UgExamples/tree/master/SimplyE"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>scade</category>
      <category>ios</category>
      <category>android</category>
      <category>mobile</category>
    </item>
    <item>
      <title>Authentication using FireBase in Cross-Platform Swift Apps</title>
      <dc:creator>Olanrewaju Olakunle</dc:creator>
      <pubDate>Fri, 20 Jan 2023 17:10:37 +0000</pubDate>
      <link>https://dev.to/cdfcreator/authentication-using-firebase-in-cross-platform-swift-apps-19p</link>
      <guid>https://dev.to/cdfcreator/authentication-using-firebase-in-cross-platform-swift-apps-19p</guid>
      <description>&lt;p&gt;An essential component of developing a new mobile app is creating the user onboarding flow, which includes the landing page, login and registration pages, etc. One of FireBase's major features, authentication, is very handy in navigating users through these opening screens of a mobile app.&lt;/p&gt;

&lt;p&gt;Notably, Firebase handles everything you need to handle on the server side (user management, OAuth, security, password storage, etc.), so you won't need to worry about the underlying server codes. You may protect your app's data and restrict access to only its users with the help of FireBase Security Rules.&lt;/p&gt;

&lt;p&gt;Firebase offers a variety of authentication options, including Email/Password, Google Sign-In, Facebook Sign-In, and Sign in with Apple, to name a few.&lt;/p&gt;

&lt;p&gt;We will go through implementing Email/ Password Authentication with a SCADE app in this first FireBase SCADE tutorial.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;To get started, click on this link to &lt;a href="https://github.com/Cdf-creator/Messenger/raw/main/Messenger.zip" rel="noopener noreferrer"&gt;download&lt;/a&gt; our starter SCADE Project, build and run the app in any simulator of your choice.&lt;/p&gt;

&lt;p&gt;You can also follow this link to download the &lt;a href="https://www.scade.io/download/" rel="noopener noreferrer"&gt;SCADE&lt;/a&gt; IDE if you haven't already done so.&lt;/p&gt;

&lt;h3&gt;
  
  
  The following is the structure breakdown of our starter project:
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fovzkh0nn8pyhe2ze9ecj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fovzkh0nn8pyhe2ze9ecj.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sources&lt;/strong&gt; – this folder houses the login, main, and signUp Page Builders that hold the login, landing page, and signUp UI screens respectively, along with their corresponding page.swift and page.svg files. &lt;/p&gt;

&lt;p&gt;Most importantly, the Sources folder also contains the start.swift file that represent the runtime entry point of any SCADE project. If you open this file, you would notice we set the root view controller of the current window to be the loginPage. In other words, this simply means the loginPage becomes the first screen we see anytime our app is run.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;build.yaml&lt;/code&gt; - this file sets the path to both Android and iOS specific settings of our app project. It includes the bundle id that we will require later on in this tutorial for FireBase Integration.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Package.swift&lt;/code&gt; - This Package manifest file will house the FireBase dependencies we'll be needing later on for this tutorial.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The navigation into each screen is done programmatically on each page's &lt;code&gt;page.swift&lt;/code&gt; &lt;strong&gt;file&lt;/strong&gt;. Also, these screens are more or less currently static as we are yet to add the FireBase support.&lt;/p&gt;

&lt;h2&gt;
  
  
  Diving to FireBase Integration
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Go to &lt;a href="https://console.firebase.google.com/" rel="noopener noreferrer"&gt;Firebase Console&lt;/a&gt; using your Gmail address and create a new project (name it as you wish). Once you’ve created a new Firebase project, go to its Firebase Dashboard, by simply clicking on it in Firebase. You ought to arrive at this screen:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgg6c1m2me6wabj7avd3q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgg6c1m2me6wabj7avd3q.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Click on the first button below the text &lt;strong&gt;"Get started by adding Firebase to your app"&lt;/strong&gt; to add a new iOS app to your project. Next, go to the iOS section of your project's &lt;code&gt;build.yaml&lt;/code&gt; file in SCADE and copy the &lt;code&gt;bundle Id&lt;/code&gt; and paste it as the input value of the &lt;code&gt;Apple bundle ID&lt;/code&gt; to register your app. If you’d prefer to use your own &lt;code&gt;bundle ID&lt;/code&gt;, make sure you update the Bundle Identifier of your project in SCADE:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fow48eiisby2ma8ccugbr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fow48eiisby2ma8ccugbr.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;After clicking on the &lt;strong&gt;Register-app&lt;/strong&gt; button, FireBase will generate a &lt;code&gt;GoogleService-Info.plist&lt;/code&gt; file, which you need to download and add to the &lt;strong&gt;Sources folder&lt;/strong&gt; of your project in SCADE:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdva3cl4sxfpszr2mrwws.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdva3cl4sxfpszr2mrwws.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;strong&gt;Google Firebase iOS SDKs&lt;/strong&gt; are a collection of libraries that are primarily used to integrate FireBase into mobile app projects. These &lt;strong&gt;Swift SDKs&lt;/strong&gt; serve as bridges between your SCADE apps and the FireBase backend, to put it simply.&lt;/p&gt;

&lt;p&gt;To install FireBase using SPM, open your project's &lt;code&gt;Package.swift&lt;/code&gt; &lt;strong&gt;file&lt;/strong&gt; and add the &lt;strong&gt;FireBase package details&lt;/strong&gt; under &lt;strong&gt;dependencies&lt;/strong&gt;. Also, add &lt;strong&gt;Firebase Auth&lt;/strong&gt; as the &lt;strong&gt;product target&lt;/strong&gt; under the &lt;strong&gt;targets path&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F73d69n5gcwjysxflsutz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F73d69n5gcwjysxflsutz.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Next, we &lt;code&gt;import FireBase&lt;/code&gt; to our already established &lt;code&gt;start.swift&lt;/code&gt; &lt;strong&gt;file&lt;/strong&gt; and add an initializer in &lt;code&gt;FirebaseApp.configure()&lt;/code&gt; to the &lt;code&gt;onFinishLaunching&lt;/code&gt; &lt;strong&gt;method&lt;/strong&gt; that would help in configuring FireBase for us:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Firlbp7dnkdhiz9kr8rfl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Firlbp7dnkdhiz9kr8rfl.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  FireBase Authentication
&lt;/h2&gt;

&lt;p&gt;In the sidebar, from the &lt;strong&gt;Build section&lt;/strong&gt; drop-down menu, click on &lt;strong&gt;Authentication&lt;/strong&gt; and navigate to the &lt;strong&gt;Sign-In Method&lt;/strong&gt; tab to select &lt;strong&gt;Email/Password&lt;/strong&gt; as your provider. Next, toggle the option that says &lt;strong&gt;"Allow users to sign up using their email address and password..."&lt;/strong&gt; on the next screen before finally clicking on the &lt;strong&gt;"Save" button&lt;/strong&gt; to enable selection:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fspjs041xtoi3r3yl40wz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fspjs041xtoi3r3yl40wz.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Registering a new User to FireBase Server
&lt;/h2&gt;

&lt;p&gt;The next step is to connect our SignUp screen to FireBase as the starter project only has the UI part done. &lt;/p&gt;

&lt;p&gt;For this project, the signUp screen handles the whole registration process. We have already created a &lt;code&gt;signUpButtonTapped&lt;/code&gt; &lt;strong&gt;method&lt;/strong&gt; inside the &lt;code&gt;signUp.page.swift&lt;/code&gt; &lt;strong&gt;file&lt;/strong&gt; to trigger the &lt;code&gt;signUpButton&lt;/code&gt; when pressed by a user. But only the logic that binds its textboxes was created for the starter project.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;textboxes logic&lt;/strong&gt; is checking that both the e-mail and password fields are not empty and that the password is at least 8 characters long. And if all the above is not met, a text indicating that all details must be entered correctly is shown below the password textbox. &lt;/p&gt;

&lt;p&gt;We needed to &lt;code&gt;import FirebaseAuth&lt;/code&gt; to have access to the &lt;code&gt;Auth.auth().createUser&lt;/code&gt; &lt;strong&gt;method&lt;/strong&gt; that helps in creating and securing authenticating users to FireBase and also error handling just to mention a few. &lt;/p&gt;

&lt;p&gt;Below the textboxes logic, inside the &lt;code&gt;signUpButtonTapped&lt;/code&gt; method, we added  the &lt;code&gt;Auth.auth().createUser&lt;/code&gt; &lt;strong&gt;method&lt;/strong&gt; to collect both the email and password values needed for creating a new user account in FireBase. We used its &lt;code&gt;completion handler&lt;/code&gt; to determine the status of the operation by retrieving the result if successful and printing the newly created user information to the console or by returning an error message depending on the type of &lt;code&gt;auth error&lt;/code&gt; received to the console if it fails:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuuddinndyyrt79vo6n9i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuuddinndyyrt79vo6n9i.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Going by the above method, you sure know that you have just created a new user on your FireBase project when an instance of the newly created user is printed on the console and the clicked button navigate you to the &lt;code&gt;main.page&lt;/code&gt; screen:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsa3f48mxeg94u1i3pk01.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsa3f48mxeg94u1i3pk01.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To see the registration details of the new user that just got created, navigate to the Users tab of the &lt;strong&gt;Authentication section&lt;/strong&gt; of your &lt;strong&gt;FireBase Console&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq0q6al921zg53btwwlmj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq0q6al921zg53btwwlmj.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Logging in an existing User on FireBase
&lt;/h2&gt;

&lt;p&gt;Now that the mechanism for creating new users is successfully accomplished, the next thing is to head to the &lt;code&gt;login.page.swift&lt;/code&gt; file and add a &lt;code&gt;Firebase Auth&lt;/code&gt; &lt;strong&gt;method&lt;/strong&gt; inside the already created &lt;code&gt;loginButtonTapped&lt;/code&gt; &lt;strong&gt;method&lt;/strong&gt; that is responsible for allowing users to sign into the app with their credentials.&lt;/p&gt;

&lt;p&gt;Similar to the &lt;code&gt;signUpButtonTapped&lt;/code&gt; &lt;strong&gt;method&lt;/strong&gt;, the &lt;code&gt;loginButtonTapped&lt;/code&gt; &lt;strong&gt;method&lt;/strong&gt; only currently contains the logic that controls its textboxes as at the time the starter project was created. The textboxes logic is the same as the one for the &lt;code&gt;signUpButtonTapped&lt;/code&gt; &lt;strong&gt;method&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Again, we are leveraging &lt;strong&gt;Firebase Auth SDK&lt;/strong&gt; to communicate with the &lt;strong&gt;Firebase instance&lt;/strong&gt; and make a login request via the provided email and passowrd values by users. &lt;/p&gt;

&lt;p&gt;The completion handler for the &lt;code&gt;Auth.auth().signIn&lt;/code&gt; &lt;strong&gt;call&lt;/strong&gt; returns an error that describes why the authentication fails which is depended on the type of auth error code received (e.g. &lt;code&gt;AuthErrorCode.invalidEmail&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;If there are no errors, a print statement indicating a successful sign-in of the user is sent to the terminal before finally navigating the signed-in user to the &lt;code&gt;main.page&lt;/code&gt; &lt;strong&gt;screen.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Note that the &lt;code&gt;login.page.swift&lt;/code&gt; file manages the login screen. Locate the &lt;code&gt;loginButtonTapped&lt;/code&gt; &lt;strong&gt;method&lt;/strong&gt; and add the following lines of code below the textboxes logic:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhgg0hwlbn7mlpoj94kyq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhgg0hwlbn7mlpoj94kyq.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2kt06fprffy4fn4oyeaf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2kt06fprffy4fn4oyeaf.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Signing Out a User on FireBase
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;logOutButtonTapped&lt;/code&gt; &lt;strong&gt;method&lt;/strong&gt; is created to clear the current user information and token locally while printing to the terminal a &lt;strong&gt;"Sign Out"&lt;/strong&gt; statement and navigating the signed-out user back to the &lt;strong&gt;login page&lt;/strong&gt; if successful. The method also throws an error if the sign-out process is not successful. &lt;/p&gt;

&lt;p&gt;Note, it's of good practice to check and make the &lt;code&gt;currentUser&lt;/code&gt; &lt;strong&gt;property&lt;/strong&gt; &lt;code&gt;nil&lt;/code&gt; to always have users signed out successfully before calling the &lt;strong&gt;FireBase sign-out method&lt;/strong&gt; responsible for signing out authentication:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuh6ah2b2xq8d7s0wqfbf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuh6ah2b2xq8d7s0wqfbf.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Favnv9iy2ci5j8tk434cw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Favnv9iy2ci5j8tk434cw.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This FireBase tutorial shows a step-by-step way of integrating &lt;strong&gt;Firebase Auth&lt;/strong&gt; into SCADE projects. We made use of some of the &lt;strong&gt;Firebase Auth methods&lt;/strong&gt; to implement the &lt;strong&gt;sign-up&lt;/strong&gt;, &lt;strong&gt;sign-in&lt;/strong&gt;, and &lt;strong&gt;sign-out&lt;/strong&gt; features for our app project for this tutorial. &lt;/p&gt;

&lt;p&gt;The Firebase integration in this tutorial is basic, so it will need many more features to build a complete standard mobile app.&lt;/p&gt;

&lt;p&gt;The complete source code for this tutorial is available on GitHub: &lt;a href="https://github.com/Cdf-creator/Messenger/tree/main/Messenger" rel="noopener noreferrer"&gt;Messenger&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>firebase</category>
      <category>swift</category>
      <category>ios</category>
      <category>scade</category>
    </item>
    <item>
      <title>How to Build and Run a Vapor Project on Native Open-Source MacOS Nimble Editor</title>
      <dc:creator>Olanrewaju Olakunle</dc:creator>
      <pubDate>Mon, 05 Dec 2022 16:06:04 +0000</pubDate>
      <link>https://dev.to/cdfcreator/how-to-build-and-run-a-vapor-project-on-native-open-source-macos-nimble-editor-5h02</link>
      <guid>https://dev.to/cdfcreator/how-to-build-and-run-a-vapor-project-on-native-open-source-macos-nimble-editor-5h02</guid>
      <description>&lt;p&gt;Vapor is an open-source Swift web framework built for developers interested in creating web apps and Restful APIs just to mention a few. Vapor's simplicity and flexibility make it simple to create a new project on the go thanks to its handy command line tool.&lt;/p&gt;

&lt;p&gt;The first part of this tutorial will take you step by step through creating a new Vapor project, and building and running it through the Native Open-Source MacOS Nimble Editor.&lt;/p&gt;

&lt;p&gt;Lastly, In the second part of this tutorial, we will also look at learning and creating our routes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Requirements:
&lt;/h2&gt;

&lt;p&gt;You'll need the following given below for this tutorial:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Nimble Code Editor&lt;/strong&gt; - &lt;a href="https://github.com/scade-platform/Nimble/releases" rel="noopener noreferrer"&gt;Download Here&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Swift 5.6&lt;/strong&gt; or &lt;strong&gt;later&lt;/strong&gt; - Including command line. Vapor-4 requires this.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;MacOS&lt;/strong&gt; - We choose this operating system for this tutorial to create a Vapor project.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Homebrew&lt;/strong&gt; - It's needed for installing the Vapor Toolbox. Run the &lt;a href="https://brew.sh" rel="noopener noreferrer"&gt;installation command&lt;/a&gt; in this link if you are yet to install Homebrew.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;After downloading and installing the Nimble editor from the aforementioned link, run the &lt;code&gt;swift --version&lt;/code&gt; command on your computer to verify that you have the most recent swift version installed:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8dh2kfnwdrjyh0hbogbi.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8dh2kfnwdrjyh0hbogbi.jpeg" alt="Image description" width="800" height="55"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's install the &lt;strong&gt;Vapor Toolbox&lt;/strong&gt; using &lt;strong&gt;Homebrew&lt;/strong&gt; as previously indicated before we can create our first Vapor project.&lt;/p&gt;

&lt;p&gt;The Vapor Toolbox is a special CLI tool that comprises handy utilities that we can use to create new Vapor projects. Though it's not required for using Vapor, it automatically helps to install all the dependencies that are required for vapor to run.&lt;/p&gt;

&lt;p&gt;Run the following command in the terminal to install Vapor:&lt;br&gt;&lt;br&gt;
&lt;code&gt;brew install vapor&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;After the complete installation of Vapor, enter the &lt;code&gt;vapor --help&lt;/code&gt; command on the terminal to double-check that it's correctly installed on your machine.&lt;/p&gt;

&lt;p&gt;And if it's correctly installed, the output of the &lt;code&gt;vapor --help&lt;/code&gt; command would be as follows:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa0qf18h76uhx7w7vcuur.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa0qf18h76uhx7w7vcuur.jpeg" alt="Image description" width="800" height="531"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Create your first Vapor project
&lt;/h2&gt;

&lt;p&gt;To create a new Vapor project from a template on your machine, enter into the terminal with the Vapor Toolbox's new project command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;vapor new [ProjectName]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Vapor will &lt;strong&gt;by default&lt;/strong&gt; ask you if you want to use &lt;code&gt;Fluent&lt;/code&gt; and/or &lt;code&gt;Leaf&lt;/code&gt;. We recommend you enter an &lt;code&gt;n&lt;/code&gt; for both questions. It would also ask and give you options on the type of database to work with:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjbpf5127osroegd013w2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjbpf5127osroegd013w2.png" alt="Image description" width="706" height="471"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Alternatively, run the command with the &lt;code&gt;-n&lt;/code&gt; option to create a Vapor project:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;vapor new [ProjectName] -n&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This will create a new folder in the current directory containing the project. The &lt;code&gt;-n&lt;/code&gt; flag added in the above method gives you a fundamental template to build on. It also saves you the stress of answering a no to the respective questions and does it automatically for you.&lt;/p&gt;

&lt;p&gt;You should see the resemblance of the screenshot below in your terminal if your project was created successfully:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn93gnp6gknkk3r2ur7xb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn93gnp6gknkk3r2ur7xb.png" alt="Image description" width="730" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Open the created project with the Nimble Editor
&lt;/h2&gt;

&lt;p&gt;Open your newly created project folder with Nimble and click the &lt;strong&gt;large rectangular "project launch selector button"&lt;/strong&gt; (found to the right of the &lt;strong&gt;Play&lt;/strong&gt; and &lt;strong&gt;Stop buttons&lt;/strong&gt; at the upper left of the window). Check that &lt;strong&gt;Mac&lt;/strong&gt; is chosen as the &lt;strong&gt;launch runtime&lt;/strong&gt;. Press the &lt;strong&gt;play button&lt;/strong&gt; to build and run your project:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnx01gjspvhjqco5goo9f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnx01gjspvhjqco5goo9f.png" alt="Image description" width="686" height="66"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Alternatively, you can also use the &lt;code&gt;Command + R&lt;/code&gt; keyboard shortcut to run your project.&lt;/p&gt;

&lt;p&gt;While your project is building, the required dependencies needed for the vapor project to successfully work are automatically downloaded and saved in the generated &lt;code&gt;Package.resolved&lt;/code&gt; &lt;strong&gt;file&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flgm9ulo3wbqk7y0ail69.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flgm9ulo3wbqk7y0ail69.jpeg" alt="Image description" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Please note that it will take some time to fetch and resolve the dependencies the first time you run your project. &lt;/p&gt;

&lt;p&gt;Visit &lt;a href="http://localhost:8080/hello" rel="noopener noreferrer"&gt;localhost:8080/hello&lt;/a&gt; and &lt;a href="http://127.0.0.1:8080/" rel="noopener noreferrer"&gt;http://127.0.0.1:8080&lt;/a&gt; in any browser of your choice while your project is running to see the responses shown in the screenshots below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fajhhgaz581nbik7jdc2u.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fajhhgaz581nbik7jdc2u.jpeg" alt="Image description" width="800" height="334"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fejvjbfi3on7qt0yk0mku.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fejvjbfi3on7qt0yk0mku.jpeg" alt="Image description" width="800" height="335"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You should also be able to see each request you make to the server in your console as your project is running:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8crevwfs4mz89067efcf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8crevwfs4mz89067efcf.png" alt="Image description" width="800" height="188"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating our own GET and Post Routes
&lt;/h2&gt;

&lt;p&gt;Now that we have successfully created our first app, let's delete the contents in the &lt;code&gt;routes.swift&lt;/code&gt; file of our project folder and add new routes with Vapor:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Creating our Get Route
&lt;/h3&gt;

&lt;p&gt;Replace the content of the &lt;code&gt;routes.swift&lt;/code&gt; file with the following code in the screenshot below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkxg0bezwi572r1n29h5k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkxg0bezwi572r1n29h5k.png" alt="Image description" width="800" height="419"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Use the &lt;strong&gt;play button&lt;/strong&gt; or the &lt;strong&gt;build&lt;/strong&gt; and &lt;strong&gt;run commands&lt;/strong&gt; to build and run the project again. You should see the response shown in the screenshot below when you visit &lt;a href="http://localhost:8080/name" rel="noopener noreferrer"&gt;http://localhost:8080/name&lt;/a&gt; in your preferred browser:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd6fe9e80ul3st2ddz2s8.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd6fe9e80ul3st2ddz2s8.jpeg" alt="Image description" width="800" height="334"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. How to create a Route that takes a Parameter
&lt;/h3&gt;

&lt;p&gt;When not required, it becomes redundant to always establish a new route for every response. We can use &lt;strong&gt;a new route as a parameter&lt;/strong&gt; and process it to provide a response as required by the parameter. We must always &lt;strong&gt;include a parameter after a route&lt;/strong&gt; in any request URL we are creating.&lt;/p&gt;

&lt;p&gt;For instance, we use &lt;code&gt;:name&lt;/code&gt; to create a &lt;strong&gt;dynamic parameter&lt;/strong&gt; for our route. The idea here is to extract the user's name that is passed in the Request object else an error should be thrown if the &lt;code&gt;name&lt;/code&gt; &lt;strong&gt;parameter&lt;/strong&gt; can't be found. Finally, we return a string with a Hello greeting together with the extracted user's name as the main response:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F906y5sxb0ceurn5n43j8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F906y5sxb0ceurn5n43j8.png" alt="Image description" width="800" height="385"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Rebuild and run the Vapor project after the above is accomplished. Use &lt;code&gt;John&lt;/code&gt; as the &lt;strong&gt;parameter value example&lt;/strong&gt; in the request URL. You should see the response shown in the screenshot below when you visit &lt;a href="http://localhost:8080/hello/John" rel="noopener noreferrer"&gt;http://localhost:8080/hello/John&lt;/a&gt; in your preferred browser:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbe2ieklbpy7owra9zox5.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbe2ieklbpy7owra9zox5.jpeg" alt="Image description" width="800" height="331"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Returning JSON
&lt;/h3&gt;

&lt;p&gt;We can still check out a lot more aspects of Vapor outside just creating a route with or without a parameter. It's quite an easy task to use Vapor to return &lt;strong&gt;JSON objects&lt;/strong&gt; in route handlers. Most importantly, Vapor uses the &lt;code&gt;Content protocol&lt;/code&gt; to encode a response as a JSON object. The &lt;code&gt;Content protocol&lt;/code&gt; is a wrapper around &lt;code&gt;Codable&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If we need to return a &lt;strong&gt;JSON object&lt;/strong&gt; as the response of a route, we may first need to create a &lt;strong&gt;struct&lt;/strong&gt; that &lt;strong&gt;conforms&lt;/strong&gt; to &lt;code&gt;Content protocol&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For instance, we created both &lt;code&gt;DataCollection&lt;/code&gt; and &lt;code&gt;IndividualData&lt;/code&gt; objects to represent the &lt;strong&gt;JSON API response&lt;/strong&gt;. Also, as previously mentioned, we ensured both objects conform to the &lt;code&gt;Content protocol&lt;/code&gt; as this will come in handy when encoding the API response json to &lt;code&gt;DataCollection&lt;/code&gt; object:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffiwyihskmzmy2oifguyn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffiwyihskmzmy2oifguyn.png" alt="Image description" width="397" height="340"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, We created a method that returns the &lt;code&gt;DataCollection&lt;/code&gt; object. Finally, our &lt;strong&gt;"/json"&lt;/strong&gt; endpoint now returns the data object which contains an array of different names with their respective ages:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0k0ooeo4z9cp7rlgbu5p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0k0ooeo4z9cp7rlgbu5p.png" alt="Image description" width="800" height="553"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Build and run the Vapor project once more. Visit &lt;a href="http://localhost:8080/json" rel="noopener noreferrer"&gt;http://localhost:8080/json&lt;/a&gt; in your preferred browser simultaneously, and you ought to see the response displayed in the screenshot below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwrdfbphujmoigeu6hcnp.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwrdfbphujmoigeu6hcnp.jpeg" alt="Image description" width="800" height="325"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Handling POST request
&lt;/h3&gt;

&lt;p&gt;A POST request has a body that accepts an object as input. In other words, a POST method does the work of creating an object and saving it in a server database. We are going to use &lt;strong&gt;Postman&lt;/strong&gt; to pass some data via a &lt;strong&gt;POST request&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;We are going to use a client like postman to pass the request object with the &lt;code&gt;gender&lt;/code&gt; property in our created &lt;code&gt;DataKind&lt;/code&gt; struct object:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5ac2m98q56icwcdn17o4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5ac2m98q56icwcdn17o4.png" alt="Image description" width="337" height="193"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When we send a &lt;strong&gt;post request&lt;/strong&gt; using &lt;strong&gt;Postman&lt;/strong&gt;, this request object will be received on our server. Check the screenshot below to see the added code we used in getting the incoming request. Its processing and how we returned the &lt;code&gt;DataCollection&lt;/code&gt; object:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmpe8tlu30rq7188emtzo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmpe8tlu30rq7188emtzo.png" alt="Image description" width="397" height="340"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, build and run the Vapor project one more time, and simultaneously open &lt;strong&gt;Postman&lt;/strong&gt; to set the request to be &lt;code&gt;POST&lt;/code&gt; and the URL to &lt;a href="http://localhost:8080/gender-group" rel="noopener noreferrer"&gt;http://localhost:8080/gender-group&lt;/a&gt;. That's not all, under the &lt;strong&gt;Body tab&lt;/strong&gt;, select &lt;strong&gt;form-data&lt;/strong&gt; as the type. Afterward, create a &lt;code&gt;gender&lt;/code&gt; &lt;strong&gt;key&lt;/strong&gt; and set its &lt;strong&gt;value&lt;/strong&gt; to &lt;code&gt;males&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqw5qufyp45lxlitelgqt.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqw5qufyp45lxlitelgqt.jpeg" alt="Image description" width="800" height="256"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You should be able to see the response in the &lt;strong&gt;POST's body request&lt;/strong&gt; after pressing the &lt;strong&gt;Send button&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftzmplyisx4rpd3ypnahr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftzmplyisx4rpd3ypnahr.png" alt="Image description" width="800" height="660"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;This tutorial gives a general overview of how to get started with Vapor and how to use the Nimble editor to create basic GET and POST routes.&lt;/p&gt;

&lt;p&gt;The source code for this tutorial is available on GitHub: &lt;a href="https://github.com/Cdf-creator/VaporDemo" rel="noopener noreferrer"&gt;VaporDemo&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>watercooler</category>
    </item>
    <item>
      <title>Textbox Control Guide on Native CrossPlatform Swift Mobile Apps</title>
      <dc:creator>Olanrewaju Olakunle</dc:creator>
      <pubDate>Tue, 18 Oct 2022 14:35:49 +0000</pubDate>
      <link>https://dev.to/cdfcreator/textbox-control-guide-on-native-crossplatform-swift-mobile-apps-29c</link>
      <guid>https://dev.to/cdfcreator/textbox-control-guide-on-native-crossplatform-swift-mobile-apps-29c</guid>
      <description>&lt;p&gt;The Textbox control's fundamental concept is to accept user input. By default, it writes on its textfield the word &lt;strong&gt;"Enter"&lt;/strong&gt; and also takes a single line of text. However, you can make it accept multiple texts too. &lt;/p&gt;

&lt;p&gt;A Textbox in &lt;a href="https://www.scade.io/download/"&gt;SCADE&lt;/a&gt; collects inputs from the keyboard into an app. We can use Textbox Control in many mobile apps to build forms, send messages, create search experiences, and many more. Use it as an input element.&lt;/p&gt;

&lt;p&gt;The Textbox control in SCADE has a lot of properties and a few methods that we can use to configure it to the taste of our mobile app project - we'll go over a number of them in this tutorial.&lt;/p&gt;

&lt;h2&gt;
  
  
  Some Key Textbox Control's Properties
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;Name&lt;/code&gt;: The name of a given Textbox control.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Text&lt;/code&gt;: a default text value shown by the textfield.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Placeholder&lt;/code&gt;: It's used for displaying the hint text inside the textfield.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Secure&lt;/code&gt;: makes use of iOS and Android masking characters to hide texts.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Accessability&lt;/code&gt;: accepts texts to help impaired.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Tab Index&lt;/code&gt;: order of the textfields.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Keyboard&lt;/code&gt;: It has two attributes (&lt;code&gt;OnTop&lt;/code&gt; and &lt;code&gt;Resize&lt;/code&gt;) that you can use to configure how the keyboard is displayed.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Keyboard type&lt;/code&gt;: it provides an option to have the keyboard set numerically or alphabetically. Note that you can only do this using the &lt;code&gt;keyboardType&lt;/code&gt; property (the page builder currently has no support for this).&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Some Key Textbox Control's Properties
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;onEditFinished&lt;/code&gt;: thanks to this method, you can capture when a user presses return or the tab key or leave the control to show that they are done editing a text.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;onTextChanged&lt;/code&gt;: you can simply use this to listen to the changes made to the value of a textfield.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;hideKeyboard&lt;/code&gt;: it simply does the work of hiding the keyboard for us via code.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Both the &lt;code&gt;onEditFinished&lt;/code&gt; and &lt;code&gt;onTextChanged&lt;/code&gt; methods have two important properties known as &lt;code&gt;newValue&lt;/code&gt; and &lt;code&gt;oldValue&lt;/code&gt; for listening and capturing a textfield value.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementation
&lt;/h2&gt;

&lt;p&gt;In this tutorial, we are going to learn how to use the textbox control by creating two textboxes that require users to enter their names and unique password.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting an Initial Text for the Textboxes
&lt;/h2&gt;

&lt;p&gt;After adding textboxes to your page builder (via the &lt;code&gt;Widget Palette&lt;/code&gt;), click on any of them to have access to the textbox control properties. The &lt;code&gt;Text&lt;/code&gt; attribute, found at the top-right side of your page builder, is used to set a default value for textboxes. A textbox control displays these initial text values first whenever an app is launched.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;See the screenshot below as a guide:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hOtfXOij--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n3u8phogr31uxr69y6fm.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hOtfXOij--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n3u8phogr31uxr69y6fm.jpeg" alt="Image description" width="880" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also, depending on the &lt;code&gt;layout container&lt;/code&gt; you decided to work with, you can use a layout container's properties to configure each of your textbox to the size and position you want them displayed on your mobile page.&lt;/p&gt;

&lt;p&gt;For instance, we built this tutorial on an &lt;strong&gt;Autolayout container&lt;/strong&gt; and use its constraints property to set the two textboxes (named &lt;code&gt;nameTextbox&lt;/code&gt; and &lt;code&gt;passwordTextbox&lt;/code&gt;) horizontally centered and give them the same height and width. It also allows us to set the top-constraint of the &lt;code&gt;nameTextbox&lt;/code&gt; and that of the &lt;code&gt;passwordTextbox&lt;/code&gt; to just 40-points and 30-points below the &lt;code&gt;NavBar&lt;/code&gt; and &lt;code&gt;nameTextbox&lt;/code&gt; respectively:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ez0Zex_t--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gixoktxrzsaxmtkxws1a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ez0Zex_t--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gixoktxrzsaxmtkxws1a.png" alt="Image description" width="880" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--13ws1UIW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d402fo715zafgi2y4heo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--13ws1UIW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d402fo715zafgi2y4heo.png" alt="Image description" width="880" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Output on iOS:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7OY_vv48--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cq6jcbctl2shedvo75t6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7OY_vv48--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cq6jcbctl2shedvo75t6.png" alt="Image description" width="277" height="561"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Output on Android:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qJWSX_gI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5vipymy97o5cybjapcyw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qJWSX_gI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5vipymy97o5cybjapcyw.png" alt="Image description" width="283" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a Multiline Textbox
&lt;/h2&gt;

&lt;p&gt;Textbox control has a &lt;strong&gt;multiline&lt;/strong&gt; property that allows users to input text over multiple lines. You can easily activate this feature on the textbox(es) of your mobile app project by checking the &lt;code&gt;Multiline&lt;/code&gt; attribute just underneath the &lt;code&gt;Text&lt;/code&gt; property of the Textbox control you are working on in the page builder of your &lt;strong&gt;SCADE IDE&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8T9DWwxt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mo0hdwdspjqavu403hs9.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8T9DWwxt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mo0hdwdspjqavu403hs9.jpeg" alt="Image description" width="880" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding Placeholder on Textfield in SCADE
&lt;/h2&gt;

&lt;p&gt;Placeholders are used to provide users with a notion of the input values that the textfield will take. In other words, the &lt;code&gt;Placeholder&lt;/code&gt; property may offer a hint to users of the input that is expected of them in a Textbox control. The hint text disappears when users click inside the textbox and start inputting texts. The default color is grey, however, you may change it through the &lt;code&gt;color&lt;/code&gt; element of the &lt;code&gt;Text&lt;/code&gt; Property:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HQECxeTy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zx226616jh6wmav4pbq3.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HQECxeTy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zx226616jh6wmav4pbq3.jpeg" alt="Image description" width="880" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Output on iOS:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DE4yVGkd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iz9pfujy9b3mgek55odr.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DE4yVGkd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iz9pfujy9b3mgek55odr.gif" alt="Image description" width="240" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Output on Android:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--P0LaUBmg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0a6qgqcnfidlhe926fy0.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P0LaUBmg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0a6qgqcnfidlhe926fy0.gif" alt="Image description" width="228" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How to retrieve the value of a TextField?
&lt;/h2&gt;

&lt;p&gt;SCADE has two main methods you can use to retrieve users' text value: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;onEditFinished method:&lt;/strong&gt; The &lt;code&gt;onEditFinished&lt;/code&gt; method is of type &lt;code&gt;SCDWidgetsEditFinishEventHandler&lt;/code&gt; and it basically listens when a user clicks on the &lt;code&gt;return&lt;/code&gt; key or &lt;code&gt;tab&lt;/code&gt; key on the keyboard. Another way the &lt;code&gt;onEditFinished&lt;/code&gt; method can be called in SCADE is when users leave a Textbox control completely after inputting or editing a text. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Below is the sample code:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gLDatY77--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8xv1zdzqkbt51hwcrowi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gLDatY77--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8xv1zdzqkbt51hwcrowi.png" alt="Image description" width="880" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For instance, in the screenshot below, the &lt;code&gt;onEditFinshed&lt;/code&gt; method prints to the &lt;strong&gt;IDE terminal&lt;/strong&gt; the textfield value of the &lt;code&gt;nameTextbox&lt;/code&gt; each time either the &lt;code&gt;return&lt;/code&gt; key or &lt;code&gt;tab&lt;/code&gt; key is pressed:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--j5EvEEWU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9y497coqyy5bkonhx8m4.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--j5EvEEWU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9y497coqyy5bkonhx8m4.jpeg" alt="Image description" width="880" height="550"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;onTextChanged method:&lt;/strong&gt; This second method is of type &lt;code&gt;SCDWidgetsTextChangeEventHandler&lt;/code&gt; and it works in a completely different way compared to the aforementioned. The &lt;code&gt;onTextChanged&lt;/code&gt; method captures a changed textfield value when called upon.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Below is the sample code:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VQfCuroC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vjn2c8vgqu5vuahk1s0p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VQfCuroC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vjn2c8vgqu5vuahk1s0p.png" alt="Image description" width="880" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For example, as shown in the illustration below, the &lt;code&gt;onTextChanged&lt;/code&gt; method prints to the &lt;strong&gt;IDE terminal&lt;/strong&gt; each time the textfield value of the &lt;code&gt;nameTextbox&lt;/code&gt; changes:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GIqf9pnv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jdypc9w5ganagro15izz.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GIqf9pnv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jdypc9w5ganagro15izz.jpeg" alt="Image description" width="880" height="550"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Changing from an Alphabetical to a Numeric Keyboard
&lt;/h2&gt;

&lt;p&gt;SCADE Textbox control has a &lt;code&gt;keyboardType&lt;/code&gt; property that you can use to change the default keyboard type of a textfield from &lt;code&gt;alphabetical&lt;/code&gt; to &lt;code&gt;numeric&lt;/code&gt; in your app project. For example, we switched the keyboard type of &lt;code&gt;passwordTextbox&lt;/code&gt; in our project sample from accepting &lt;code&gt;alphabetical&lt;/code&gt; input to &lt;code&gt;numeric&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Below is the sample code:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4yVJTLeR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zrz70ao4grvmszr0tweg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4yVJTLeR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zrz70ao4grvmszr0tweg.png" alt="Image description" width="880" height="346"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Output on iOS:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_ZkNag96--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vnrv5emkzzzlfzr1zds8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_ZkNag96--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vnrv5emkzzzlfzr1zds8.gif" alt="Image description" width="240" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Output on Android:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XDsOnR8W--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q5mf73pfktvc31qo25h8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XDsOnR8W--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q5mf73pfktvc31qo25h8.gif" alt="Image description" width="228" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Masking Textfield Values inside a Textbox Control in SCADE
&lt;/h2&gt;

&lt;p&gt;Another important SCADE Textbox control attribute is the &lt;code&gt;Secure&lt;/code&gt; property. Its function is to obscure textfield values from being easily readable or understandable and it's commonly used on a textfield that contains a password.  &lt;/p&gt;

&lt;p&gt;We activated this feature on the &lt;code&gt;passwordTextbox&lt;/code&gt; of our sample project by checking on the &lt;code&gt;Secure box&lt;/code&gt; beneath the &lt;code&gt;Placeholder&lt;/code&gt; property of the Textbox control in the page builder of SCADE IDE:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UeeeGRLa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ve3wwv70qk13v6o5apc3.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UeeeGRLa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ve3wwv70qk13v6o5apc3.jpeg" alt="Image description" width="880" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Output on iOS:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HlUTBtGz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jf8fzxkuwe3qbsoix0dy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HlUTBtGz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jf8fzxkuwe3qbsoix0dy.gif" alt="Image description" width="240" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Output on Android:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--K42nYmmz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m5d2mjhvr1mn3yu912oq.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--K42nYmmz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m5d2mjhvr1mn3yu912oq.gif" alt="Image description" width="228" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This tutorial has taught us how to use a Textbox control in a Cross-Platform Swift mobile app that requires user input. Most importantly, we covered all the important properties and methods of SCADE Textbox control that can make the aforementioned possible.&lt;/p&gt;

&lt;p&gt;The source code for this tutorial is available on GitHub: &lt;a href="https://github.com/Cdf-creator/Textbox-Control"&gt;Textbox-Control&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>mobile</category>
      <category>swift</category>
      <category>ios</category>
      <category>android</category>
    </item>
    <item>
      <title>Slider Feature on Native CrossPlatform Swift Mobile Apps</title>
      <dc:creator>Olanrewaju Olakunle</dc:creator>
      <pubDate>Fri, 07 Oct 2022 15:16:31 +0000</pubDate>
      <link>https://dev.to/cdfcreator/slider-feature-on-native-crossplatform-swift-mobile-apps-156k</link>
      <guid>https://dev.to/cdfcreator/slider-feature-on-native-crossplatform-swift-mobile-apps-156k</guid>
      <description>&lt;p&gt;Slider control, commonly known as Carousel Slider on iOS and Android, is one of the most often used image sliders in most mobile apps such as eCommerce apps, social media apps, etc. nowadays. Slider Control is used in these mobile apps mostly for showing products, images, advertisements, and other content.&lt;/p&gt;

&lt;p&gt;Thanks to &lt;a href="https://www.scade.io/download/"&gt;SCADE&lt;/a&gt;, mobile developers can now simply implement an image slider from scratch into their app projects with ease. This alone can help improve user experience as users can easily use this interesting feature to swipe left and right to see different items of their choice. &lt;/p&gt;

&lt;p&gt;In this article, you will learn how to use the Page Editor to implement and customize the Slider Control feature for your SCADE project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Slider Control's Properties:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;Items&lt;/code&gt;:   This property contains the data we want the slider to display. We use it to store the asset images for this project.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;elementProvider&lt;/code&gt;: It is of type &lt;code&gt;SCDWidgetsElementProvider&lt;/code&gt; responsible for mapping data to the slider's elements' visual controls.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;elements&lt;/code&gt;: serve as a container for the slider's visual controls.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;onSlide&lt;/code&gt;: It has an event handler that uses its &lt;code&gt;to-and-from properties&lt;/code&gt; to detect slide events.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;selected&lt;/code&gt;: used for sliding to a specific item.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Implementation
&lt;/h2&gt;

&lt;p&gt;You must follow the steps below to implement this feature in your SCADE project:&lt;/p&gt;

&lt;h2&gt;
  
  
  Step1: Bind the slider's element to data from a defined Class
&lt;/h2&gt;

&lt;p&gt;You can simply use a simpler data type or a class to describe the data container. Mind you, if you are going with the latter, you will need to make your newly created &lt;code&gt;class&lt;/code&gt; a &lt;code&gt;subclass&lt;/code&gt; of the &lt;code&gt;EObject class&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;The screenshot below shows how to achieve this with a named &lt;code&gt;class&lt;/code&gt; called &lt;code&gt;Pic&lt;/code&gt; created in the &lt;code&gt;main.page.swift&lt;/code&gt; file of our project:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--t_MJLtif--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/48vjive1j9ky0pypkcq8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--t_MJLtif--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/48vjive1j9ky0pypkcq8.png" alt="Image description" width="880" height="322"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step2: Design the Page Editor
&lt;/h2&gt;

&lt;p&gt;Firstly, use the &lt;code&gt;Show Widget Palette&lt;/code&gt; attribute of the SCADE-IDE to add (drag and drop) and center (if you want it centered on your app screen) the slider control widget to the &lt;code&gt;main.page&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Lxpnw5or--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4rppnx2l8ph4fx16gcdd.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Lxpnw5or--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4rppnx2l8ph4fx16gcdd.jpeg" alt="Image description" width="880" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step3: Define the logic for connecting data to Visual Controls
&lt;/h2&gt;

&lt;p&gt;Next, use the slider's &lt;code&gt;elementProvider&lt;/code&gt; property to define a provider object that is of type &lt;code&gt;SCDWidgetsElementProvider&lt;/code&gt;. The defined provider object (of type SCDWidgetsElementProvider) is tasked with the duty of populating data to the slider's display element controls. &lt;/p&gt;

&lt;p&gt;For instance, we use the provider object we created inside &lt;code&gt;SCDWidgetsElementProvider&lt;/code&gt; to connect the &lt;code&gt;image1 control&lt;/code&gt; that we added inside the slider control in the previous step to the data container:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xle4hfiC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kfs6f9r75cr99nbhbatf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xle4hfiC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kfs6f9r75cr99nbhbatf.png" alt="Image description" width="880" height="226"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step4: Provide the Data Container with the image data
&lt;/h2&gt;

&lt;p&gt;Ensure the Data Container we have created in the first step has valid access to the data we want the slider control to have an effect on. &lt;/p&gt;

&lt;p&gt;As an illustration for this tutorial, we added the images we want the slider control to have an effect on to the Assets folder since that's what we initially provided in the Data Container to house the images to be displayed:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TUpFoY2Y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/thvxx8ct4fznzhmmsnfz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TUpFoY2Y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/thvxx8ct4fznzhmmsnfz.png" alt="Image description" width="880" height="376"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That’s not all, the slider's &lt;code&gt;items&lt;/code&gt; property also needs to store the list of images (i.e. data) before the slider can get to display them. &lt;/p&gt;

&lt;p&gt;For this tutorial, we simply used the created &lt;code&gt;filename&lt;/code&gt; parameter (of type &lt;code&gt;String&lt;/code&gt;) of the &lt;code&gt;Pic class&lt;/code&gt; to collect the correct names of each image and store them as a list to the slider's &lt;code&gt;items&lt;/code&gt; property:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4xhQRBuS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qz9bmck9u6mr53w4pz4a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4xhQRBuS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qz9bmck9u6mr53w4pz4a.png" alt="Image description" width="880" height="151"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Output on iOS:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZlXuHETf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pa3shzbzv7kne8dw1i20.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZlXuHETf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pa3shzbzv7kne8dw1i20.gif" alt="Image description" width="238" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Output on Android:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--91Jlhwdu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0sdubr4x265asmsgru8f.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--91Jlhwdu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0sdubr4x265asmsgru8f.gif" alt="Image description" width="228" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Additional Features
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;h2&gt;
  
  
  Enable Slide Event
&lt;/h2&gt;

&lt;p&gt;You can simply use the slider's &lt;code&gt;onSlide&lt;/code&gt; property to listen to sliding events via the &lt;code&gt;to&lt;/code&gt; and &lt;code&gt;from&lt;/code&gt; attributes of the &lt;code&gt;SCDWidgetsSlideEventHandler&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SafmsHi3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6aqmkftb825qrdn34vav.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SafmsHi3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6aqmkftb825qrdn34vav.png" alt="Image description" width="880" height="141"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In other words, this feature enables you to determine the precise position of an item and perhaps use the information to improve your app project.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h2&gt;
  
  
  How to Slide to a Specific Item
&lt;/h2&gt;

&lt;p&gt;Aside from achieving the above output, you can also use another slider property called &lt;code&gt;selected&lt;/code&gt; to start the slide from a particular item.&lt;/p&gt;

&lt;p&gt;How do you achieve this? It’s simple, initialize the &lt;code&gt;selected&lt;/code&gt; property to the index of the item (image) of your choice. For example, you can set &lt;code&gt;selected&lt;/code&gt; = 1 so that the slider control can go to the 2nd item since the item count begins at 0:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zyjnxMds--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1h0ocuwpnkx3xx88p8r6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zyjnxMds--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1h0ocuwpnkx3xx88p8r6.png" alt="Image description" width="880" height="258"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; this can only be achieved in the &lt;code&gt;show method&lt;/code&gt; (and not in the &lt;code&gt;load method&lt;/code&gt;).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h2&gt;
  
  
  Having access to a more generic elementProvider
&lt;/h2&gt;

&lt;p&gt;We have used the simpler approach of the &lt;code&gt;elementProvider&lt;/code&gt; in the earlier part of this tutorial to connect data to the visual control inside the slider control of our project. However, a generic &lt;code&gt;elementProvider&lt;/code&gt; can also accomplish the same thing and even give you access to more technical attributes that you can use to configure your slider.&lt;/p&gt;

&lt;p&gt;For example, we use the position property of this &lt;code&gt;elementProvider&lt;/code&gt; to connect data from the&lt;br&gt;
&lt;code&gt;items&lt;/code&gt; property of the slider to the visual control:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6aCNDbgz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ercfk9qfpe9bbukn0l3d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6aCNDbgz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ercfk9qfpe9bbukn0l3d.png" alt="Image description" width="880" height="619"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I covered how to create and use a slider control in Cross Platform Swift mobile apps in this article. We also learned how to add some new features and adjust the slider control to our liking.&lt;/p&gt;

&lt;p&gt;The source code for this tutorial is available on GitHub: &lt;a href="https://github.com/Cdf-creator/SliderControl"&gt;Slider Control&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>scade</category>
      <category>swift</category>
      <category>ios</category>
      <category>android</category>
    </item>
    <item>
      <title>AutoCompletion in Native Open-Source MacOS Nimble Editor</title>
      <dc:creator>Olanrewaju Olakunle</dc:creator>
      <pubDate>Tue, 27 Sep 2022 11:56:52 +0000</pubDate>
      <link>https://dev.to/cdfcreator/autocompletion-in-native-open-source-macos-nimble-editor-3ekg</link>
      <guid>https://dev.to/cdfcreator/autocompletion-in-native-open-source-macos-nimble-editor-3ekg</guid>
      <description>&lt;p&gt;Autocomplete is a workspace feature normally used to suggest code snippets as developers type in their IDEs and Code Editors. Software developers no longer have to keep track of programming syntax, API method names and details, and other essential information because of this fantastic code editing feature.&lt;/p&gt;

&lt;p&gt;This article aims to provide a better understanding of how the &lt;a href="https://github.com/scade-platform/Nimble"&gt;Nimble&lt;/a&gt; editor autocompletes codes by displaying a completion pop-up as you type to reduce the amount of time you spend typing and allowing you to view and insert potential completions from a list of suggestions to the statement that is currently under your cursor in the code editor.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding the Concept of AutoCompletion
&lt;/h2&gt;

&lt;p&gt;Nimble's AutoCompletion feature is tasked with the responsibility of assisting you finish off the names of &lt;code&gt;classes&lt;/code&gt;, &lt;code&gt;methods&lt;/code&gt;, &lt;code&gt;fields&lt;/code&gt;, and &lt;code&gt;keywords&lt;/code&gt; within the visibility scope. Nimble analyses the context in question when invoking Autocompletion and make suggestions that are reachable from the current cursor position (suggestions also include Live templates). &lt;/p&gt;

&lt;p&gt;For instance, If AutoCompletion is applied to a part of a named &lt;code&gt;method&lt;/code&gt; in a given &lt;code&gt;class&lt;/code&gt;, Nimble help display a list of possible results based on the item type:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UcMlacNz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pg9ntxuy05tlkmne4jrp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UcMlacNz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pg9ntxuy05tlkmne4jrp.png" alt="Image description" width="880" height="292"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Two Methods for Maximizing Nimble's AutoCompletion Feature
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;This is the default way in which the AutoCompletion system is invoked in the Nimble editor. As you type, Nimble automatically shows suggestions if a language service is aware of possible code completions. &lt;/p&gt;

&lt;p&gt;And if you continue typing characters, the list of members (such as &lt;code&gt;variables&lt;/code&gt;, &lt;code&gt;classes&lt;/code&gt;, &lt;code&gt;constants&lt;/code&gt;, &lt;code&gt;methods&lt;/code&gt;, and so forth) that is displayed is filtered to only include members containing your typed characters. The selected member will be inserted where your cursor is by &lt;strong&gt;pressing the Enter key&lt;/strong&gt; on your keyboard:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/mBurFZNvHrffbHCMaa/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/mBurFZNvHrffbHCMaa/giphy.gif" alt="Image description" width="480" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The suggestions widget shown in the editor has support for &lt;strong&gt;CamelCase filtering&lt;/strong&gt;. In other words, you can type the uppercase letters in a &lt;strong&gt;constant or method name&lt;/strong&gt; to limit the suggestions. For example, &lt;strong&gt;"myp"&lt;/strong&gt; will quickly bring up &lt;strong&gt;"myPost"&lt;/strong&gt; as shown in the illustration above.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You can manually trigger the AutoCompletion feature in the Nimble editor by clicking together the &lt;code&gt;Control key&lt;/code&gt; and &lt;code&gt;SpaceBar&lt;/code&gt; (&lt;code&gt;⌃Space&lt;/code&gt;) on your keyboard. &lt;/p&gt;

&lt;p&gt;Alternatively, you can choose the &lt;strong&gt;"Show Completion" option&lt;/strong&gt; from the &lt;strong&gt;Editor drop-down menu&lt;/strong&gt; on the &lt;strong&gt;Nimble menubar&lt;/strong&gt; in the top-left corner of the screen:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SKnqiYAc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uao0gyxhq6g7pvxey95i.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SKnqiYAc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uao0gyxhq6g7pvxey95i.gif" alt="Image description" width="880" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A crucial benefit of this method is that it helps in displaying inaccessible &lt;code&gt;static fields&lt;/code&gt;, &lt;code&gt;keywords&lt;/code&gt;, &lt;code&gt;methods&lt;/code&gt;, &lt;code&gt;classes&lt;/code&gt;, and &lt;code&gt;members&lt;/code&gt;. &lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  AutoCompleting Type Names
&lt;/h2&gt;

&lt;p&gt;Possible type names (and &lt;code&gt;classes&lt;/code&gt;) are listed in the completion list as user types after placing a full colon in front of a declared variable name, parameters in &lt;code&gt;parenthesises&lt;/code&gt;, etc... Importantly, only useful types are suggested, and the names listed are filtered according to the current namespace context:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6Omlm6Xq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wr36rq4g1n64cwmvgslm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6Omlm6Xq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wr36rq4g1n64cwmvgslm.png" alt="Image description" width="880" height="275"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  AutoCompleting Variable Names
&lt;/h2&gt;

&lt;p&gt;Since Swift has a variable declaration statement, the Nimble editor completes &lt;code&gt;variables&lt;/code&gt; automatically as the user types. For instance, If a user inputs a word that matches a variable name, the completion list pre-selects the variable:&lt;/p&gt;

&lt;h2&gt;
  
  
  AutoCompleting Object Members
&lt;/h2&gt;

&lt;p&gt;The Autocompletion feature automatically suggests available object members as soon as a user types &lt;code&gt;-&amp;gt;&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qHDVWoRp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/azp99wk5vlrhbv31horf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qHDVWoRp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/azp99wk5vlrhbv31horf.png" alt="Image description" width="880" height="214"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Nimble has many strong features, including AutoCompletion. For more information about the Nimble code editor, &lt;a href="https://github.com/scade-platform/Nimble"&gt;continue reading&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>editors</category>
      <category>swift</category>
      <category>macos</category>
      <category>ides</category>
    </item>
    <item>
      <title>How to Copy and Paste Figma Design to Build Cross-Platform Mobile Apps on SCADE</title>
      <dc:creator>Olanrewaju Olakunle</dc:creator>
      <pubDate>Wed, 31 Aug 2022 18:24:05 +0000</pubDate>
      <link>https://dev.to/cdfcreator/how-to-copy-and-paste-figma-design-to-build-cross-platform-mobile-apps-on-scade-141l</link>
      <guid>https://dev.to/cdfcreator/how-to-copy-and-paste-figma-design-to-build-cross-platform-mobile-apps-on-scade-141l</guid>
      <description>&lt;p&gt;Developing a successful mobile application is not simple; there are many factors to take into account, including planning, designing, coding, testing, and maintenance.&lt;/p&gt;

&lt;p&gt;In this tutorial, we are going to look at one page of an existing app project on Figma and learn how to copy and paste the design into a project on &lt;a href="https://www.scade.io/download/"&gt;SCADE&lt;/a&gt;. Figma is a well-known web-based vector graphics editor and prototyping tool that lets designers and software developers construct the user interface and wireframes for websites and mobile applications.&lt;/p&gt;

&lt;p&gt;It's not always advisable to launch SCADE right away while developing an app. You’ll want to work on the app’s look and feel before doing any code. One of the reasons is that design plays a crucial role to get a user-friendly application. It is what makes using the app a seamless experience for the users.&lt;br&gt;
Additionally, by doing this before you start coding, it will enable you to figure out exactly what your app will perform. Once you are done with the design, you can then match the designs on SCADE.&lt;/p&gt;

&lt;p&gt;By the end of this tutorial, you should have solid knowledge to do the following: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Work with Figma designs on SCADE. &lt;/li&gt;
&lt;li&gt;Use the GridLayout to build a Responsive Mobile UI. &lt;/li&gt;
&lt;li&gt;Be able to Create Mobile Apps by Copying and Pasting SVG Contents from Figma into the Button Widget, and that the SVG Designs preserve their Original Size when doing so. &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;For the &lt;strong&gt;Profile &amp;amp; Settings page&lt;/strong&gt; in this tutorial, we will use the GridLayout, which gives us the flexibility to have complex layouts that are highly responsive without having to worry about working with constraints:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DIwMHay5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/egigvvsm55v7uv3atafe.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DIwMHay5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/egigvvsm55v7uv3atafe.gif" alt="Image description" width="880" height="589"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Profile &amp;amp; Settings page&lt;/strong&gt; below is the Figma design we'll be replicating on SCADE in this tutorial:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MhTaQa----/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/my9ymwuz59q5pvyhwf1y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MhTaQa----/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/my9ymwuz59q5pvyhwf1y.png" alt="Image description" width="880" height="839"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  SETTING UP THE BASIC STRUCTURE
&lt;/h2&gt;

&lt;p&gt;Open your project and click on the &lt;strong&gt;main.page file&lt;/strong&gt; to set up the bare bones of our basic structure before we enter the details of our page. &lt;/p&gt;

&lt;p&gt;Next, change the &lt;strong&gt;Row&lt;/strong&gt; value of your &lt;strong&gt;Grid&lt;/strong&gt; to 4 under &lt;strong&gt;LAYOUT&lt;/strong&gt; on the right side of your main page. Additionally, paste the &lt;strong&gt;Profile &amp;amp; Settings page's background color's hex code&lt;/strong&gt; copied from the Figma design into the &lt;strong&gt;main page background's Fills Hex field&lt;/strong&gt;:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IxRGsFtB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/meyent4147r9k1o17uup.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IxRGsFtB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/meyent4147r9k1o17uup.jpeg" alt="Image description" width="880" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1. CREATING A CUSTOM NAVIGATION BAR
&lt;/h2&gt;

&lt;p&gt;Looking at our &lt;strong&gt;Profile &amp;amp; Settings design&lt;/strong&gt;, we need to create our custom navigation bar at the top. This is made feasible by adding a &lt;strong&gt;horizontal container&lt;/strong&gt; in the first row of the divided main &lt;strong&gt;Grid&lt;/strong&gt; and having its name updated to &lt;strong&gt;NavBar&lt;/strong&gt;. That's not all, we also need to divide the &lt;strong&gt;NavBar&lt;/strong&gt; into &lt;strong&gt;2 columns&lt;/strong&gt;, and use its &lt;strong&gt;Alignment and Fill properties&lt;/strong&gt; to ensure that it only occupies a limited amount of space at the top of the screen:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Whyr1wz4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mvp8qjrqivt5xqnnzkna.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Whyr1wz4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mvp8qjrqivt5xqnnzkna.jpeg" alt="Image description" width="880" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, let's add a &lt;strong&gt;label&lt;/strong&gt; with the name &lt;strong&gt;profileLabel&lt;/strong&gt; to the &lt;strong&gt;first column of the NavBar&lt;/strong&gt;. we also need to give it a label text called &lt;strong&gt;"Profile"&lt;/strong&gt;. Also, the &lt;strong&gt;Alignment and Fill properties&lt;/strong&gt; are needed here to configure the &lt;strong&gt;profileLabel&lt;/strong&gt; to the &lt;strong&gt;top-left side&lt;/strong&gt; of the screen with &lt;strong&gt;20-padding&lt;/strong&gt; ensured at the top and left side of it:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AfxLu-cE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dhurzgouiznhbi6tbxad.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AfxLu-cE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dhurzgouiznhbi6tbxad.jpeg" alt="Image description" width="880" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the &lt;strong&gt;second column of the NavBar&lt;/strong&gt;, we add a &lt;strong&gt;button widget&lt;/strong&gt; beside the &lt;strong&gt;profileLabel&lt;/strong&gt; and name it &lt;strong&gt;"settingsIcon"&lt;/strong&gt;. Just like the &lt;strong&gt;profileLabel&lt;/strong&gt;, we need the &lt;strong&gt;Alignment and Fill properties&lt;/strong&gt; to set the &lt;strong&gt;settingsIcon&lt;/strong&gt; to the &lt;strong&gt;top right corner&lt;/strong&gt; of the screen. The &lt;strong&gt;settingsIcon&lt;/strong&gt;, however, doesn't require a &lt;strong&gt;text title&lt;/strong&gt;, &lt;strong&gt;background image&lt;/strong&gt;, or &lt;strong&gt;fill color&lt;/strong&gt;. What is needed on the button widget here is to &lt;strong&gt;select and right-click&lt;/strong&gt; on the &lt;strong&gt;settingsIcon&lt;/strong&gt; on the &lt;strong&gt;Profile &amp;amp; Settings page&lt;/strong&gt; of our Figma design, then &lt;strong&gt;go to Copy as - Copy as SVG&lt;/strong&gt;. Once that’s done, you can &lt;strong&gt;paste the SVG icon&lt;/strong&gt; on our settingsIcon button of our project on SCADE by using the keyboard shortcut &lt;strong&gt;command + V&lt;/strong&gt; or the &lt;strong&gt;"Paste" option&lt;/strong&gt; from the &lt;strong&gt;Edit dropdown menu on the SCADE menubar&lt;/strong&gt; placed in the top-left corner of the screen:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--M8HgCTbB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pfir7gv66y337gkp3zkq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--M8HgCTbB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pfir7gv66y337gkp3zkq.png" alt="Image description" width="880" height="1025"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xkkVJPH2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m0n92astvzb1v8dwk2ks.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xkkVJPH2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m0n92astvzb1v8dwk2ks.jpeg" alt="Image description" width="880" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2. ADDING AN UPPERSECTION
&lt;/h2&gt;

&lt;p&gt;After finishing the &lt;strong&gt;navigation bar&lt;/strong&gt;, let's add a &lt;strong&gt;vertical container&lt;/strong&gt; and give it the name &lt;strong&gt;"UpperSection"&lt;/strong&gt; to the &lt;strong&gt;second row&lt;/strong&gt; of the &lt;strong&gt;divided main Grid&lt;/strong&gt;. Notably, we are also creating three rows in the &lt;strong&gt;Uppersection&lt;/strong&gt; to accommodate three items: &lt;strong&gt;a second SVG icon&lt;/strong&gt; and &lt;strong&gt;two labels&lt;/strong&gt;. We are using the &lt;strong&gt;UpperSection Fill property&lt;/strong&gt; to configure it to occupy as much space as it can take. Not only that, but we also set its &lt;strong&gt;Vertical Indent property&lt;/strong&gt; to a negative value so it can stack over the space of the preceding navigation bar:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VaV9ROwl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/va7urg0j32m7b8xwy4e3.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VaV9ROwl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/va7urg0j32m7b8xwy4e3.jpeg" alt="Image description" width="880" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We return to our &lt;strong&gt;Profile &amp;amp; Settings page design&lt;/strong&gt; to &lt;strong&gt;select and right-click on the circle star icon, then go to Copy as - Copy as SVG&lt;/strong&gt;. Once that’s done, we add a &lt;strong&gt;button widget&lt;/strong&gt;, name it &lt;strong&gt;"starIcon"&lt;/strong&gt;, in the &lt;strong&gt;first row of the UpperSection&lt;/strong&gt; without a &lt;strong&gt;text title, background image or fill color&lt;/strong&gt; and &lt;strong&gt;paste&lt;/strong&gt; the &lt;strong&gt;SVG icon&lt;/strong&gt; inside it by pressing the &lt;strong&gt;shortcut command + V or selecting "Paste" from the Edit dropdown menu on the SCADE menubar in the top-left corner of the screen&lt;/strong&gt;. Additionally, we use its &lt;strong&gt;Fill parameter&lt;/strong&gt; to make sure it occupies all available space:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Jg9X2yIJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/698d89kxx1as8nztxmrv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Jg9X2yIJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/698d89kxx1as8nztxmrv.png" alt="Image description" width="880" height="1035"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Lh52IJxu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ht9idlad8le91m9w2ijz.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Lh52IJxu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ht9idlad8le91m9w2ijz.jpeg" alt="Image description" width="880" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We add a &lt;strong&gt;label&lt;/strong&gt; in the &lt;strong&gt;second row&lt;/strong&gt; of the &lt;strong&gt;UpperSection&lt;/strong&gt; named &lt;strong&gt;"reviewsAndRatingLabel"&lt;/strong&gt; that outputs a &lt;strong&gt;text&lt;/strong&gt; about having access to Reviews and Rating. we give it a &lt;strong&gt;fontsize&lt;/strong&gt;, &lt;strong&gt;font-type&lt;/strong&gt; and also use its &lt;strong&gt;Text Alignment property&lt;/strong&gt; to make it &lt;strong&gt;centred&lt;/strong&gt;. Thanks to its &lt;strong&gt;Fill property&lt;/strong&gt;, we ensure the &lt;strong&gt;reviewAndRatingLabel&lt;/strong&gt; occupies all the available space within its control:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Mw0CzL0X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/il2yt83bhpvv0s8m2qie.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Mw0CzL0X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/il2yt83bhpvv0s8m2qie.jpeg" alt="Image description" width="880" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;last row&lt;/strong&gt; of the &lt;strong&gt;UpperSection&lt;/strong&gt; takes another label named &lt;strong&gt;"keeptrackLabel"&lt;/strong&gt; that returns a &lt;strong&gt;text&lt;/strong&gt; emphasizing keeping track of shows and movies to watch. We give it the same treatment as the &lt;strong&gt;reviewsAndRatingLabel&lt;/strong&gt; above except that we make its texts &lt;strong&gt;multi-line&lt;/strong&gt; and reduce its fontsize to 14:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fi9CHqw_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e5pql2k2jop5491kt6s4.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fi9CHqw_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e5pql2k2jop5491kt6s4.jpeg" alt="Image description" width="880" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3. ADDING A SIGN-IN BUTTON
&lt;/h2&gt;

&lt;p&gt;We add a Vertical container with the name &lt;strong&gt;"SigninActionView"&lt;/strong&gt; and &lt;strong&gt;top padding of 60&lt;/strong&gt; in the &lt;strong&gt;third row&lt;/strong&gt; of the &lt;strong&gt;divided main Grid&lt;/strong&gt; to accommodate &lt;strong&gt;another button widget&lt;/strong&gt;. It's important to note that the &lt;strong&gt;SigninActionView&lt;/strong&gt; is also set up to take up the most amount of space possible:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4gKVyGp5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/86kx9w5zryunzqy9stz7.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4gKVyGp5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/86kx9w5zryunzqy9stz7.jpeg" alt="Image description" width="880" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Inside the  &lt;strong&gt;SigninActionView&lt;/strong&gt;, we add a &lt;strong&gt;button widget&lt;/strong&gt; and name it &lt;strong&gt;"signinButton"&lt;/strong&gt;. We need the  &lt;strong&gt;signinButton's&lt;/strong&gt; &lt;strong&gt;Alignment and Fill properties&lt;/strong&gt; to set it to the &lt;strong&gt;top center area of the SigninActionView&lt;/strong&gt;. As usual, like other button widgets used in this tutorial, the &lt;strong&gt;signinButton&lt;/strong&gt;, however, doesn't require a &lt;strong&gt;text title&lt;/strong&gt;, &lt;strong&gt;background image&lt;/strong&gt;, or &lt;strong&gt;fill color&lt;/strong&gt;. All we need do is to &lt;strong&gt;select and right-click&lt;/strong&gt; on the &lt;strong&gt;signinButton&lt;/strong&gt; on the &lt;strong&gt;Profile &amp;amp; Settings page&lt;/strong&gt; of our Figma design, then &lt;strong&gt;go to Copy as - Copy as SVG&lt;/strong&gt;. Once that’s done, we then &lt;strong&gt;paste the SVG icon&lt;/strong&gt; on our project signinButton on SCADE by using the keyboard shortcut &lt;strong&gt;command + V&lt;/strong&gt; or the &lt;strong&gt;"Paste" option&lt;/strong&gt; from the &lt;strong&gt;Edit dropdown menu on the SCADE menubar&lt;/strong&gt; in the top-left corner of the screen:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YyX86BGZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eztqoi6cb7ipwjks54md.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YyX86BGZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eztqoi6cb7ipwjks54md.png" alt="Image description" width="880" height="938"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ara2jnEz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dck5gi9j6xkyl85l56bj.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ara2jnEz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dck5gi9j6xkyl85l56bj.jpeg" alt="Image description" width="880" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  4. WORKING WITH A TABBAR
&lt;/h2&gt;

&lt;p&gt;We divide a ToolBar named the &lt;strong&gt;TabBar&lt;/strong&gt; into &lt;strong&gt;4 columns&lt;/strong&gt; to accommodate the &lt;strong&gt;home, search, favorite, and profile icons&lt;/strong&gt;. The &lt;strong&gt;TabBar's Fill property&lt;/strong&gt; is used to configure it to sit at the bottom of the &lt;strong&gt;last row&lt;/strong&gt; of the &lt;strong&gt;divided main Grid&lt;/strong&gt;. How are &lt;strong&gt;TabBar's&lt;/strong&gt; four items added? Just like we have done for all the icons we have used so far, we add a button widget into each of the &lt;strong&gt;tabBarItem&lt;/strong&gt; and &lt;strong&gt;simply select the four Icons from the tabbar on our Profile &amp;amp; Settings design page and right-click on them, then go to Copy as - Copy as SVG&lt;/strong&gt;. Once that’s done, we then paste the copied SVG icons into their respective button widget by using the shortcut &lt;strong&gt;command + V or clicking on "Paste" from the Edit drop-down menu on SCADE menubar at the top-left corner of the screen&lt;/strong&gt;:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tJaHOTOu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5ipgugw1iwg244j4tkue.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tJaHOTOu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5ipgugw1iwg244j4tkue.png" alt="Image description" width="880" height="632"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZRiJBpb3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yckam3r6x9i3c5rhy0g2.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZRiJBpb3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yckam3r6x9i3c5rhy0g2.jpeg" alt="Image description" width="880" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Output on iOS:&lt;/strong&gt; &lt;br&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hWLBMj-K--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u134sbaivwkp5qeqk0cb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hWLBMj-K--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u134sbaivwkp5qeqk0cb.png" alt="Image description" width="318" height="641"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Output on Android:&lt;/strong&gt; &lt;br&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yJA-6qkh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yozdebozq3kdxau2i5h3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yJA-6qkh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yozdebozq3kdxau2i5h3.png" alt="Image description" width="325" height="685"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This tutorial taught us how to bring a Figma design into SCADE. We’ve also learnt how to look at a design and figure out what components it has. Then, we added all the components of the design into pages (such as main.page as an example) and updated them to match the Figma design. We've also learnt how to use the GridLayout so that the design looks good on any device. Lastly, we also learnt how to copy/paste designs from Figma into the button widget and observe these SVG designs maintain the same size as those on Figma. The source code for this tutorial is available on &lt;a href="https://github.com/Cdf-creator/MovieDB"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Please note that this tutorial is based on &lt;strong&gt;SCADE 2.0.54&lt;/strong&gt;, which only supports copyng and pasting designs and icons into the button widget; &lt;strong&gt;future releases of SCADE will have support for all widgets&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>scade</category>
      <category>crossplatform</category>
      <category>android</category>
      <category>ios</category>
    </item>
    <item>
      <title>Create and Link Swift Packages from Nimble to Cross-Platform Native App Projects</title>
      <dc:creator>Olanrewaju Olakunle</dc:creator>
      <pubDate>Mon, 25 Jul 2022 11:48:11 +0000</pubDate>
      <link>https://dev.to/cdfcreator/create-and-link-swift-packages-from-nimble-to-cross-platform-native-app-projects-29j8</link>
      <guid>https://dev.to/cdfcreator/create-and-link-swift-packages-from-nimble-to-cross-platform-native-app-projects-29j8</guid>
      <description>&lt;p&gt;Swift packages are bundles of source files, binaries, and resources that you can reuse in your projects. They can also be seen as a tool, similar to CocoaPods and Carthage, for controlling the distribution of Swift code. It is integrated with Swift's build system to automatically download, compile, and link dependencies.&lt;/p&gt;

&lt;p&gt;In this tutorial, we are going to learn: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;how we can use the &lt;a href="https://github.com/scade-platform/Nimble/releases/tag/v1.3"&gt;Nimble Code Editor&lt;/a&gt; to create swift packages &lt;/li&gt;
&lt;li&gt;manage projects and dependencies&lt;/li&gt;
&lt;li&gt;how to read and change the &lt;code&gt;Package.swift&lt;/code&gt; &lt;strong&gt;files&lt;/strong&gt;. &lt;/li&gt;
&lt;li&gt;how can we link the created SPM to an existing SCADE project.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Definition of some Key Terminologies Used
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Packages:&lt;/strong&gt; Packages are basically repositories that house several executables and libraries. A package essentially includes source files and a manifest file.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Manifest File:&lt;/strong&gt; The manifest file, also known as the &lt;code&gt;Package.swift&lt;/code&gt; file, defines the package name and its contents using the &lt;code&gt;PackageDescription module&lt;/code&gt;. It is also concerned with managing dependencies, and every package has its &lt;code&gt;Package.swift&lt;/code&gt; manifest to handle any dependencies that it may have.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Targets:&lt;/strong&gt; A package may have one or many targets. Each target identifies a product and has the option to declare one or more dependencies.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;README:&lt;/strong&gt; This file enables you to describe how other developers can use your library.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Source Folder:&lt;/strong&gt; Location of our swift development files&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tests Folder:&lt;/strong&gt; Unit tests directory.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;This first section of this tutorial explains how to use the &lt;a href="https://github.com/scade-platform/Nimble/releases/tag/v1.3"&gt;Nimble Code Editor&lt;/a&gt; to create a swift package that alphabetically returns all the European nations together with their respective capitals. The tutorial's second part focuses on discovering how to link the Swift package we built with our ListControl project:&lt;/p&gt;

&lt;h2&gt;
  
  
  Section 1 - Using Nimble to Create a New Swift Package
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step One: Create a new Swift Package with Nimble
&lt;/h3&gt;

&lt;p&gt;To begin, launch the Nimble app and click &lt;strong&gt;File&lt;/strong&gt; &amp;gt; &lt;strong&gt;New&lt;/strong&gt; &amp;gt; &lt;strong&gt;New Project...&lt;/strong&gt; from the &lt;strong&gt;top-left menu bar&lt;/strong&gt;. On the following pop-up screen, select the &lt;strong&gt;Swift Package template&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;As an alternative, you can accomplish the aforementioned using the &lt;strong&gt;keyboard shortcut&lt;/strong&gt; &lt;code&gt;Shift + Command + N&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--v4OSCQNn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v3abwe9gzo6sd660ckpf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--v4OSCQNn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v3abwe9gzo6sd660ckpf.png" alt="Image description" width="880" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Type your package name, select your project folder location, then press the &lt;strong&gt;Create button&lt;/strong&gt; to create the swift package folder - you are expected to do all of this after selecting the &lt;strong&gt;Next button&lt;/strong&gt; of the Swift Package template screen.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--y9e4J9tr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sep8ak8hg1dc9q7th16d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--y9e4J9tr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sep8ak8hg1dc9q7th16d.png" alt="Image description" width="880" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step Two: Writing Source Code in the Package
&lt;/h3&gt;

&lt;p&gt;Next is to write/add the source code in our Swift package. Copy all the source files into the &lt;code&gt;Sources\EuropeanCountries&lt;/code&gt; &lt;strong&gt;folder&lt;/strong&gt;. If you'd like, you may delete the default &lt;code&gt;Sources/EuropeanCountries.swift&lt;/code&gt; &lt;strong&gt;template file&lt;/strong&gt; and replace it with our &lt;code&gt;Country.swift&lt;/code&gt; &lt;strong&gt;file&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EQOjJmhj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/286ahke83xhkdzku8687.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EQOjJmhj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/286ahke83xhkdzku8687.png" alt="Image description" width="880" height="1220"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copy all of your unit test files into the &lt;code&gt;TestsEuropeanCountriesTests&lt;/code&gt; &lt;strong&gt;folder&lt;/strong&gt; if you have any.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wS8uw8Rv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dmn7cvgy9t3457hhnr79.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wS8uw8Rv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dmn7cvgy9t3457hhnr79.png" alt="Image description" width="880" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We completely deleted the &lt;code&gt;Tests folder&lt;/code&gt; because we won't need unit tests for this tutorial. Recall that you must remove the &lt;code&gt;.testTarget&lt;/code&gt; syntax from your package targets if you wish to delete your swift package &lt;code&gt;Tests folder&lt;/code&gt; along with us.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZnAiu_7y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/thp9xby5r0xy6zyjefu5.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZnAiu_7y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/thp9xby5r0xy6zyjefu5.jpeg" alt="Image description" width="880" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's also advised that you keep your &lt;code&gt;README.md&lt;/code&gt; &lt;strong&gt;file&lt;/strong&gt; meaningfully updated. This makes it easier for other developers to use your Swift package:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JnBTIZW6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8t2q1vebdjthxtp8x92c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JnBTIZW6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8t2q1vebdjthxtp8x92c.png" alt="Image description" width="880" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step Three: Edit the Default Manifest (Package.swift) File
&lt;/h3&gt;

&lt;p&gt;You’ll find an array of dependencies in your swift package’s manifest file. There is one example dependency there, but it is commented out because it is solely for reference. If you have dependencies for your Swift package, you can define them under the dependencies tag. Add all the dependencies in your &lt;code&gt;target&lt;/code&gt; too.&lt;br&gt;
Most importantly, you need at least the URL info and the name of a library to add it as a dependency in your manifest file.&lt;/p&gt;

&lt;p&gt;We implemented inheritance from &lt;code&gt;EObject&lt;/code&gt; in this tutorial so that the &lt;code&gt;Country class&lt;/code&gt; could be used as a binding in the ScadeKit widget. We also needed the &lt;code&gt;ScadeExtensions&lt;/code&gt; library as a dependency using &lt;code&gt;ScadeKit&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Note: If you also require the ScadeExtensions library as a dependency, you must add the &lt;code&gt;ScadeKit&lt;/code&gt; information provided below to your SPM package manifest file.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Add header:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pM_dKMwq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/82ykciumu1lj5h4hwtxg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pM_dKMwq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/82ykciumu1lj5h4hwtxg.png" alt="Image description" width="880" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;And also add this for target:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SXKQDBI5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r47189upgj3lw01g09iw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SXKQDBI5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r47189upgj3lw01g09iw.png" alt="Image description" width="828" height="372"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This tutorial Manifest file together with its minimum iOS Version and Dependency looks like this:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LASWQZGH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4bukwzpsmv2ugl9y18nc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LASWQZGH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4bukwzpsmv2ugl9y18nc.png" alt="Image description" width="880" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step Four: Publishing Your Swift Package
&lt;/h3&gt;

&lt;p&gt;There is now just a step left before we can distribute our swift library. Just use the Terminal application to upload your SPM code to your GitHub repository. Developers will be able to access your library when they enter your SPM link. &lt;/p&gt;

&lt;h2&gt;
  
  
  Section 2 -  Using a Package in a SCADE Project
&lt;/h2&gt;

&lt;p&gt;Swift packages can be used in SCADE in two different ways. The SPM package we just created can be used locally in a project or uploaded to a personal Git repository. Both methods will be demonstrated for you in this tutorial section:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. How to use Swift Package Locally
&lt;/h3&gt;

&lt;p&gt;Open the &lt;code&gt;Package.swift&lt;/code&gt; file of your SCADE project, under dependencies, add the path to where your SPM package is located locally in your machine via the &lt;code&gt;.package(path: “/path/to/package”)&lt;/code&gt; syntax. Not only that, but you also need to list the name of your package among the &lt;code&gt;targets&lt;/code&gt;. Once all of these are done, you have successfully added your package to your project, and can be imported and used!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;See an example below:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jVRqneSn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ylxnn22voq6d5328ts4b.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jVRqneSn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ylxnn22voq6d5328ts4b.jpeg" alt="Image description" width="880" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. How to add Swift Package to your SCADE Project via Git Repository URL
&lt;/h3&gt;

&lt;p&gt;Similar to the manual way described above, open the manifest file of your SCADE project and paste the GitHub repository URL for your SPM package under dependencies along with the &lt;code&gt;package and branch name&lt;/code&gt; using the appropriate syntax. You must also put your package name as a reference under the &lt;code&gt;target&lt;/code&gt; panel.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;See an example below:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KbJnFIL---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b09475n7eof5xn7w9v6n.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KbJnFIL---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b09475n7eof5xn7w9v6n.jpeg" alt="Image description" width="880" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This goes for both methods explained above - import your package's product as a Swift module to utilize its functionality in your SCADE project. &lt;/p&gt;

&lt;p&gt;Both classes (&lt;code&gt;Country&lt;/code&gt; and &lt;code&gt;Countries&lt;/code&gt;) in the following code snippet import the &lt;code&gt;EuropeanCountries module&lt;/code&gt; of our Swift package and make use of its features:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eCiNVNgU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sdek54df66qxl2mid1nq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eCiNVNgU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sdek54df66qxl2mid1nq.png" alt="Image description" width="880" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;SCADE generates the &lt;code&gt;Package.resolved&lt;/code&gt; &lt;strong&gt;file&lt;/strong&gt; whenever you include a package dependency in your project. The checksum of each binary dependency is listed along with the exact Git commits that each package dependency corresponds to.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Package.resolved&lt;/code&gt; &lt;strong&gt;file&lt;/strong&gt; is located in your project directory as a standalone file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;See an example below:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---pJpZ9T2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sqxp6n0kogmf0km4ikf5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---pJpZ9T2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sqxp6n0kogmf0km4ikf5.png" alt="Image description" width="880" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This tutorial has taught us how to create SPM packages using the Nimble Code Editor and how to use such packages for cross-platform native app projects. If you have any questions, kindly remark below. Thanks for reading!&lt;/p&gt;

</description>
      <category>swift</category>
      <category>editors</category>
      <category>ides</category>
      <category>macos</category>
    </item>
    <item>
      <title>How to Display Images in Swift Cross-Platform Native Apps in SCADE</title>
      <dc:creator>Olanrewaju Olakunle</dc:creator>
      <pubDate>Fri, 15 Jul 2022 08:00:00 +0000</pubDate>
      <link>https://dev.to/cdfcreator/how-to-display-images-in-swift-cross-platform-native-apps-in-scade-2ohf</link>
      <guid>https://dev.to/cdfcreator/how-to-display-images-in-swift-cross-platform-native-apps-in-scade-2ohf</guid>
      <description>&lt;p&gt;The image control, just like every other control in SCADE acts as a wrapper around native controls, exposing a fraction of its functionality to users. We'll learn how to display images from within the app or dynamically downloaded from the internet in this tutorial. We can't envision an app these days without images. Although the images are stored in the assets folder, they are loaded during runtime. &lt;a href="https://www.scade.io/download/"&gt;SCADE&lt;/a&gt; currently only supports great image formats like PNG, SVG, and JPG.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Properties Needed for Implementation:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;content:&lt;/strong&gt;  it stores the images that you would like to display. Not to forget, it has a &lt;code&gt;Data&lt;/code&gt; type. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;URL:&lt;/strong&gt; relative path to the image's source. When initializing this attribute, ensure you have its path accurately sorted out. That’s, the image name comes last after you might have spelled out the folder you have the images stored in. See example: &lt;code&gt;Assets/shoe1.png&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;isContentPriority:&lt;/strong&gt; this type-Bool property specifies which incoming source we use in rendering the image. It’s set to &lt;code&gt;false&lt;/code&gt; if the &lt;code&gt;URL&lt;/code&gt; field is used in getting information to display the image and set to &lt;code&gt;true&lt;/code&gt; if the content field is used instead. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;There are three (3) possible ways you can use to add an image(s) to your Android and iOS apps in SCADE:&lt;/p&gt;

&lt;h2&gt;
  
  
  Method One: Static Image Referencing
&lt;/h2&gt;

&lt;p&gt;You can simply achieve this by using the &lt;strong&gt;Widget Palette&lt;/strong&gt; to drag and drop the image control to any &lt;code&gt;.page&lt;/code&gt; file of choice (for example &lt;code&gt;main.page&lt;/code&gt;). Once this is done, make use of the &lt;strong&gt;Path feature&lt;/strong&gt;, under the Image attribute, found on the right side of your page to find and select the image you want to display in your app from the folder that contains it. Interestingly, using this method, your images get stored automatically in your Assets folder.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;See the result below:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5ho5nVyt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9t79m5ucng8xzunr0d1y.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5ho5nVyt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9t79m5ucng8xzunr0d1y.jpeg" alt="Image description" width="880" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Method Two: Adding Images Using Code
&lt;/h2&gt;

&lt;p&gt;Two things you must never forget to do if you want to go with this approach:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Ensure that the path in the &lt;code&gt;URL&lt;/code&gt; field is valid.&lt;/li&gt;
&lt;li&gt;Initialize the &lt;code&gt;contentPriority&lt;/code&gt; attribute value of your images to be &lt;code&gt;false&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Remember, unlike in the above method, you will need to add your images manually to the Assets folder here to complete the phase of displaying your images in your desired area. Additionally, you may also use the &lt;strong&gt;Scale Mode&lt;/strong&gt; built within the Image Control to make adjustments and ensure that your images are properly sized for your app. &lt;br&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;See an example below:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--onnQI_eC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jqtj1xorgz7xo07ut7ch.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--onnQI_eC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jqtj1xorgz7xo07ut7ch.jpeg" alt="Image description" width="880" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;See code snippet below:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BOaMEmQS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eg620bly8jdm2etldwby.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BOaMEmQS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eg620bly8jdm2etldwby.png" alt="Image description" width="880" height="741"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Output on iOS:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--78oHr5ZR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ma1pt7dcxv0weqxmk2kp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--78oHr5ZR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ma1pt7dcxv0weqxmk2kp.png" alt="Image description" width="626" height="1252"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Output on Android:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TvY7kbAE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0mrmv44gmbzxmklezacv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TvY7kbAE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0mrmv44gmbzxmklezacv.png" alt="Image description" width="634" height="1340"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Method Three: Using raw data from the Internet to display images
&lt;/h2&gt;

&lt;p&gt;Most apps require data to be fetched from a remote server, and downloading images is a frequent activity. This approach makes things convenient for you in the sense that you don’t need to initially store your images on your app before you can render them - all you need to do is to get the image addresses of the images of your choice from the internet or any other source.&lt;/p&gt;

&lt;p&gt;The main goal of this method is to teach you how to download images using swift. First, add a third image control with the name &lt;strong&gt;image3&lt;/strong&gt; underneath &lt;strong&gt;image2&lt;/strong&gt; on the main page. Make use of the &lt;strong&gt;Constraints property&lt;/strong&gt; to control its size and position just like you have done in the other two methods above.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;See an example below:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--w-9PENAt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6027vtjgbehqx47z6ean.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--w-9PENAt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6027vtjgbehqx47z6ean.png" alt="Image description" width="880" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This method is primarily focused on updating the Image Control on the main thread using Grand Central Dispatch. Creating a URL object that points to the remote image is the first thing we do. The next step is to invoke the &lt;code&gt;init(contentsOf:)&lt;/code&gt; &lt;strong&gt;initializer&lt;/strong&gt; on the Data object. We utilize the &lt;code&gt;try?&lt;/code&gt; &lt;strong&gt;keyword&lt;/strong&gt; and &lt;code&gt;optional binding&lt;/code&gt; to safely access the initialization's result because the initializer is throwing. Lastly, in the body of the &lt;code&gt;if statement&lt;/code&gt;, we put the raw image data received from the network call in the &lt;code&gt;content field&lt;/code&gt; and also set the value of the &lt;code&gt;contentPriority&lt;/code&gt; &lt;strong&gt;property&lt;/strong&gt; to be &lt;code&gt;true&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;See code snippet below:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9ecJpW_0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2y3q4kfezrfj64xnic1t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9ecJpW_0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2y3q4kfezrfj64xnic1t.png" alt="Image description" width="880" height="693"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Output on iOS:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cpfVisY8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/45oaph6qlw2lv4rtzw2g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cpfVisY8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/45oaph6qlw2lv4rtzw2g.png" alt="Image description" width="626" height="1252"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Output on Android:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zjtErCD---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/71pdclfhc9nvvl1cuu7f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zjtErCD---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/71pdclfhc9nvvl1cuu7f.png" alt="Image description" width="634" height="1340"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This concludes the tutorial on how to display images in SCADE using Swift for Android and iOS, including all steps and examples. Feel free to use any of the above methods individually or collectively in your next SCADE project - everything depends on how you want your app structuring to be. The source code for this tutorial is available on &lt;a href="https://github.com/Cdf-creator/ImageControl"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>scade</category>
      <category>swift</category>
      <category>ios</category>
      <category>android</category>
    </item>
    <item>
      <title>Nimble - native, open-source, extendable MacOS Code Editor</title>
      <dc:creator>Olanrewaju Olakunle</dc:creator>
      <pubDate>Wed, 15 Jun 2022 14:58:38 +0000</pubDate>
      <link>https://dev.to/cdfcreator/nimble-native-open-source-extendable-macos-code-editor-2ipn</link>
      <guid>https://dev.to/cdfcreator/nimble-native-open-source-extendable-macos-code-editor-2ipn</guid>
      <description>&lt;p&gt; Developers use code editors to write code. Code editors format and highlight your code to make it easier to read and understand. &lt;/p&gt;



&lt;p&gt; These programming tools are equipped with interesting features such as Language-specific syntax highlighting, automatic code indentation, color schemes to suit your preferences and improve code readability, Plugins for initiating a variety of activities and default packages during the development process, a tree view of your project's folders and files for ease of navigating and many more. &lt;/p&gt;



&lt;p&gt; We'll walk you through the steps to install Nimble, one of the best MacOS code editors. By the end of this article, you'll be able to create and edit code written in different languages using Nimble. Not only that, but you'll also learn about some of its unique plugins, which make it extensible, as well as its theming settings, which help you make your code more beautiful. &lt;/p&gt;


&lt;h2&gt;
  
  
  Understanding the Concept of Nimble
&lt;/h2&gt;

&lt;p&gt;Nimble is a lightweight open-source, extendable Code Editor and IDE exclusively written for MAC. It is a document-based Cocoa application written in the Swift language. Nimble is popularly known for its high performance and easy extensibility. Not only these, but it's also popular for its support of many programming languages. &lt;/p&gt;

&lt;p&gt;Thanks to LSP (Language Server Protocol), Nimble also provides programming language-specific features such as auto(completion) and diagnostics for its users. Finally, and most crucially, Nimble makes it simple to maintain, add, and build dependencies/frameworks when working on SPM projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;You must have installed &lt;strong&gt;macOS 10.15 Catalina or higher&lt;/strong&gt;, &lt;strong&gt;Xcode 12.4 or higher&lt;/strong&gt;, and &lt;strong&gt;Swift 5.3.2 or higher&lt;/strong&gt; before running the Nimble app because this is the only development environment it supports.&lt;/p&gt;

&lt;p&gt;You can download the latest version of Nimble from this &lt;a href="https://github.com/scade-platform/Nimble/releases/tag/v1.3"&gt;GitHub Repo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--V_VYrfkI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0mwczr6cnda62mzwgvcn.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--V_VYrfkI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0mwczr6cnda62mzwgvcn.jpeg" alt="Image description" width="880" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you have successfully downloaded the .dmg file of Nimble, open it and drag-and-drop in the Applications folder. Afterward, launch the application, and your editor will appear as shown below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0AgRXNXZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/004csemwpc2iv9jxwbsf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0AgRXNXZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/004csemwpc2iv9jxwbsf.png" alt="Image description" width="880" height="476"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating Your First Project on Nimble
&lt;/h2&gt;

&lt;p&gt;Select &lt;strong&gt;"New"&lt;/strong&gt; from the File menu on Nimble menubar to create a new file or project. Alternatively, you can also use &lt;strong&gt;command + N&lt;/strong&gt; and &lt;strong&gt;shift + command + N&lt;/strong&gt; to create a new file and project, respectively. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Note: When you create a new project on Nimble, you can choose from a variety of project types. We will use &lt;strong&gt;Type Executable&lt;/strong&gt; for this tutorial.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RDuNhv56--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c30v84y38r82dkm7irxs.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RDuNhv56--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c30v84y38r82dkm7irxs.gif" alt="Image description" width="880" height="535"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the new project is created, you can insert your code in the built-in &lt;strong&gt;main.swift&lt;/strong&gt; file, similar to any other code editor, and save the project in your working repository. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jkioj-oq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pl56nc5ct7xl2pvlivas.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jkioj-oq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pl56nc5ct7xl2pvlivas.png" alt="Image description" width="880" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Nimble Code editor also offers a number of options depending on the file format. Aside from creating and running Swift files, the Nimble Code editor also lets you manage files in other languages. For instance, in the project folder created above, create a java file and save it with the &lt;strong&gt;.java&lt;/strong&gt; file extension.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Gf3aGPW7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/khl2kvcgejpm220xa1dz.png" alt="Image description" width="880" height="550"&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;Default Light Theme&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Theming
&lt;/h2&gt;

&lt;p&gt;Themes help Code editors seem better by adding colors and beautiful backgrounds. They influence the appearance of the editor's user interface by changing the colors of elements of the editors/IDE.&lt;/p&gt;

&lt;p&gt;The Nimble Code editor comes with two default themes - the default light and dark themes. You can simply customize the appearance of your editor by switching between the two inbuilt themes.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fGi8aCFR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k4iq2q9jzh6tzo1byi8b.png" alt="Image description" width="880" height="550"&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;Default Dark Theme&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;However, Nimble's appearance is not limited to just these two themes; you can also add compatible custom themes (&lt;strong&gt;.yml&lt;/strong&gt; files) to your list of options. How do you achieve this? Goto &lt;strong&gt;~/Library/Application Support/Nimble&lt;/strong&gt; and create a folder called &lt;strong&gt;Themes&lt;/strong&gt; in it. Next, copy and paste your created custom themes files inside this folder - that's all.&lt;/p&gt;

&lt;p&gt;Alternatively, you may add a custom theme to your Code editor by right-clicking on it to show its contents before navigating to &lt;strong&gt;CodeEditor.plugin-&amp;gt;Contents-&amp;gt;Resources-&amp;gt;Themes folder&lt;/strong&gt; to add a new theme to the two default themes already in the folder.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YRC91XSX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5276uv5rapvp56t0od2b.png" alt="Image description" width="880" height="550"&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;Dracula Theme&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Great Plugin Systems
&lt;/h2&gt;

&lt;p&gt;Every editor has development plugins that initiate a series of operations and preset packages. The Nimble Code editor is integrated with a handful of plugins that improve the user experience and assist users to increase productivity. This chapter examines each of these built-in plugins and their functions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;h3&gt;
  
  
  Project Navigator
&lt;/h3&gt;

&lt;p&gt;The project navigator plugin divides your project into two sections, labeled "Open Files" and "Folders" respectively. The &lt;strong&gt;"Open Files" section&lt;/strong&gt; contains the files you just navigated to in your Code editor, while the &lt;strong&gt;"Folders" section&lt;/strong&gt; has every file and sub-folder in your project folder. You can't navigate between files and directories on Nimble without this plugin.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--taEtSqP2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u8i4uvowkiy7y437w8qx.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--taEtSqP2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u8i4uvowkiy7y437w8qx.jpeg" alt="Image description" width="880" height="550"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;
  
  
  BuildSystem
&lt;/h3&gt;

&lt;p&gt;The Nimble-integrated BuildSystem plugin is to compile, build, and run swift codes and packages to the terminal. Not only that, but this plugin also allows you to clean up your code for better performance optimization. Finally, owing to the BuildSytem plugin's minification capability, you may include as many comments and white space as you like to your source code and split it into as many files as you need without worrying about app performance or load times.&lt;/p&gt;

&lt;p&gt;The BuildSystem plugin can be located in the top-left corner of your Code editor's Tools menu bar.&lt;/p&gt;
&lt;h4&gt;
  
  
  The BuildSytem Items Shortcut
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Run&lt;/strong&gt; - &lt;strong&gt;Command + R&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Build&lt;/strong&gt; - &lt;strong&gt;Command + B&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clean&lt;/strong&gt; - &lt;strong&gt;Command + K&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;
  
  
  LSPClient
&lt;/h3&gt;

&lt;p&gt;The BuildSystem plugin can be located in the top-left corner of your Code editor's Tools menu bar. The LSP Client plugin uses the Language Server Protocol to provide many language features, such as Auto-Completion, Format-Document, Show-Completion, Diagnostics, Code-Navigation, and finding references.&lt;/p&gt;
&lt;h4&gt;
  
  
  Some common LSPClient features that support Nimble include:
&lt;/h4&gt;

&lt;p&gt;1. &lt;strong&gt;Format-Document:&lt;/strong&gt; Format the current document or current selection. It may be applied manually by clicking on Format-Document under the Editor menu bar at the top-left corner of the Code editor or through a command invocation (Control + Command + I).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZfYl559O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/28ctlf15rpc0ynqu7p35.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZfYl559O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/28ctlf15rpc0ynqu7p35.gif" alt="Image description" width="880" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2. &lt;strong&gt;Diagnostics:&lt;/strong&gt;  It does the work of showing diagnostics highlights. Diagnostics is a general term for &lt;strong&gt;"things that are of interest in the file"&lt;/strong&gt;. It may be syntax errors, warnings from your compiler, or hints about unused variables in a function.&lt;/p&gt;

&lt;p&gt;For instance, a comma (&lt;strong&gt;,&lt;/strong&gt;) is purposely placed after the parenthesis on the last line of code in the &lt;strong&gt;main.swift file&lt;/strong&gt;, as shown in the screenshot below, to test Nimble's diagnostic feature.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--y6PEgzLt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zkk398azzpoiu6a15x3u.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--y6PEgzLt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zkk398azzpoiu6a15x3u.jpeg" alt="Image description" width="880" height="550"&gt;&lt;/a&gt;    &lt;/p&gt;

&lt;p&gt;3. &lt;strong&gt;Show-Completion:&lt;/strong&gt; Displays documentation for a selected completion item in the list. You can also manually trigger Nimble's &lt;strong&gt;Show-Completion feature&lt;/strong&gt; anywhere in your code by pressing the &lt;strong&gt;Control + Space command&lt;/strong&gt;. &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BSGg8esM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cxkg7lrn9rcrc0jny22t.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BSGg8esM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cxkg7lrn9rcrc0jny22t.jpeg" alt="Image description" width="880" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;4. &lt;strong&gt;Auto-Completion:&lt;/strong&gt; It gives you word completions based on the current buffer. It shows the autocomplete widget synchronously. The LSP package enriches the auto-complete list with language server results.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_Ip4m6jx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g1e0gkszgv9yoc4vcbyq.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_Ip4m6jx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g1e0gkszgv9yoc4vcbyq.gif" alt="Image description" width="880" height="550"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;
  
  
  Language Extensions
&lt;/h3&gt;

&lt;p&gt;Language Extensions in Nimble give clever editing features for a variety of programming languages.  Nimble doesn't come with built-in language support, but it gives a set of APIs that enable sophisticated language features. For instance, it comes with a Python extension that allows Nimble to highlight syntax in Python files. Similarly, when you type System. and out shows up in Intellisense, it is the Java Programming Language Features extension at work.&lt;/p&gt;

&lt;p&gt;Without the Language Extensions, the code in the Nimble Code editor looks like this:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IPfr83cc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pdswml5hfl3diior3hxo.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IPfr83cc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pdswml5hfl3diior3hxo.jpeg" alt="Image description" width="880" height="550"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;
  
  
  File-Icons
&lt;/h3&gt;

&lt;p&gt;The file-icons plugin provides missing icons for commonly used file formats. It allocates file extension icons and colors for easier visual grepping. In other words, this plugin is tasked with the responsibility of showing file icons based on file extension.&lt;br&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XCiiUnfi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nkxuofowpf3fe49d682g.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XCiiUnfi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nkxuofowpf3fe49d682g.jpeg" alt="Image description" width="880" height="550"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;
  
  
  ImageViewer
&lt;/h3&gt;

&lt;p&gt;The ImageViewer plugin is used for displaying image files on Nimble. To put it another way, without this plugin, you won't be able to view images on Nimble. It supports images with formats such as jpeg, png, and SVG.&lt;br&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6hjzpYZI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/21bsut5f5n86ky8tvh2i.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6hjzpYZI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/21bsut5f5n86ky8tvh2i.jpeg" alt="Image description" width="880" height="550"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This lesson provides you with a thorough understanding of Nimble's fundamentals and prepares you to use it in your software development projects.&lt;/p&gt;

</description>
      <category>editors</category>
      <category>ides</category>
      <category>macos</category>
      <category>swift</category>
    </item>
    <item>
      <title>Learn how to manage webpages in your Swift Cross-Platform Native Apps with the WebView Control</title>
      <dc:creator>Olanrewaju Olakunle</dc:creator>
      <pubDate>Tue, 07 Jun 2022 15:40:21 +0000</pubDate>
      <link>https://dev.to/cdfcreator/learn-how-to-manage-webpages-in-your-swift-cross-platform-native-apps-with-the-webview-control-4kom</link>
      <guid>https://dev.to/cdfcreator/learn-how-to-manage-webpages-in-your-swift-cross-platform-native-apps-with-the-webview-control-4kom</guid>
      <description>&lt;p&gt; The WebView Control is an amazing tool you can use to load interactive web content in your SCADE apps. it's a handy object you can always rely on when trying to view webpages in your mobile apps without having to open a browser. Interestingly, with the WebView control feature integrated into SCADE (&lt;a href="https://www.scade.io/download/"&gt;www.scade.io&lt;/a&gt;), you are also saved from the stress of having to implement again (in your mobile apps) a feature you already have on your website. &lt;/p&gt;


&lt;h2&gt;
  
  
  WebView Control's Properties
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;SCDWidgetsLoadEvent:&lt;/strong&gt; indicates that the page we're trying to load has loaded successfully.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SCDWidgetsLoadFailedEvent:&lt;/strong&gt; when a failure occurs, this event is triggered. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SCDWidgetsShouldLoadEventHandler:&lt;/strong&gt; used to block specific pages from loading based on their URL.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt; In this tutorial, we'll play with the WebView control while creating a basic app that shows webpages and allows us to explore them. &lt;/p&gt;


&lt;p&gt;By the end of this tutorial, you'll be able to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;position a WebView control anywhere within the app page&lt;/li&gt;
&lt;li&gt;load a webpage&lt;/li&gt;
&lt;li&gt;receive events when the page was loaded&lt;/li&gt;
&lt;li&gt;prevent pages from loading&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;To work with the WebView control, create a new project on your &lt;strong&gt;SCADE IDE&lt;/strong&gt; (if you don't already have an existing one) and follow the given steps below:&lt;/p&gt;

&lt;h2&gt;
  
  
  Step One: Drag and drop the WebView to the desired position on the page
&lt;/h2&gt;

&lt;p&gt;Use the &lt;strong&gt;Widget Palette&lt;/strong&gt; to drag and drop the WebView control to any position on your preferred page. Notably, SCADE allows you to add as many WebView widgets as you like to your page; in our simple app example, we used three WebView widgets on our &lt;strong&gt;main.page&lt;/strong&gt;. You can also take advantage of the &lt;strong&gt;LAYOUT&lt;/strong&gt; attribute that you can find on the page to adjust the height and width of the WebView widget to suit your taste.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UjeKxPu4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nlwm8zb71dzsqawslzbm.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UjeKxPu4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nlwm8zb71dzsqawslzbm.jpeg" alt="Image description" width="880" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Additionally, you can also add &lt;strong&gt;constraints&lt;/strong&gt; to your WebView control to better the look and feel of your webpages when they are displayed on your app.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wVWFoMuK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ndddvzeb08lo2clq6p9j.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wVWFoMuK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ndddvzeb08lo2clq6p9j.jpeg" alt="Image description" width="880" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step Two: Add logic to reference the WebView control
&lt;/h2&gt;

&lt;p&gt;Open your project &lt;strong&gt;main.page.swift&lt;/strong&gt; file and add the necessary logic when referencing the WebView widgets before loading the &lt;strong&gt;UIKit&lt;/strong&gt; page. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;See an example below:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jkCW63iQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1bki1erxgrhdcwso8k4l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jkCW63iQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1bki1erxgrhdcwso8k4l.png" alt="Image description" width="880" height="734"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Output: the three URLs in the above code are displayed on top of each other as seen in the result below:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;iOS:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2KHg4lB1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/21ng4bynmgg0ge2y6539.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2KHg4lB1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/21ng4bynmgg0ge2y6539.gif" alt="Image description" width="238" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Android: &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HPZR5vce--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6lrtew8rqi0wxn34e0yi.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HPZR5vce--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6lrtew8rqi0wxn34e0yi.gif" alt="Image description" width="228" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Additional Features
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;h2&gt;
  
  
  Using events to determine if a webpage is successfully loaded or failed
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;SCDWidgetsLoadEvent&lt;/strong&gt; and &lt;strong&gt;SCDWidgetsLoadFailedEvent&lt;/strong&gt; attributes are more or less the opposite of each other. The &lt;strong&gt;SCDWidgetsLoadEvent&lt;/strong&gt; can be used to indicate whether a page has loaded successfully, but the &lt;strong&gt;SCDWidgetsLoadFailedEvent&lt;/strong&gt; is only triggered when a page has failed to load. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;See an example below:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1TyY8NdZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rm8seioiyvh8okn31cdw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1TyY8NdZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rm8seioiyvh8okn31cdw.png" alt="Image description" width="880" height="511"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The preceding code snippet will print &lt;strong&gt;-OnLoaded: Optional("&lt;a href="https://m.youtube.com/%22)-"&gt;https://m.youtube.com/")-&lt;/a&gt;&lt;/strong&gt; to the terminal if the page loads successfully, but &lt;strong&gt;-NonLoaded: Optional("&lt;a href="https://m.youtube.com/%22)-"&gt;https://m.youtube.com/")-&lt;/a&gt;&lt;/strong&gt; to the terminal if the page fails to load.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h2&gt;
  
  
  Determining whether or not a page should be loaded
&lt;/h2&gt;

&lt;p&gt;We may wish to prevent some pages from loading based on the URL in some circumstances. This may be done using the &lt;strong&gt;SCDWidgetsShouldLoadEventHandler&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;See an example below:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Cqg3IbRV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8j2nhus80df2rxnc4smi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Cqg3IbRV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8j2nhus80df2rxnc4smi.png" alt="Image description" width="880" height="525"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The URL in the above code snippet will load when the app is run since it meets the condition of containing &lt;strong&gt;"bensound"&lt;/strong&gt;. &lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;You now know more about WebView and, more importantly, when and how to utilize it in your SCADE project. You can now comfortably manage the WebView or specify the URL that should be loaded or stopped from loading in your app when the requirement arises.&lt;/p&gt;

&lt;p&gt;Here is the Github link for reference: &lt;a href="https://github.com/Cdf-creator/WebView"&gt;https://github.com/Cdf-creator/WebView&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>scade</category>
      <category>swift</category>
      <category>android</category>
      <category>ios</category>
    </item>
    <item>
      <title>How to use SCADE's List Control to build Native Cross-platform Swift Apps</title>
      <dc:creator>Olanrewaju Olakunle</dc:creator>
      <pubDate>Fri, 27 May 2022 09:44:03 +0000</pubDate>
      <link>https://dev.to/cdfcreator/how-to-use-scades-list-control-to-build-native-cross-platform-swift-apps-2i86</link>
      <guid>https://dev.to/cdfcreator/how-to-use-scades-list-control-to-build-native-cross-platform-swift-apps-2i86</guid>
      <description>&lt;p&gt; You can simply use the List control to display a list of scrollable items in your SCADE project. It allows you to display data in a scrollable list format. Users can then click on any list item to select it. We don't need to utilize scroll view or anything else with the List widget in the Swift cross-platform native development platform like SCADE (&lt;a href="https://www.scade.io/download/"&gt;www.scade.io&lt;/a&gt;) because it is scrollable by default. &lt;/p&gt;



&lt;p&gt;The List control is unique and will come in handy when creating cross-platform applications. We'll be using the List control in this tutorial to demonstrate how to use it in a fairly frequent scenario. &lt;/p&gt;


&lt;h2&gt;
  
  
  List Control's Properties
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;List Element&lt;/strong&gt; &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;List Element's Background:&lt;/strong&gt; used for controlling visual component. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clicked Animation Effect:&lt;/strong&gt; very useful when changing the background when a row has been clicked.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;Here, we want to alphabetically display all the European countries and their respective capitals alongside them in our basic SCADE app. &lt;/p&gt;


&lt;p&gt;You'll be able to do the following by the conclusion of this tutorial:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;correctly list data in a list control&lt;/li&gt;
&lt;li&gt;process row click with an event handler&lt;/li&gt;
&lt;li&gt;create a list element with a clicked animation effect&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;Create a new project in your &lt;strong&gt;SCADE IDE&lt;/strong&gt; to work with the List control (if you don't already have one) and follow the steps below:&lt;/p&gt;

&lt;h2&gt;
  
  
  Step One: Add List Control to the desired position on Page
&lt;/h2&gt;

&lt;p&gt;Once you've successfully dragged and dropped the List control to your preferred page of choice, use the constraints box to ensure that the List widget takes up all the available space. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;See the Screenshot below as a Guide:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bvx0iLHU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i72wev7bllx7w2fjk2y3.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bvx0iLHU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i72wev7bllx7w2fjk2y3.jpeg" alt="Image description" width="880" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;How you customize the List control's &lt;strong&gt;list element&lt;/strong&gt; determines how your data is displayed. We put a Grid control within the &lt;strong&gt;list element&lt;/strong&gt; in the basic SCADE app we're building in this tutorial, and we configured it to have two rows and a column to accommodate the &lt;strong&gt;countryName&lt;/strong&gt; and &lt;strong&gt;countryCapital&lt;/strong&gt; text labels. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;See the Screenshot below as a Guide:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1ImTJFQE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0jlugx14c4m9r9vstctc.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1ImTJFQE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0jlugx14c4m9r9vstctc.jpeg" alt="Image description" width="880" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step Two: Create a Data Model
&lt;/h2&gt;

&lt;p&gt;Create a new class in a new swift file in your SCADE project and define the type of data you want to bind to the List control and its properties, just as the &lt;strong&gt;Country class&lt;/strong&gt; in the &lt;strong&gt;Country.swift&lt;/strong&gt; file we created in this tutorial for displaying European countries and their capitals. Above all, don't forget to inherit the &lt;strong&gt;EObject&lt;/strong&gt; class alongside your new class as well. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;See examples below:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lo2DTnOT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/awbjussbyjcp6i81qsi9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lo2DTnOT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/awbjussbyjcp6i81qsi9.png" alt="Image description" width="880" height="541"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MqhGqhSd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mmjhbza3m1ht1652lfym.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MqhGqhSd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mmjhbza3m1ht1652lfym.png" alt="Image description" width="880" height="1154"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step Three: Define and Bind the Data Source to Controls
&lt;/h2&gt;

&lt;p&gt;The next task is to link the view to the model using the &lt;strong&gt;SCDWidgetsElementProvider&lt;/strong&gt; class. How will this be achieved? Set an instance of &lt;strong&gt;SCDWidgetsElementProvider&lt;/strong&gt; with &lt;strong&gt;.elementProvider&lt;/strong&gt; and add the logic that links the data to the List element's visual controls. After that, set the Items property to define the data source.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;See an example below:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9cNLNQgJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/01v2f81bgjdkmax79ui7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9cNLNQgJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/01v2f81bgjdkmax79ui7.png" alt="Image description" width="880" height="546"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Output on iOS:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CCeP5V1m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6tcd3cnhl1e51newpyk7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CCeP5V1m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6tcd3cnhl1e51newpyk7.png" alt="Image description" width="582" height="1182"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--G1OCJbJF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/re3ms8yjrp0dxf7fkw69.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--G1OCJbJF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/re3ms8yjrp0dxf7fkw69.gif" alt="Image description" width="261" height="531"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Output on Android:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TfJpw0g7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/orferxejka5jnlu4q92n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TfJpw0g7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/orferxejka5jnlu4q92n.png" alt="Image description" width="634" height="1334"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tXTkVjoC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/enykf74547508gggoyvb.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tXTkVjoC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/enykf74547508gggoyvb.gif" alt="Image description" width="285" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Additional Features
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;h3&gt;
  
  
  Using event handler to activate row click
&lt;/h3&gt;

&lt;p&gt;You may use &lt;strong&gt;SCDWidgetsItemSelectedEventHandler&lt;/strong&gt; to make an item clickable where it's needed in your SCADE app. This event handler is added to the &lt;strong&gt;.onItemSelected&lt;/strong&gt; handler.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;See an example below:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZuEk2Irm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bn3qe4ij6qwcgturae6t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZuEk2Irm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bn3qe4ij6qwcgturae6t.png" alt="Image description" width="880" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The preceding code snippet will print to the terminal &lt;strong&gt;-Hello and the name of the country-&lt;/strong&gt; that has its row clicked by the user.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;
  
  
  Adding clicked animation effect on List element
&lt;/h3&gt;

&lt;p&gt;One of the most important things to do before using this awesome feature is to import &lt;strong&gt;ScadeUI&lt;/strong&gt; and &lt;strong&gt;ScadeGraphics&lt;/strong&gt; in addition to &lt;strong&gt;ScadeKit&lt;/strong&gt;, which you initially already have imported into your project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;See an example below:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KkR1geYc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sw5enr11ba469d78lnio.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KkR1geYc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sw5enr11ba469d78lnio.png" alt="Image description" width="636" height="484"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After that, you'll need to open the &lt;strong&gt;Package.swift&lt;/strong&gt; file, under dependencies, add the ScadeExtensions repo dependency to your project. This is required to use &lt;strong&gt;ScadeUI&lt;/strong&gt; and &lt;strong&gt;ScadeGraphics&lt;/strong&gt; effectively. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Check the code snippets below to see how to add the dependency:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RrFTyxfQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wzvrovhi5oi1oy22d63v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RrFTyxfQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wzvrovhi5oi1oy22d63v.png" alt="Image description" width="880" height="276"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--J48eO0qO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7wlr1bwwuz051g5jhaa5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--J48eO0qO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7wlr1bwwuz051g5jhaa5.png" alt="Image description" width="880" height="514"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Having correctly followed the above instructions, the next step is to make sure your app's List element's background is set to Fill color. You can't leave or set the background to "None" since there would be no visual component to set the background to.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;See an example below:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3np0RRoM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vulz8rdfz01x7dtw7vw0.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3np0RRoM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vulz8rdfz01x7dtw7vw0.jpeg" alt="Image description" width="880" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, as we have done in this tutorial, you may choose to add another &lt;strong&gt;onItemSelected&lt;/strong&gt; handler or go with just one item selected handler to access the List's List element &lt;strong&gt;SCDWidgetsListElement&lt;/strong&gt; and set the animation effect using the event's element attribute.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;See an example below:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CfHrceqH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/05wviy9a4ywwzt9oll7b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CfHrceqH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/05wviy9a4ywwzt9oll7b.png" alt="Image description" width="880" height="558"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We were able to apply the animation effect to the background of the List element of our SCADE tutorial project using the aforementioned code snippet. To animate the fill property, we chose gold as the initial color and the original color as the finish color, as you can see in the output below (to fill the background).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Output on iOS:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xR50GTjU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ysxxwirehquix6sn3lkn.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xR50GTjU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ysxxwirehquix6sn3lkn.gif" alt="Image description" width="261" height="531"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Output on Android:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NXmqt4g2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hq6eh6x63xk2lsak14dl.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NXmqt4g2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hq6eh6x63xk2lsak14dl.gif" alt="Image description" width="285" height="600"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this SCADE Tutorial, we learned how to create and use a List Control in the SCADE Application. The source code for this tutorial is available on &lt;a href="https://github.com/Cdf-creator/List-Control"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>scade</category>
      <category>swift</category>
      <category>ios</category>
      <category>android</category>
    </item>
  </channel>
</rss>
