<?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: Maarek</title>
    <description>The latest articles on DEV Community by Maarek (@kevinmaarek).</description>
    <link>https://dev.to/kevinmaarek</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%2F121390%2F39125714-3bc0-4f0c-9b33-ba5e0f75279e.jpg</url>
      <title>DEV Community: Maarek</title>
      <link>https://dev.to/kevinmaarek</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kevinmaarek"/>
    <language>en</language>
    <item>
      <title>Deploy your smart contracts on any Ethereum network</title>
      <dc:creator>Maarek</dc:creator>
      <pubDate>Mon, 03 Jan 2022 23:59:02 +0000</pubDate>
      <link>https://dev.to/kevinmaarek/deploy-your-smart-contracts-with-truffle-1igl</link>
      <guid>https://dev.to/kevinmaarek/deploy-your-smart-contracts-with-truffle-1igl</guid>
      <description>&lt;p&gt;So you finally wrote your smart contract, it works fine, you’ve tested it locally, maybe wrote a cool wep app that goes along with it and want to deploy it live? I got you covered.&lt;/p&gt;

&lt;p&gt;In this article, we will se how to use Truffle to deploy any contract on a test network or the main Ethereum network.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choosing a network
&lt;/h2&gt;

&lt;p&gt;First let’s enumerate our network options. Ethereum has a few public test network that we can work on, you can find their name and their specificity on the official &lt;a href="https://ethereum.org/en/developers/docs/networks/"&gt;Ethereum webiste&lt;/a&gt;.&lt;br&gt;
We could also work on the Polygon network which is a Layer 2 network.&lt;/p&gt;
&lt;h2&gt;
  
  
  Setup a wallet
&lt;/h2&gt;

&lt;p&gt;Once you’ve decided where to deploy, we need to have a wallet on that network with some funds on it. Deploying a contract, like any other operation on the Ethereum blockchain isn’t free. If we are working on a public test network, you can create a wallet and claim some free Ether on it with &lt;a href="https://classroom.github.com/a/Iaz_xDSH"&gt;faucets&lt;/a&gt;. I would suggest to use a new wallet that you’ll use only for contract deployment.&lt;/p&gt;
&lt;h2&gt;
  
  
  Infura: your way to the blockchain
&lt;/h2&gt;

&lt;p&gt;For the next steps, we will work with Infura. Infura provides a suite of tools for developers to work on the Ethereum blockchain.&lt;/p&gt;

&lt;p&gt;It allows you to develop anything on the Ethereum network without having to host or setup any of the complexity that working with a large blockchain come with, hosting Ethereum nodes. Essentially Infura is a Blockchain nodes provider.&lt;/p&gt;

&lt;p&gt;To create a infura project, go on the &lt;a href="https://infura.io/"&gt;Infura website&lt;/a&gt;, create an account. Once done, login and go to your dashboard. There you have the option to create a new project. Select Ethereum in the product option and give it a name (you can change the name latter if you want). Infura will generate an API key and a project secret Key. The API key will be required for the next steps.&lt;/p&gt;
&lt;h2&gt;
  
  
  Configure Truffle for your network
&lt;/h2&gt;

&lt;p&gt;First of all, we need a wallet provider. As told before, you need a wallet with a few Ether (or MATIC if you work with the Polygon network) to deploy a contract.&lt;/p&gt;

&lt;p&gt;We will use &lt;code&gt;hdwallet-provider&lt;/code&gt; that does the job well enough.&lt;/p&gt;

&lt;p&gt;In a Terminal on the root of your project type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install --save truffle-hdwallet-provider
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the next step, I’ll assume you’ve setup your project with the command &lt;code&gt;truffle init&lt;/code&gt;, which implies that you have, on your project’s root, a file named &lt;code&gt;truffle-config.js&lt;/code&gt;. That is the file we will work on.&lt;/p&gt;

&lt;p&gt;Before the module.export statement, import the freshly installed wallet provider :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;HDWalletProvider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;truffle-hdwallet-provider&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For now, every time you’ve deployed your contracts, truffle automatically went for the development environment, and has used your local blockchain (probably run with Ganache). We need to add a new network. For now, your file should look like this :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;development&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;127.0.0.1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;7545&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;network_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;mocha&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100000&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;compilers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;solc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0.8.11&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;db&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you would guess, we will add the network we want to deploy to in the &lt;code&gt;networks&lt;/code&gt; object, after &lt;code&gt;development&lt;/code&gt;. For the rest of the post, I will work with the Ropsten network.&lt;/p&gt;

&lt;p&gt;So I will add the following under &lt;code&gt;networks&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;ropsten&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;HDWalletProvider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;YOUR_WALLET_MNEMONIC&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://ropsten.infura.io/YOUR_API_KEY&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nx"&gt;network_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;gas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4000000&lt;/span&gt;      &lt;span class="c1"&gt;//make sure this gas allocation isn't over 4M, which is the max&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are deploying on the main network, name the network “main” instead of “ropsten”, the network id should be &lt;code&gt;1&lt;/code&gt;. For the gas price, you should be able to get an idea of reasonable price checking out the &lt;a href="https://ethgasstation.info/"&gt;Ether Gas Station&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Obviously, replace the mnemonic and the infura URL with the one that goes with the network you are deploying to followed by your project’s API key. You can get the URL from your Infura project setting, there should be a dropdown menu with all the supported networks, just select one and copy past the URL.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;⚠️ Do not commit your mnemonic ⚠️&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Make sure it’s stored in a .env file, or something that is in the .gitignore file. &lt;/p&gt;

&lt;p&gt;You could put your mnemonic on a .secret file, that is listed in the .gitignore and access like :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mnemonic&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;readFileSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.secret&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then you would be good to go! Just run the following :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;truffle&lt;/span&gt; &lt;span class="nx"&gt;deploy&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;network&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;network&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here I would replace &lt;code&gt;&amp;lt;network name&amp;gt;&lt;/code&gt; by &lt;code&gt;ropsten&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Happy deployments 🙂&lt;/p&gt;

</description>
      <category>ethereum</category>
      <category>web3</category>
      <category>solidity</category>
      <category>truffle</category>
    </item>
    <item>
      <title>Testing your smart contract with Truffle</title>
      <dc:creator>Maarek</dc:creator>
      <pubDate>Fri, 31 Dec 2021 09:48:10 +0000</pubDate>
      <link>https://dev.to/kevinmaarek/testing-your-smart-contract-with-truffle-3g6f</link>
      <guid>https://dev.to/kevinmaarek/testing-your-smart-contract-with-truffle-3g6f</guid>
      <description>&lt;p&gt;As you might know testing is very important, especially when working with smart contract and blockchain, as anything in the blockchain is immutable. There is ways to make upgrades to a contract but we’ll get to that in another post.&lt;/p&gt;

&lt;p&gt;For this article, I’ll be working with the fundraiser contract I wrote in my &lt;a href="https://dev.to/kevinmaarek/getting-started-with-solidity-your-first-smart-contract-3mpe"&gt;last post&lt;/a&gt;. Here is the full code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight solidity"&gt;&lt;code&gt;&lt;span class="c1"&gt;// SPDX-License-Identifier: MIT
&lt;/span&gt;&lt;span class="k"&gt;pragma&lt;/span&gt; &lt;span class="n"&gt;solidity&lt;/span&gt; &lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="mf"&gt;0.8&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;contract&lt;/span&gt; &lt;span class="n"&gt;Fundraiser&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;address&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;backers&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;owner&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;sendMoney&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;payable&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"No Ether were sent."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;backers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;getBalance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;view&lt;/span&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint256&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kt"&gt;address&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;this&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nb"&gt;balance&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;endFundraising&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sender&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Only the owner is allowed to end the fundraising."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;payable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nb"&gt;transfer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;this&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nb"&gt;balance&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And I’m assuming you’ve used &lt;code&gt;truffle init&lt;/code&gt; to setup your project, meaning, you have a &lt;code&gt;test&lt;/code&gt; directory in your workspace. This directory should be empty by now.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a test file
&lt;/h2&gt;

&lt;p&gt;We’ll start by creating a new file called &lt;code&gt;fundraiser.js&lt;/code&gt;. We are going to write our test in Javascript. If you are familiar with it, Truffle uses the &lt;a href="https://mochajs.org/"&gt;Mocha testing framework&lt;/a&gt;, with a few differences, it uses &lt;code&gt;contract()&lt;/code&gt; instead of &lt;code&gt;describe()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That &lt;code&gt;contract&lt;/code&gt; method is just used to logically group the tests by contract. Before executing your tests, the function make sure the contract is redeployed to the running environment.&lt;/p&gt;

&lt;p&gt;Here, I’m assuming you have Ganache installed and running.&lt;/p&gt;

&lt;p&gt;So in this empty JavaScript file, we will first get our compiled contract and call the &lt;code&gt;contract&lt;/code&gt; method to start writing test cases:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Fundraiser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;artifacts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./Fundraiser.sol&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Fundraiser&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;accounts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;contract&lt;/code&gt; method has two parameter, the first one would be the name of the contract and the second one is a function that gives you a parameter with a list of account that your environment provided for testing. That’s in that function that we will describe out test cases with Mocha’s &lt;code&gt;it&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;Just like contract, two parameters, a description of the test and the actual test.&lt;br&gt;
We can describe as many tests as we need.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Fundraiser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;artifacts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./Fundraiser.sol&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Fundraiser&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;accounts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;some test&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// ...&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;some other test&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// ...&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Interacting with our contract
&lt;/h2&gt;

&lt;p&gt;While testing a contract you will need to interact with it. The first thing you would want is to access an instance. From the artifact, you can call the &lt;code&gt;.deployed()&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight solidity"&gt;&lt;code&gt;&lt;span class="n"&gt;const&lt;/span&gt; &lt;span class="k"&gt;contract&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Fundraiser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;deployed&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To access a public variable from your contract, we will use the &lt;code&gt;call()&lt;/code&gt; function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight solidity"&gt;&lt;code&gt;&lt;span class="n"&gt;const&lt;/span&gt; &lt;span class="n"&gt;owner&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;await&lt;/span&gt; &lt;span class="k"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;call&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, to call a public function just call the function like you would to on any object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight solidity"&gt;&lt;code&gt;&lt;span class="kr"&gt;let&lt;/span&gt; &lt;span class="nb"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;await&lt;/span&gt; &lt;span class="k"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getBalance&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To add a value or specify the caller’s address, add an optional object :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight solidity"&gt;&lt;code&gt;&lt;span class="n"&gt;await&lt;/span&gt; &lt;span class="k"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sendMoney&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="n"&gt;from&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'0x0...'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: value is in Gwei (1 Gwei = 0,00000001 Ether), to send Ether, just multiply the value by 10 to the power of 18 (&lt;code&gt;10**18&lt;/code&gt; in JavaScript).&lt;br&gt;
You can also the gas and some data as parameter. More on the &lt;a href="https://trufflesuite.com/docs/truffle/getting-started/interacting-with-your-contracts.html"&gt;Truffle documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now you should have anything needed to test our contract.&lt;/p&gt;
&lt;h2&gt;
  
  
  Writing some tests
&lt;/h2&gt;

&lt;p&gt;The first one will verify if the &lt;code&gt;backers&lt;/code&gt; array get properly populated after a backer would have sent some Ether.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight solidity"&gt;&lt;code&gt;    &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"check the participants array after participation"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Get the first account
&lt;/span&gt;        &lt;span class="kr"&gt;let&lt;/span&gt; &lt;span class="n"&gt;account&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;accounts&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="c1"&gt;// Retreive the deployed contract
&lt;/span&gt;        &lt;span class="n"&gt;const&lt;/span&gt; &lt;span class="k"&gt;contract&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Fundraiser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;deployed&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="c1"&gt;// Make the account send 14 gwei
&lt;/span&gt;        &lt;span class="n"&gt;await&lt;/span&gt; &lt;span class="k"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sendMoney&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="n"&gt;from&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="c1"&gt;// Get the particpant at index 0
&lt;/span&gt;        &lt;span class="kr"&gt;let&lt;/span&gt; &lt;span class="n"&gt;backer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;await&lt;/span&gt; &lt;span class="k"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;backers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// Check if that participant is the same as the addess we used
&lt;/span&gt;        &lt;span class="nb"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;backer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will write another test to check the balance increase.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight solidity"&gt;&lt;code&gt;    &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"check the balance increase"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Get the first account
&lt;/span&gt;        &lt;span class="kr"&gt;let&lt;/span&gt; &lt;span class="n"&gt;account&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;accounts&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="c1"&gt;// Retreive the deployed contract
&lt;/span&gt;        &lt;span class="n"&gt;const&lt;/span&gt; &lt;span class="k"&gt;contract&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Fundraiser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;deployed&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="c1"&gt;// Get the balance before the operation
&lt;/span&gt;        &lt;span class="kr"&gt;let&lt;/span&gt; &lt;span class="n"&gt;balanceBefore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;await&lt;/span&gt; &lt;span class="k"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getBalance&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="c1"&gt;// Send 1 gwei
&lt;/span&gt;        &lt;span class="n"&gt;await&lt;/span&gt; &lt;span class="k"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sendMoney&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="n"&gt;from&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="c1"&gt;// Get the balance after the gwei was sent
&lt;/span&gt;        &lt;span class="kr"&gt;let&lt;/span&gt; &lt;span class="n"&gt;balanceAfter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;await&lt;/span&gt; &lt;span class="k"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getBalance&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="c1"&gt;// Check if the balance after is equal to the balance before plus 1
&lt;/span&gt;        &lt;span class="nb"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;balanceAfter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;balanceBefore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One last test to check the end of the fundraising.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight solidity"&gt;&lt;code&gt;    &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"check the balance after the fundraising ends"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Retreive the deployed contract
&lt;/span&gt;        &lt;span class="n"&gt;const&lt;/span&gt; &lt;span class="k"&gt;contract&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Fundraiser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;deployed&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="c1"&gt;// Get the contract owner by accessing the owner attribute
&lt;/span&gt;        &lt;span class="n"&gt;const&lt;/span&gt; &lt;span class="n"&gt;contractOwner&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;call&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="kr"&gt;let&lt;/span&gt; &lt;span class="n"&gt;contractsBalanceBefore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;await&lt;/span&gt; &lt;span class="k"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getBalance&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="kr"&gt;let&lt;/span&gt; &lt;span class="n"&gt;ownersBalanceBefore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;await&lt;/span&gt; &lt;span class="n"&gt;web3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;eth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getBalance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;contractOwner&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// End the fund raising
&lt;/span&gt;        &lt;span class="n"&gt;await&lt;/span&gt; &lt;span class="k"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;endFundraising&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="n"&gt;from&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;contractOwner&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="kr"&gt;let&lt;/span&gt; &lt;span class="n"&gt;contractsBalanceAfter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;await&lt;/span&gt; &lt;span class="k"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getBalance&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="kr"&gt;let&lt;/span&gt; &lt;span class="n"&gt;ownersBalanceAfter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;await&lt;/span&gt; &lt;span class="n"&gt;web3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;eth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getBalance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;contractOwner&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// Check if the contract balance is now zero
&lt;/span&gt;        &lt;span class="nb"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;contractsBalanceAfter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// Check if the owner account received the contract's balance
&lt;/span&gt;        &lt;span class="nb"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ownersBalanceBefore&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;ownersBalanceAfter&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;contractsBalanceBefore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looks like we now have a decent code coverage for our contract.&lt;/p&gt;

&lt;p&gt;We can just run the tests with the command &lt;code&gt;truffle test&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Dont hesitate to check out the amazing documentation from the &lt;a href="https://trufflesuite.com/docs/truffle/testing/writing-tests-in-javascript.html"&gt;truffle website&lt;/a&gt;. You can also check the &lt;a href="https://mochajs.org/"&gt;Mocha documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Feel free to comment if you have any question, or contact me via Twitter.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>solidity</category>
      <category>ethereum</category>
      <category>smartcontract</category>
    </item>
    <item>
      <title>Write your first smart contract in Solidity</title>
      <dc:creator>Maarek</dc:creator>
      <pubDate>Thu, 30 Dec 2021 23:55:03 +0000</pubDate>
      <link>https://dev.to/kevinmaarek/getting-started-with-solidity-your-first-smart-contract-3mpe</link>
      <guid>https://dev.to/kevinmaarek/getting-started-with-solidity-your-first-smart-contract-3mpe</guid>
      <description>&lt;p&gt;Few month ago, I started my journey on Ethereum development. I discovered an amazing and very promising ecosystem that is placing the foundation stones of the futur of the internet as we know it.&lt;/p&gt;

&lt;p&gt;So today, I decided to write a series of article to get started in this environment that may sound very obscure to a lot of people right now.&lt;/p&gt;

&lt;h2&gt;
  
  
  Before we start...
&lt;/h2&gt;

&lt;p&gt;In this article I will cover how to setup a development environment to start working with the Solidity programming language and write a smart contract, then deploy it on a local network. &lt;strong&gt;I will assume you know the basics of programming&lt;/strong&gt; (eg: variables, functions, control flows and loops, class...).&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing everything you  need:
&lt;/h2&gt;

&lt;p&gt;Firstly, you need to &lt;strong&gt;get a NodeJS environment&lt;/strong&gt; set up. If you don’t already have that, you can download NodeJS from the &lt;a href="https://nodejs.org/en/download/"&gt;official website&lt;/a&gt; or use your favorite package manager.&lt;/p&gt;

&lt;p&gt;Now we can &lt;strong&gt;install Truffle&lt;/strong&gt;, an open source tool suite that will allow you to develop, test and deploy your contract.&lt;br&gt;
Use &lt;code&gt;npm install -g truffle&lt;/code&gt; and you’re all set.&lt;/p&gt;

&lt;p&gt;Then, &lt;strong&gt;download Ganache&lt;/strong&gt; from the &lt;a href="https://trufflesuite.com/ganache/"&gt;Truffle website&lt;/a&gt;. This tool will allow you to setup a personal Ethereum blockchain that you can use to run and test your contract.&lt;/p&gt;

&lt;p&gt;Finally, you can fire up any IDE, time to code. I would recommend VSCode with the &lt;a href="https://github.com/juanfranblanco/vscode-solidity"&gt;Solidity plugin&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Time to code!
&lt;/h2&gt;

&lt;p&gt;Alright, the first thing to do once you’ve downloaded everything is to init a project. To do so, create a new directory and let truffle do his thing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir fundraiser-contract
cd fundraiser-contract
truffle init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Directory and files will be created :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;├── contracts
│   └── Migrations.sol
├── migrations
│   └── 1_initial_migration.js
├── test
└── truffle-config.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We’ll quickly go over these files :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;contracts/&lt;/code&gt; will contains your solidity sources. It already have a contract in it, called Migration (.sol is the solidity extension). This contract keeps track of migrations and deployment in the network you’re working on.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;migrations/&lt;/code&gt; contains your smart contracts deployments logic.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;test/&lt;/code&gt; as you can guess is here for your testing environment.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Good, we’re all set. Now we’re going to create a new contract. Let’s work on a simple fundraiser contract.&lt;/p&gt;

&lt;p&gt;So let’s start by creating a new solidity file, say &lt;code&gt;Fundraiser.sol&lt;/code&gt; in the &lt;code&gt;contract&lt;/code&gt; directory. Then we’ll add a license, a version directive and create a contract:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight solidity"&gt;&lt;code&gt;&lt;span class="c1"&gt;// SPDX-License-Identifier: MIT
&lt;/span&gt;&lt;span class="k"&gt;pragma&lt;/span&gt; &lt;span class="n"&gt;solidity&lt;/span&gt; &lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="mf"&gt;0.8&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;contract&lt;/span&gt; &lt;span class="n"&gt;Fundraiser&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Specifying a license is mandatory in solidity. The pragma statement is used to tell the compiler which Solidity version it should use.&lt;/p&gt;

&lt;p&gt;This contract will have few things :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The owner’s address, which deployed the contract &amp;amp; the one who will get the money collected by the contract.&lt;/li&gt;
&lt;li&gt;An array of the backers, so the owner can personally thank them.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So we will add these as attributes like you would on a regular class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight solidity"&gt;&lt;code&gt;&lt;span class="k"&gt;contract&lt;/span&gt; &lt;span class="n"&gt;Fundraiser&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;address&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;backers&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, I’ll set all the variables’ access to public.&lt;/p&gt;

&lt;p&gt;To get the owner’s address we will just implement the contract’s constructor and get his address from here. In solidity there is a few global variable that you can access. Here we will use &lt;code&gt;msg&lt;/code&gt;, which contains the address of the one who calls the functions: &lt;code&gt;msg.sender&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Our constructor would look like :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight solidity"&gt;&lt;code&gt;&lt;span class="k"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;owner&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we need a function accessible to anyone to send some Ether to this contract. We’ll call it &lt;code&gt;sendMoney&lt;/code&gt; cause that’s what it actually does.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight solidity"&gt;&lt;code&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;sendMoney&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;payable&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"No Ether were sent."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;backers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first statement is a &lt;code&gt;require&lt;/code&gt; call. He's here to check if the condition given as its first argument is true, otherwise, the function will stop its execution and the transaction will be reverted with the error message passed as second argument. Here we want to make sure the caller actually sent some Ether: we check if the function caller &lt;em&gt;attached&lt;/em&gt; a value: &lt;code&gt;msg.value&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Note that the function is marked &lt;code&gt;public&lt;/code&gt; and &lt;code&gt;payable&lt;/code&gt; so anyone can call it, and send Ether.&lt;/p&gt;

&lt;p&gt;Then, we just add the sender’s address to the backers list.&lt;/p&gt;

&lt;p&gt;Next we want to let the owner get it’s freshly raised money. So let’s make a function called &lt;code&gt;endFundraising&lt;/code&gt; that will collect the money.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight solidity"&gt;&lt;code&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;endFundraising&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sender&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Only the owner is allowed to end the fundraising."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;payable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nb"&gt;transfer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;this&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nb"&gt;balance&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That function will be public but we are going to make sure that the caller (&lt;code&gt;msg.sender&lt;/code&gt;) is the owner with a &lt;code&gt;require&lt;/code&gt; statement.&lt;br&gt;
Then, we can just transfer its funds to the owner with the Solidity &lt;code&gt;transfer&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;Just for fun, I’ll also add a get balance function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight solidity"&gt;&lt;code&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;getBalance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;view&lt;/span&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint256&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kt"&gt;address&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;this&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nb"&gt;balance&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every contract has a balance and can hold funds.&lt;/p&gt;

&lt;p&gt;And we’re done! You just wrote your first contract 😎.&lt;/p&gt;

&lt;p&gt;Here is the full code :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight solidity"&gt;&lt;code&gt;&lt;span class="c1"&gt;// SPDX-License-Identifier: MIT
&lt;/span&gt;&lt;span class="k"&gt;pragma&lt;/span&gt; &lt;span class="n"&gt;solidity&lt;/span&gt; &lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="mf"&gt;0.8&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;contract&lt;/span&gt; &lt;span class="n"&gt;Fundraiser&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;address&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;backers&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;owner&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;sendMoney&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;payable&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"No Ether were sent."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;backers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;getBalance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;view&lt;/span&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint256&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kt"&gt;address&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;this&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nb"&gt;balance&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;endFundraising&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sender&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Only the owner is allowed to end the fundraising."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;payable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nb"&gt;transfer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;this&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nb"&gt;balance&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, this contract is quite simple, and I bet you can see a lot of evolutions, such as locking the fundraising once the funds has been transferred, also, wouldn’t it be nice to have a cool web app that would allow any user to send the funds?&lt;/p&gt;

&lt;h2&gt;
  
  
  Let’s deploy!
&lt;/h2&gt;

&lt;p&gt;Ok, so the contract should work right? The next step would be to deploy it on your personal network.&lt;/p&gt;

&lt;p&gt;And, hey, I can ear you: “Woow!! Are we about to deploy this? Shouldn’t we write tests before and make sure it passes all? What kind of developer is this guy!”...&lt;br&gt;
And you are right. But I keep the testing part for &lt;a href="https://dev.to/kevinmaarek/testing-your-smart-contract-with-truffle-3g6f"&gt;another post&lt;/a&gt;. This one is getting quite long already - don’t be mad.&lt;/p&gt;

&lt;p&gt;Earlier, you installed Ganache. Launch it, click on Quickstart, it will automatically start and setup an Ethereum blockchain on your local network and give you 10 accounts loaded with 100 fake Ether to play with it. Once started, we can prepare our deployment.&lt;/p&gt;

&lt;p&gt;Remember that &lt;code&gt;migration&lt;/code&gt; directory? Create a new JavaScript file called &lt;code&gt;2_deploy_contracts.js&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In this file we will write the deployment/migration code for our contract. It’s pretty standard, you can just copy past it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight solidity"&gt;&lt;code&gt;&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;Fundraiser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;artifacts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"./Fundraiser.sol"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;deployer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;deployer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;deploy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Fundraiser&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you’re really done. You would just need to type the command &lt;code&gt;truffle migrate&lt;/code&gt;, in you terminal (make sure you’re in your project’s root).&lt;/p&gt;

&lt;p&gt;Now what? &lt;a href="https://dev.to/kevinmaarek/testing-your-smart-contract-with-truffle-3g6f"&gt;Testing time!&lt;/a&gt; &lt;a href="https://dev.to/kevinmaarek/deploy-your-smart-contracts-with-truffle-1igl"&gt;Deployment?&lt;/a&gt; And, wouldn’t it be nice to test it with a small web app? Yup, that’s what’s next!&lt;/p&gt;

&lt;p&gt;Don’t hesitate to comment or contact me via Twitter if you have any question.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>solidity</category>
      <category>ethereum</category>
      <category>web3</category>
      <category>smartcontract</category>
    </item>
    <item>
      <title>Create your own command line tools in Swift</title>
      <dc:creator>Maarek</dc:creator>
      <pubDate>Tue, 15 Dec 2020 17:25:31 +0000</pubDate>
      <link>https://dev.to/kevinmaarek/create-your-own-command-line-tools-in-swift-4l18</link>
      <guid>https://dev.to/kevinmaarek/create-your-own-command-line-tools-in-swift-4l18</guid>
      <description>&lt;p&gt;Swift is certainly a great programming language for developing apps made for the Apple ecosystem. But as you know, Swift, as a language, is not Apple specific. You can use Swift in many other areas such as backend (with Vapor). Swift runs on Linux and Windows too.&lt;br&gt;
Today I would like to present a quick "Getting started" post about how to make your own command line tools with Swift.&lt;/p&gt;

&lt;p&gt;As a developer there is many tasks that I'm sure you have already made your own tools for, to automate them.&lt;br&gt;
Cropping images, scrapping stuff from the internet, generating all kind of files or config stuff... You name it.&lt;br&gt;
Today I'll try to demonstrate how to create your own tool using Swift, the Swift package manager, and the argument parser.&lt;/p&gt;
&lt;h2&gt;
  
  
  Building a command line tool using the Swift Package Manager
&lt;/h2&gt;

&lt;p&gt;I find very useful to have an image comparison tool on my computer. I have a lot of UITests on my apps and while the tests are running, they automatically take screenshots of the screen. There are many use-cases such as upload them to iTunes Connect, but I also use it to compare screens over time and over versions of my apps. If I see any unexpected difference between my "Base" screenshots and the one taken while testing, I know something is wrong with my UI.&lt;/p&gt;
&lt;h3&gt;
  
  
  So today we'll be building an image comparison command line tool
&lt;/h3&gt;

&lt;p&gt;Let's start by creating the project :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mkdir img_cmp
$ cd img_cmp
$ swift package init --type executable
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nothing crazy here; I create an &lt;code&gt;img_cmp&lt;/code&gt; directory for my project and initilize the project.&lt;br&gt;
A folder structure hase been created for me :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Creating executable package: img_cmp
Creating Package.swift
Creating README.md
Creating .gitignore
Creating Sources/
Creating Sources/img_cmp/main.swift
Creating Tests/
Creating Tests/LinuxMain.swift
Creating Tests/img_cmpTests/
Creating Tests/img_cmpTests/img_cmpTests.swift
Creating Tests/img_cmpTests/XCTestManifests.swift
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Awesome, now you can build and run the project with command line :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;swift build
swift run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you're on a macOS machine and have XCode installed, you can double click on Packaged.swift, it will open the project.&lt;br&gt;
Otherwise you can simply open Sources/img_cmp/main.swift in you favorite text editor.&lt;/p&gt;

&lt;p&gt;Now we are going to import the Argument Parser. This is a Swift package made by Apple to get simple user input via arguments while running the program.&lt;/p&gt;

&lt;p&gt;In your Package.swift file, you will add the dependancy as follow :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let package = Package(
    name: "img_cmp",
    dependencies: [
        .package(url: "https://github.com/apple/swift-argument-parser", from: "0.3.0"),
    ],
    targets: [
        .target(
            name: "img_cmp",
            dependencies: [
                .product(name: "ArgumentParser", package: "swift-argument-parser"),
            ]),
        .testTarget(
            name: "img_cmpTests",
            dependencies: ["img_cmp"]),
    ]
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you have added the Argument Parser framework. If you are on XCode, it will automatically update the dependancy package and resolve the dependancy versions.&lt;/p&gt;

&lt;p&gt;In the main.swift, we can now import the framework :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import ArgumentParser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Creating the program
&lt;/h3&gt;

&lt;p&gt;We need to start by creating a parsable command. Nothing simpler: make a struct that conforms to &lt;code&gt;ParsableCommand&lt;/code&gt;, a protocol defined in the Argument Parser framework.&lt;br&gt;
Here I'll call it &lt;code&gt;ImgCmp&lt;/code&gt;.&lt;br&gt;
After that, we'll call the static &lt;code&gt;main&lt;/code&gt; function, that will take care of running the program for me.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;struct ImgCmp: ParsableCommand {

}
ImgCmp.main()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great, now to make our program do something, I will implement the function &lt;code&gt;run&lt;/code&gt; in our struct (also defined in the protocol &lt;code&gt;ParsableCommand&lt;/code&gt;). This will be the method used to execute the command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;struct ImgCmp: ParsableCommand {
    func run() throws { }
}
ImgCmp.main()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice this command can throw error, so the OS can catch the exit status of your program.&lt;/p&gt;

&lt;h3&gt;
  
  
  Get all the arguments !
&lt;/h3&gt;

&lt;p&gt;Alright now we want the user to input two images to compare one to another. So we'll need (at least) 2 arguments.&lt;br&gt;
The ArgumentParser let use input 3 type of arguments :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Arguments&lt;br&gt;
That's a required input needed for the program to run.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Options&lt;br&gt;
An option is an extra value that the user can input for a specific behaviour.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Flag&lt;br&gt;
A Flag is a simple option that the user can add or not.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nano -L /path/to/file --tabsize=1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we use the command &lt;code&gt;nano&lt;/code&gt; which is used to edit a file.&lt;br&gt;
&lt;code&gt;-L&lt;/code&gt; is a flag (Don't add newlines to the ends of files).&lt;br&gt;
&lt;code&gt;/path/to/file&lt;/code&gt; is an argument (The file to edit).&lt;br&gt;
&lt;code&gt;--tabsize=1&lt;/code&gt; is an option (Set the size (width) of a tab to cols columns).&lt;/p&gt;

&lt;p&gt;To parse argument, the framework makes everything for us.&lt;br&gt;
It's based on property wrappers - that you might have used with SwiftUI and it's pretty simple :&lt;br&gt;
Every argument is an attribute of the struct (here &lt;code&gt;ImgCmp&lt;/code&gt;) and the propery wrapper takes parameters to define and specify the argument.&lt;br&gt;
Let's start with our two main arguments :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Argument(help: "The reference image.")
var base: String

@Argument(help: "The image to compare.")
var image: String
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now if you run the command without two arguments it should say:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ img_cmp swift run img_cmp
Error: Missing expected argument '&amp;lt;base&amp;gt;'

USAGE: img-cmp &amp;lt;base&amp;gt; &amp;lt;image&amp;gt;

ARGUMENTS:
  &amp;lt;base&amp;gt;                  The reference image. 
  &amp;lt;image&amp;gt;                 The image to compare. 

OPTIONS:
  -h, --help              Show help information.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But add some strings and you're good :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ img_cmp swift run img_cmp /Users/me/Desktop/a.png /Users/me/Desktop/b.png
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now for me, this is not enough. I want the user to be able to specify a tolerance for comparing. Say if A is 99% B, it's okay for me.&lt;br&gt;
For that we'll add an option&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Option(name: [.customLong("tolerance"), .customShort("t")], help: "The tolerance to consider an image identical as a value from 0 to 1.\n 0 is strictly identical.")
    var tolerence: Float?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the Option property wrapper, you can specify a long and a short name (here "tolerance" and "t").&lt;br&gt;
Now we can use execute :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ img_cmp swift run img_cmp /Users/me/Desktop/a.png /Users/me/Desktop/b.png -t 0.01
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's also add a verbose flag. If the user would like to display more information and non blocking messages. A basic "-v" will work for me.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Flag(name: [.customLong("verbose"), .customShort("v")], help: "Show logs, information and non blocking messages.")
var verbose = false
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Back the to run function : to exit a program, just throw an ExitCode (.success, .failure...). Just add an exit statement to the function : &lt;code&gt;throw ExitCode.success&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  There you go!
&lt;/h3&gt;

&lt;p&gt;Now I wont (unless you ask for it in the comment) write about the program's body because it's kind of out of subject (and in real life, you would probably use imagemagick ^^), but here how your code should look like so far:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import ArgumentParser

struct ImgCmp: ParsableCommand {

    @Argument(help: "The reference image.")
    var base: String

    @Argument(help: "The image to compare.")
    var image: String

    @Flag(name: [.customLong("verbose"), .customShort("v")], help: "Show logs, information and non blocking messages.")
    var verbose = false

    @Option(name: [.customLong("tolerance"), .customShort("t")], help: "The tolerance to consider an image identical, as a value from 0 to 1.\n 0 is stricly identical.")
    var tolerance: Float?

    func run() throws {
        // here you would compare the images, log stuff and return the right status code.
        throw ExitCode.success
    }
}

ImgCmp.main()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I hope you enjoyed this simple post. Don't hestitate to ask any question in the comment section, I'll be glad to help :).&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>swift</category>
      <category>command</category>
      <category>tools</category>
      <category>ios</category>
    </item>
    <item>
      <title>View Controller containment in Swift</title>
      <dc:creator>Maarek</dc:creator>
      <pubDate>Sat, 14 Nov 2020 17:56:56 +0000</pubDate>
      <link>https://dev.to/kevinmaarek/view-controller-containment-in-swift-7ac</link>
      <guid>https://dev.to/kevinmaarek/view-controller-containment-in-swift-7ac</guid>
      <description>&lt;p&gt;Containment of view controllers is an often used technique in UIKit.&lt;br&gt;
It allows to drastically reduce the complexity of a view controller, very easily, simply by splitting it into multiple smaller ones.&lt;br&gt;
Having smaller view controllers, with a reduced functional scope, makes testing easier, so as reusability across your codebase.&lt;/p&gt;
&lt;h3&gt;
  
  
  Pratical example
&lt;/h3&gt;

&lt;p&gt;Let’s say you have a video player in your app. The first third of the screen would be used for the actual video player, with the controls and everything (play/pause, time indicator), and the rest of the screen would display the playlist. A very common layout - the exact one you would find on the YouTube app.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IPVqMSzx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/a2geg3ns3jcaxmtxigdc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IPVqMSzx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/a2geg3ns3jcaxmtxigdc.png" alt="YouTube-like player layout" width="527" height="491"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I would be very suitable to split this PlayerViewController into :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;VideoPlayerViewController&lt;/li&gt;
&lt;li&gt;PlaylistViewController&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The two smaller view controller would have simple interfaces like delegates :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    func playerDidEndPlaying(player: Player, media: Media)
    func playlistDidSelect(playlist: Playlist, media: Media)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Allowing you to build a “main” view controller that would implement these methods and be used as data source for your two child view controller.&lt;br&gt;
The best part is if you wish you swap the playlist for a comment section - say, after a user action, you would just replace the Playlist child view controller by a CommentViewController.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Y8nYwtnB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/vuduhqcwrt8vebetzops.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Y8nYwtnB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/vuduhqcwrt8vebetzops.png" alt="Alt Text" width="880" height="503"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You would then be able to test independently the comment, player and playlists view controllers.&lt;br&gt;
As you can see, view controller containment is great for reusability, a better code organization, reducing complexity and better testing.&lt;/p&gt;

&lt;p&gt;Here is a very helpful extension to add and remove a child view controller.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;extension UIViewController {
    /// Add a child UIViewController to a given UIView. If `view` is set to nil or not set, it will add the child the ViewController's view.
    /// - Parameters:
    ///   - child: Child view controller as a UIViewController
    ///   - view: Target UIVew that will contain the child
    func add(_ child: UIViewController, view: UIView? = nil) {
        let view: UIView = view ?? self.view
        addChild(child)
        child.view.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(child.view)
        NSLayoutConstraint.activate([
            child.view.topAnchor.constraint(equalTo: view.topAnchor),
            child.view.bottomAnchor.constraint(equalTo: view.bottomAnchor),
            child.view.leftAnchor.constraint(equalTo: view.leftAnchor),
            child.view.rightAnchor.constraint(equalTo: view.rightAnchor),
        ])
        child.didMove(toParent: self)
    }


    /// Remove a child viewController from it's container
    func remove() {
        guard parent != nil else {
            return
        }
        willMove(toParent: nil)
        view.removeFromSuperview()
        removeFromParent()
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A simple use-case based on the given example with a PlayerViewController would render as follow :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class PlayerViewController: UIViewController {
    let player = VideoPlayerViewController()
    let playlist = PlaylistViewController()
    let comment = CommentViewController()

    let playerViewContainer = UIView()
    let bottomViewContainer = UIView()

    override func viewDidLoad() {
        super.viewDidLoad()
        self.add(self.player, view: self.playerViewContainer)
        self.add(self.playlist, view: self.bottomViewContainer)
    }

    func showComment() {
        self.playlist.remove()
        self.add(self.comment, view: self.bottomViewContainer)
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, it is very simple and makes the "main" view controller clean, and free from player, playlist or comment related business logic!&lt;br&gt;
Aside of the reusability and cleanness of view controllers containment, the main benefit is that the child view controllers can interact with the parent's life cycle (&lt;code&gt;didLoad&lt;/code&gt;, &lt;code&gt;didAppear&lt;/code&gt;...).&lt;/p&gt;

&lt;p&gt;I hope you enjoyed this little post. I like sharing about my way of coding, if you have any question, feel free to hit me on Twitter or use the comment section :)&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>ios</category>
      <category>swift</category>
      <category>uikit</category>
    </item>
    <item>
      <title>Dependency Inversion Principle in Swift</title>
      <dc:creator>Maarek</dc:creator>
      <pubDate>Thu, 12 Nov 2020 10:30:44 +0000</pubDate>
      <link>https://dev.to/kevinmaarek/dependency-inversion-principle-in-swift-1h15</link>
      <guid>https://dev.to/kevinmaarek/dependency-inversion-principle-in-swift-1h15</guid>
      <description>&lt;p&gt;You may have heard about the Dependency Inversion principle from the OOP’s SOLID design guidelines.&lt;br&gt;
The idea behind this principle is that an implementation should only be dependant of interfaces and abstractions - never of another implementation.&lt;br&gt;
It also brings us the concept that a higher level module should never be dependant of a lower level module.&lt;/p&gt;
&lt;h3&gt;
  
  
  Protocol to the rescue
&lt;/h3&gt;

&lt;p&gt;In Swift, with protocols, you can get rid of any implementation dependency and instead rely on the implementation of a protocol.&lt;/p&gt;
&lt;h3&gt;
  
  
  Real life example
&lt;/h3&gt;

&lt;p&gt;Let say you have a network stack :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class AppServices {
    // AppServices will keep an instance of network and any other lower stack
    // that must have a shared instance. Eg: Persistence.
    static let network: AppNetwork = AppNetwork()
}

class AppNetwork {
    // This class is in charge of auth, holds the token and requests queue
    func fetch(_ operation: NetworkOperation, completion: NetworkCompletion)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And a controller that requests a list of data from an API, using the network stack :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class ViewController: UIViewController {
    func loadData() {
        AppServices.network.fetch(ListData) {
            self.view.refresh(listData)
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Network stack is a low level module, and the ViewController is tightly coupled with AppNetwork’s implementation throughout AppServices.&lt;/p&gt;

&lt;p&gt;We can solve this dependency issue by recreating the Network as a protocol :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;protocol Network {
    func fetch(_ operation: NetworkOperation, completion: NetworkCompletion) {}
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and make the AppNetwork conforms to Network :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class AppServices {
    static let network: Network = AppNetwork()
}

class AppNetwork: Network { … }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, AppServices wont hold a AppNetwork implementation but an abstract implementation of Network.&lt;br&gt;
Another benefit of this is you can easily mock your networks stack, simply by replacing the implementation of Network.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class MockedNetwork: Network {
    func fetch(_ operation: NetworkOperation, completion: NetworkCompletion) {
        completion(stubResult, fakeError)
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// make sure you set the static as a `var` and not a `let`
AppService.network = MockedNetwork()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Following this principle in this specific scenario is a very nice and clean way to improve the testability of any network dependant code, the flexibility and the scalability of your network stack, and you can remove any coupling of your app's controllers or view to your app's lower stacks.&lt;/p&gt;

&lt;p&gt;I hope you enjoy this little post.&lt;br&gt;
I chose to cover the dependency inversion principle as I feel it is a very useful and important principle to follow while coding and a great way to improve code and product's quality. I would be happy to answer any question in the comment section or feel free to reach via my Twitter ;)&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>swift</category>
      <category>design</category>
      <category>solid</category>
      <category>dependency</category>
    </item>
    <item>
      <title>Add iPad OS multiple windows support</title>
      <dc:creator>Maarek</dc:creator>
      <pubDate>Mon, 28 Oct 2019 14:28:01 +0000</pubDate>
      <link>https://dev.to/kevinmaarek/add-ipad-os-multiple-windows-support-1451</link>
      <guid>https://dev.to/kevinmaarek/add-ipad-os-multiple-windows-support-1451</guid>
      <description>&lt;p&gt;iPad OS 13 introduces the support of &lt;a href="https://developer.apple.com/design/human-interface-guidelines/ios/system-capabilities/multiple-windows/" rel="noopener noreferrer"&gt;multi windows&lt;/a&gt;. You can now have multiple “instances” or copies of the same app through separated windows.&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F9ozr7oimpez2oknh8bt5.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F9ozr7oimpez2oknh8bt5.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The implementation of such a feature requires some re-work of the current app life cycle.&lt;/p&gt;

&lt;p&gt;The first step is to add a SceneDelegate to your app. If you don't know how to, I suggest my &lt;a href="https://dev.to/kevinmaarek/add-a-scene-delegate-to-your-current-project-5on"&gt;previous post&lt;/a&gt; about it.&lt;/p&gt;

&lt;p&gt;Now, understand that a window, in iOS, is a scene and as Apple's documentation says :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A scene contains the windows and view controllers for presenting one instance of your UI. Each scene also has a corresponding UIWindowSceneDelegate object, which you use to coordinate interactions between UIKit and your app.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So how it's going to work will be pretty basic :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The user will drag and drop an item to create a new window of your app.&lt;/li&gt;
&lt;li&gt;The system will instantiate a new Scene, requesting a scene to connect to your app's session.&lt;/li&gt;
&lt;li&gt;The app's SceneDelegate will be notified that a scene has been requested to connect to it's session.
It will evaluate what kind of scene is requested by it's connection options, and will present the correct view controller.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Therefore, all of your presentation logic will gravitate around your SceneDelegate's &lt;code&gt;sceneWillConnectToSession&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;You will get the connection options object (of type &lt;code&gt;ConnectionOptions&lt;/code&gt;) in parameter of the &lt;code&gt;sceneWillConnectToSession&lt;/code&gt; function.&lt;br&gt;
It's prototype looks like this :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    open class ConnectionOptions : NSObject {
        open var urlContexts: Set&amp;lt;UIOpenURLContext&amp;gt; { get }
        open var sourceApplication: String? { get }
        open var handoffUserActivityType: String? { get }
        open var userActivities: Set&amp;lt;NSUserActivity&amp;gt; { get }
        open var notificationResponse: UNNotificationResponse? { get }
        open var shortcutItem: UIApplicationShortcutItem? { get }
        open var cloudKitShareMetadata: CKShareMetadata? { get }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The property that we will work with is the &lt;code&gt;userActivities&lt;/code&gt;.&lt;br&gt;
This is how we will differentiate our Scenes.&lt;br&gt;
So we need to set our different activites types.&lt;/p&gt;

&lt;p&gt;In your project's &lt;code&gt;info.plist&lt;/code&gt;, add a new array called &lt;code&gt;NSUserActivityTypes&lt;/code&gt; in which you will create every type of window you will want to be presentable with a string identifier.&lt;/p&gt;

&lt;p&gt;To illustrate this article I will make a restaurants list app.&lt;br&gt;
In this app, there is only one window type I will need : the one for a restaurant detail page, displaying the info, address, and reviews of a restaurant.&lt;/p&gt;

&lt;p&gt;So I will create one type "restaurant". This is what I have.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    &amp;lt;key&amp;gt;NSUserActivityTypes&amp;lt;/key&amp;gt;
    &amp;lt;array&amp;gt;
        &amp;lt;string&amp;gt;restaurant&amp;lt;/string&amp;gt;
    &amp;lt;/array&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now to make it easier to work with activity types in the code I will create an enum (of strings) with every activity type specified.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;enum ActivityType: String {
    case restaurant
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now all I have to do in my SceneDelegate, is go in the SceneWillConnectToSession method and distinguish the requested scene and present the right ViewController.&lt;/p&gt;

&lt;p&gt;Here is how to do this :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        guard let _ = (scene as? UIWindowScene) else { return }
        if let userActivity = connectionOptions.userActivities.first ?? session.stateRestorationActivity {
            // User request new window with userActivity
            switch MyActivityType(rawValue: userActivity.activityType) {
            case .restaurant:
                // Present the restaurant view controller
            case .none:
                // Present the hone view controller
            }
        } else {
            // This is an initial app launch
            self.present(viewController: ViewController(), scene: scene)
            // You don't need an else case if you have a main storyboard
        }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To present a ViewController from here, if you are using a main storyboard, the &lt;code&gt;window&lt;/code&gt; property will automatically be loaded with the storyboard's initial view controller.&lt;br&gt;
So you just need to check if the rootViewController is present (and is a NavigationController) and then push your ViewController on it, like this :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if let navigationController = window?.rootViewController as? UINavigationController {
    navigationController.pushViewController(yourViewController, animated: false)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are not using a main storyboard, you need initialize the window and set the root, like this :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if let windowScene = scene as? UIWindowScene {
    self.window = UIWindow(windowScene: windowScene)
    let mainNavigationController = UINavigationController(rootViewController: yourViewController)
    self.window!.rootViewController = mainNavigationController
    self.window!.makeKeyAndVisible()
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🥳 Now your app can open windows ! 🎉&lt;/p&gt;

&lt;h3&gt;
  
  
  Requesting new windows from the code
&lt;/h3&gt;

&lt;p&gt;Having a "Open in a new window" button right in your view could be interesting in some cases.&lt;br&gt;
To request a new window, you just need to request a scene session, with the activity you want.&lt;/p&gt;

&lt;p&gt;If you want a new "restaurant" window :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let activity: NSUserActivity = NSUserActivity(activityType: ActivityType.restaurant.rawValue)
UIApplication.shared.requestSceneSessionActivation(nil, userActivity: activity, options: nil, errorHandler: nil)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can use userInfo dictionary to pass more data such as an id.&lt;/p&gt;

&lt;p&gt;And that's it : a new window will automatically be opened.&lt;/p&gt;

&lt;h3&gt;
  
  
  Enabling drag and drop from a Table/Collection view to open your detail view controller in a new window
&lt;/h3&gt;

&lt;p&gt;Let’s say you have a TableView (or a CollectionView) of items which, on tap, will push some kind of detail ViewController, a pretty useful scenario.&lt;br&gt;
In your CollectionView or TableView, you need to set a dragDelegate, and conform to the method itemForBeginningSessionAtIndexPath and return a DragItem containing the requested UserActivty.&lt;/p&gt;

&lt;p&gt;Here is an example :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    func collectionView(_ collectionView: UICollectionView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -&amp;gt; [UIDragItem] {
        // Create a userActivity with the activity type you want
        let userActivity = NSUserActivity(activityType: ActivityType.restaurant.rawValue)
        // You can use userInfo dictionary to pass more data such as an id.
        userActivity.userInfo!["id"] = self.data[indexPath.row].id()

        // Create an item provider with our activity
        let itemProvider = NSItemProvider()
        itemProvider.registerObject(userActivity, visibility: .all)

        // Create a drag item containing the itemProvider and return it in an array
        let dragItem = UIDragItem(itemProvider: itemProvider)
        return [dragItem]
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can just drag any of you collection/table view cells to open windows.&lt;/p&gt;

&lt;p&gt;Hope you enjoyed this multiple windows on iPad OS overview.&lt;br&gt;
A sample app, with a restaurant list is available on my GitHub.&lt;/p&gt;

&lt;p&gt;I will be glad to try to help if you have any question or issues.&lt;/p&gt;

&lt;p&gt;Happy coding ! 😊&lt;/p&gt;

</description>
      <category>swift</category>
      <category>ios</category>
    </item>
    <item>
      <title>Add a Scene Delegate to your current project</title>
      <dc:creator>Maarek</dc:creator>
      <pubDate>Mon, 28 Oct 2019 14:26:58 +0000</pubDate>
      <link>https://dev.to/kevinmaarek/add-a-scene-delegate-to-your-current-project-5on</link>
      <guid>https://dev.to/kevinmaarek/add-a-scene-delegate-to-your-current-project-5on</guid>
      <description>&lt;p&gt;With iOS 13's introduced UIWindowScene and multiple window support for iPad OS, you might be looking to add Scene Delegate to your existing app (if you are willing to add support of multi window support, for example 😉).&lt;/p&gt;

&lt;p&gt;Before iOS 13, the main entry point for your app was the AppDelegate, and it was in charge of many logic and state handling. Now the work of the AppDelegate has been split, between the AppDelegate and the SceneDelegate.&lt;/p&gt;

&lt;p&gt;The AppDelegate being only responsible for the initial app setup, the SceneDelegate will handle and manage the way your app is shown.&lt;br&gt;
As an app could have multiple instances, a SceneDelegate will be called every time an instance of your app is created.&lt;/p&gt;

&lt;p&gt;To add a scene delegate, first, create a new Swift file that you’ll call "SceneDelegate" containing a subclass of &lt;code&gt;UIResponder&lt;/code&gt;, just like the AppDelegate, and that conforms to &lt;code&gt;UIWindowSceneDelegate&lt;/code&gt;. As your app might supports other versions than iOS 13, make this class only available for iOS 13.&lt;/p&gt;

&lt;p&gt;This is what you should have :&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

//
//  SceneDelegate.swift
//
import UIKit

@available(iOS 13.0, *)
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    // ...
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;To this class, add a &lt;code&gt;UIWindow&lt;/code&gt; property. That will be your main window, you will need it to present your View Controllers.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

var window: UIWindow?


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Finally, you need to implement the SceneWillConnectToSession method in your class.&lt;br&gt;
This method is the way that notifies us about the addition of a scene to the app, a scene could be seen as a window.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {

    }


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  If you are working a project that is storyboard based,
&lt;/h3&gt;

&lt;p&gt;you could leave this method empty.&lt;br&gt;
That means that you have a &lt;code&gt;UIMainStoryboardFile&lt;/code&gt; specified in your &lt;code&gt;info.plist&lt;/code&gt; with a ViewController set as initial (with an arrow on it's side).&lt;/p&gt;
&lt;h3&gt;
  
  
  If you are not working with a main storyboard,
&lt;/h3&gt;

&lt;p&gt;you should have your view hierarchy set in you AppDelegate's &lt;code&gt;applicationDidFinishLaunchingWithOptions&lt;/code&gt; method. Then you want to add the same code in your &lt;code&gt;SceneWillConnectToSession&lt;/code&gt; function, and instead of working with a &lt;code&gt;UIWindow&lt;/code&gt;, it's a &lt;code&gt;UIWindowScene&lt;/code&gt; that will host your root.&lt;br&gt;
You will also want to wrap your AppDelegates code into an &lt;code&gt;#available&lt;/code&gt; check to make sur it wont be executed if your SceneDelegate does it.&lt;/p&gt;

&lt;p&gt;So this is what you should have in your AppDelegate :&lt;br&gt;
(ViewController being your app's "Home"/"Main")&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

    // AppDelegate

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -&amp;gt; Bool {
        if #available(iOS 13.0, *) { } else {
            self.window = UIWindow(frame: UIScreen.main.bounds)
            let mainViewController = ViewController()
            let mainNavigationController = UINavigationController(rootViewController: mainViewController)
            self.window!.rootViewController = mainNavigationController
            self.window!.makeKeyAndVisible()
        }
        return true
    }


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;And in your SceneDelegate :&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

    // SceneDelegate

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        guard let _ = (scene as? UIWindowScene) else { return }
        if let windowScene = scene as? UIWindowScene {
            self.window = UIWindow(windowScene: windowScene)
            let mainNavigationController = UINavigationController(rootViewController: viewController)
            self.window!.rootViewController = mainNavigationController
            self.window!.makeKeyAndVisible()
        }
    }


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Finally, to make your app to use this Scene Delegate, you need to configure it as your main scene delegate. Just go in your &lt;code&gt;info.plist&lt;/code&gt; file and add these lines :&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

&amp;lt;key&amp;gt;UIApplicationSceneManifest&amp;lt;/key&amp;gt;
    &amp;lt;dict&amp;gt;
        &amp;lt;key&amp;gt;UIApplicationSupportsMultipleScenes&amp;lt;/key&amp;gt;
        &amp;lt;true/&amp;gt;
        &amp;lt;key&amp;gt;UISceneConfigurations&amp;lt;/key&amp;gt;
        &amp;lt;dict&amp;gt;
            &amp;lt;key&amp;gt;UIWindowSceneSessionRoleApplication&amp;lt;/key&amp;gt;
            &amp;lt;array&amp;gt;
                &amp;lt;dict&amp;gt;
                    &amp;lt;key&amp;gt;UISceneConfigurationName&amp;lt;/key&amp;gt;
                    &amp;lt;string&amp;gt;Default Configuration&amp;lt;/string&amp;gt;
                    &amp;lt;key&amp;gt;UISceneDelegateClassName&amp;lt;/key&amp;gt;
                    &amp;lt;string&amp;gt;$(PRODUCT_MODULE_NAME).SceneDelegate&amp;lt;/string&amp;gt;

                    &amp;lt;!-- ONLY IF YOU HAVE A MAIN STORYBOARD --&amp;gt;
                    &amp;lt;key&amp;gt;Storyboard Name&amp;lt;/key&amp;gt;
                    &amp;lt;string&amp;gt;Main&amp;lt;/string&amp;gt;
                &amp;lt;/dict&amp;gt;
            &amp;lt;/array&amp;gt;
        &amp;lt;/dict&amp;gt;
    &amp;lt;/dict&amp;gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;We make a SceneManifest in which we declare our SceneDelegate as being the default configuration for a scene.&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F2usrv7e423eibhd2a9j6.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F2usrv7e423eibhd2a9j6.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;⚠️ If you have a Main storyboard don't forget to specify it in the &lt;code&gt;Storyboard Name&lt;/code&gt; field. If you don't, just remove the lines.&lt;/p&gt;

&lt;p&gt;And there you are!&lt;br&gt;
Now, if you execute your app on iOS/iPad OS 13, it will use the SceneDelegate, for iOS 12 and under, it will use your good old AppDelegate!&lt;/p&gt;

&lt;p&gt;Hope you enjoyed this quick post.&lt;br&gt;
If you need any help, don't hesitate to ping me on &lt;a href="https://twitter.com/kevinmaarek" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;, or just leave a comment below! 😇&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>swift</category>
      <category>ios</category>
    </item>
    <item>
      <title>Replicating the AppStore's CollectionViewLayout (orthogonal) in Swift 5</title>
      <dc:creator>Maarek</dc:creator>
      <pubDate>Fri, 27 Sep 2019 09:36:04 +0000</pubDate>
      <link>https://dev.to/kevinmaarek/replicating-the-appstore-s-collectionviewlayout-orthogonal-in-swift-5-42je</link>
      <guid>https://dev.to/kevinmaarek/replicating-the-appstore-s-collectionviewlayout-orthogonal-in-swift-5-42je</guid>
      <description>&lt;h1&gt;
  
  
  Building a simple bi-directional scrolling UICollectionView
&lt;/h1&gt;

&lt;p&gt;In a precedent &lt;a href="https://dev.to/kevinmaarek/using-collectionview-compositional-layouts-in-swift-5-1nan"&gt;post&lt;/a&gt; I scratched the surface of the freshly released CollectionView Compositional Layout API to get simpler and more complex CollectionViewLayout.&lt;br&gt;
The today's challenge is to replicate this orthogonal scrolling CollectionView layout that you might have seen in your iDevice's AppStore ("Apps" or "Games" tab).&lt;/p&gt;

&lt;p&gt;Basically we have some featured content in wide cards, with horizontal scroll, the app list that scrolls vertically, just like a regular TableView, and some basic blocks of content, maybe headers or footers with text.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oFnotXwF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/efyeqz9p7y3fhxigdcny.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oFnotXwF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/efyeqz9p7y3fhxigdcny.jpeg" alt="Alt Text" width="338" height="462"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So let's start by building our cells :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the "featured cell" card, having the "card" look, rounded corner, shadow and stuff with a large title and a smaller label ;&lt;/li&gt;
&lt;li&gt;an "app cell", that contains an app icon, title and some category ;&lt;/li&gt;
&lt;li&gt;and a "text cell" : just a basic cell with a multi-line label.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I am not going to detail this part as it's not the point of this post but you can check the code, at the end of the article.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FSJZ5bsm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/26g24a3vz33lgpysh71f.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FSJZ5bsm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/26g24a3vz33lgpysh71f.jpeg" alt="Alt Text" width="618" height="644"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Right now the ViewController is empty, I'm going to add a simple function that will return a &lt;code&gt;UICollectionViewLayout&lt;/code&gt; that we will use in the CollectionView initializer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    func makeLayout() -&amp;gt; UICollectionViewLayout {
        let layout = UICollectionViewCompositionalLayout { (section: Int, environment: NSCollectionLayoutEnvironment) -&amp;gt; NSCollectionLayoutSection? in
            //
        }
        return layout
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you know, the UICollectionViewCompositionalLayout block should return a &lt;code&gt;NSCollectionLayoutSection&lt;/code&gt;. And here we have 3 section : the one with the features card, the one with the app list and the one with our text cell.&lt;/p&gt;

&lt;h2&gt;
  
  
  The horizontal scrolling sections' Layout
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        let item = NSCollectionLayoutItem(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalHeight(1.0)))
        item.contentInsets = NSDirectionalEdgeInsets = NSDirectionalEdgeInsets(top: 0.0, leading: 12.0, bottom: 0.0, trailing: 12.0)
        let group = NSCollectionLayoutGroup.vertical(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.9), heightDimension: .fractionalHeight(0.25)), subitem: item, count: 1)
        let section = NSCollectionLayoutSection(group: group)
        section.contentInsets = NSDirectionalEdgeInsets(top: 16.0, leading: 0.0, bottom: 16.0, trailing: 0.0)
        section.orthogonalScrollingBehavior = .continuousGroupLeadingBoundary
        return section
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's detail every line of this sample of code, but first, try to keep in mind what is an item, a group and a section, as seen on my previous post about compositional layout :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lWrHkJAE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/51wrsv9uyq3k7try37ne.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lWrHkJAE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/51wrsv9uyq3k7try37ne.png" alt="" width="738" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I first declare our NSCollectionLayoutItem, with it's size, saying it's going to take 100% of the parent's width and height.&lt;/li&gt;
&lt;li&gt;I give this item the insets I want.&lt;/li&gt;
&lt;li&gt;Then, I initialize a group, a NSCollectionLayoutGroup, with the size I want each cell to take horizontally. In this case : 90% of the total collectionView width, 25% of the collectionView height.
(I want 90% so users can see there is more on the left so they want to scroll 😇)&lt;/li&gt;
&lt;li&gt;I finally create my section with my group.&lt;/li&gt;
&lt;li&gt;Add some insets.&lt;/li&gt;
&lt;li&gt;This &lt;code&gt;continuousGroupLeadingBoundary&lt;/code&gt; allows the vertical scrolling, but we can put .paging or any &lt;code&gt;OrthogonalScrollingBehavior&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's all it takes for the Featured Card's section. We'll put all that in an isolated piece of function that we'll call something like &lt;code&gt;buildHorizontalSectionLayout()&lt;/code&gt; and simply return it in our block like so :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    func makeLayout() -&amp;gt; UICollectionViewLayout {
        let layout = UICollectionViewCompositionalLayout { (section: Int, environment: NSCollectionLayoutEnvironment) -&amp;gt; NSCollectionLayoutSection? in
            if section == 0 {
                return self.buildHorizontalSectionLayout()
            }
        }
        return layout
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The vertical scrolling sections' Layout
&lt;/h2&gt;

&lt;p&gt;Now for the vertical scrolling, we'll simply mimic the tableView behaviour with self sizing cells. We want full with rows with an estimated height, adjustable according it's content's constraints.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        let item = NSCollectionLayoutItem(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalHeight(1.0)))
        item.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0)
        let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),  heightDimension: .estimated(70))
        let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitem: item, count: 1)
        let section = NSCollectionLayoutSection(group: group)
        section.contentInsets = NSDirectionalEdgeInsets(top: 10, leading: 12, bottom: 0, trailing: 12)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;An Item that takes 100% of width/height of it's superview.&lt;/li&gt;
&lt;li&gt;A group that will have an estimated height, say 70, and 1 item per group.&lt;/li&gt;
&lt;li&gt;Finally the section with the group and I specified insets.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I will also encapsulate this piece of code in a buildVerticalSectionLayout func, so now we now can update our makeLayout func :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    func makeLayout() -&amp;gt; UICollectionViewLayout {
        let layout = UICollectionViewCompositionalLayout { (section: Int, environment: NSCollectionLayoutEnvironment) -&amp;gt; NSCollectionLayoutSection? in
            if section == 0 {
                return self.buildHorizontalSectionLayout()
            } else {
                return self.buildVerticalSectionLayout()
            }
        }
        return layout
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The viewController will be pretty basic, and I am not going to detail the code. Basically just add a CollectionView, init with a frame and a layout (calling the makeLayout func), place it with constraints, register your cells, and set the delegate and dataSource.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    lazy var collectionView: UICollectionView = {
        let collectionView: UICollectionView = UICollectionView(frame: CGRect.zero, collectionViewLayout: self.makeLayout())
        collectionView.backgroundColor = UIColor.white
        collectionView.delegate = self
        collectionView.dataSource = self
        collectionView.register(Cell.self, forCellWithReuseIdentifier: "cell")
        collectionView.register(Featured.self, forCellWithReuseIdentifier: "featured")
        collectionView.register(Text.self, forCellWithReuseIdentifier: "text")
        collectionView.translatesAutoresizingMaskIntoConstraints = false
        return collectionView
    }()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And there you go !&lt;br&gt;
Here is the final result :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--llF3ghwH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/qqb9crhmr5ze642rkywz.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--llF3ghwH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/qqb9crhmr5ze642rkywz.gif" alt="Alt Text" width="238" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Bonus : you can easily build an horizontal scrolling vertical list like so&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4o8K_mio--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/6zbe9vw5guxw7w9wwx87.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4o8K_mio--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/6zbe9vw5guxw7w9wwx87.gif" alt="Alt Text" width="366" height="224"&gt;&lt;/a&gt;&lt;br&gt;
by mixing the two layout examples shown above. Just use a vertical NSCollectionLayoutGroup and set an &lt;code&gt;orthogonalScrollingBehavior&lt;/code&gt; (in the gif, it's &lt;code&gt;.groupPaging&lt;/code&gt;). Don't forget to specify how many items you want in your group (how many "app cell" in a paged block) in the parameter count of you NSCollectionLayoutGroup.&lt;/p&gt;

&lt;p&gt;Bonus 2 : You can use compositional Layouts with iOS 12 using &lt;a href="https://github.com/kishikawakatsumi/IBPCollectionViewCompositionalLayout"&gt;IBPCollectionViewCompositionalLayout&lt;/a&gt; 😋&lt;/p&gt;

&lt;p&gt;Hope you enjoyed this quick walkthrough of UICollectionViewCompositionalLayout. Of course you can &lt;a href="https://github.com/Que20/CompositionalLayoutDemo"&gt;download&lt;/a&gt; the code.&lt;br&gt;
Play with it, tweak it and make something great! ☺️&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>swift5</category>
      <category>ios</category>
      <category>collectionview</category>
      <category>uikit</category>
    </item>
    <item>
      <title>My first iOS Framework 🎉</title>
      <dc:creator>Maarek</dc:creator>
      <pubDate>Wed, 17 Jul 2019 15:42:40 +0000</pubDate>
      <link>https://dev.to/kevinmaarek/my-first-ios-framework-2l20</link>
      <guid>https://dev.to/kevinmaarek/my-first-ios-framework-2l20</guid>
      <description>&lt;p&gt;Big day for me today.&lt;/p&gt;

&lt;h3&gt;
  
  
  I just released my first public iOS framework !
&lt;/h3&gt;

&lt;p&gt;Called &lt;a href="https://github.com/Que20/UIDrawer" rel="noopener noreferrer"&gt;UIDrawer&lt;/a&gt;.&lt;br&gt;
It's custom UIPresentationController that display modals like a bottom drawer, a component you may have seen in several system iOS apps (like maps) and on multiple Android apps.&lt;/p&gt;

&lt;p&gt;For a recent project, I needed this component. It wasn't the first time I encountered that kind of product request and I decided to make a distributed framework out of it.&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%2Fgithub.com%2FQue20%2FUIDrawer%2Fraw%2Fmaster%2Fdemo.gif" 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%2Fgithub.com%2FQue20%2FUIDrawer%2Fraw%2Fmaster%2Fdemo.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I am very proud of it. I feel like there is a gap between writing your lines of code for projects and exposing publicly those lines, as a framework anyone could use.&lt;/p&gt;

&lt;p&gt;What about you?&lt;br&gt;
When did your write your first Open Source framework ?&lt;/p&gt;

</description>
      <category>swift</category>
      <category>framework</category>
      <category>first</category>
    </item>
    <item>
      <title>Forms made easy with SwiftUI</title>
      <dc:creator>Maarek</dc:creator>
      <pubDate>Mon, 01 Jul 2019 13:18:04 +0000</pubDate>
      <link>https://dev.to/kevinmaarek/forms-made-easy-with-swiftui-3b75</link>
      <guid>https://dev.to/kevinmaarek/forms-made-easy-with-swiftui-3b75</guid>
      <description>&lt;p&gt;In this post, we will build a registration form with SwiftUI.&lt;/p&gt;

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

&lt;p&gt;Let's start by creating a new Xcode Project : Choose a single view app, and dont forget to check "Use SwiftUI".&lt;/p&gt;

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

&lt;p&gt;Xcode creates a ContentView for you, we'll work with this struct as our main view. First, we will add our registration fields values. Let's say name, email, and password. We need to use the property wrapper &lt;code&gt;@State&lt;/code&gt; for our values. If you don't know what @State property wrapper is, I highly recommande to read my &lt;a href="https://dev.to/kevinmaarek/property-wrappers-in-swiftui-34ok"&gt;post&lt;/a&gt; about Properties Wrappers.&lt;br&gt;
This is what we should have by now :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;struct ContentView : View {

    @State private var name: String = ""
    @State private var email: String = ""
    @State private var password: String = ""

    var body: some View {
        Text("Hello World!")
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now in our view, we want to make a NavigationView that will contain a Form.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;struct ContentView : View {

    @State private var name: String = ""
    @State private var email: String = ""
    @State private var password: String = ""

    var body: some View {
        NavigationView {
            Form {
                Text("Hello World!")
            }
            .navigationBarTitle(Text("Registration Form"))
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By now, if you build and run you should see this :&lt;/p&gt;

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

&lt;p&gt;As you can see, the form object creates a &lt;code&gt;List&lt;/code&gt; and every &lt;code&gt;View&lt;/code&gt; in it will be a cell, just like our text here, &lt;code&gt;Hello World!&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In this form, we will remove the Hello World text and add instead some sections, three sections actually. One that we will use for the name and mail text fields, another for the password and the last one for our call to action validation button.&lt;br&gt;
A Section takes 3 parameters : a header, a footer and the content (View). Here, we will set headers to our 2 first sections :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;struct ContentView : View {

    @State private var name: String = ""
    @State private var email: String = ""
    @State private var password: String = ""

    var body: some View {
        NavigationView {
            Form {
                Section(header: Text("Your Info")) {
                    TextField($name, placeholder: Text("Name"))
                    TextField($email, placeholder: Text("Email"))
                }
                Section(header: Text("Password")) {
                    TextField($password, placeholder: Text("Password"))
                }
                Section {
                    Button(action: {
                                print("register account")
                            }) {
                                Text("OK")
                            }
                }
            }
            .navigationBarTitle(Text("Registration Form"))
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which would result into that :&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi1sh34pt9y3gapvgjfo8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi1sh34pt9y3gapvgjfo8.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's it. We now have a simple form made with SwiftUI. Note that we passe the fields values with a &lt;code&gt;$&lt;/code&gt; so that we have a 2 ways binding : the textfields read and write the value we pass to them.&lt;/p&gt;

&lt;p&gt;Now, let's try to add a few more things to this...&lt;br&gt;
I would like to add an indicator for the security level of the password.&lt;/p&gt;

&lt;p&gt;First, we are going to create an enum for the password security level :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;enum PasswordLevel: Int {
    case none = 0
    case weak = 1
    case ok = 2
    case strong = 3
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And a view :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;struct SecureLevelView : View {
    var level: PasswordLevel
    var body: some View {
        HStack {
            RoundedRectangle(cornerRadius: 8).foregroundColor(self.getColors()[0]).frame(height: 10)
            RoundedRectangle(cornerRadius: 8).foregroundColor(self.getColors()[1]).frame(height: 10)
            RoundedRectangle(cornerRadius: 8).foregroundColor(self.getColors()[2]).frame(height: 10)
        }
    }

    func getColors() -&amp;gt; [Color] {
        switch self.level {
        case .none:
            return [.clear, .clear, .clear]
        case .weak:
            return [.red, .clear, .clear]
        case .ok:
            return [.red, .orange, .clear]
        case .strong:
            return [.red, .orange, .green]
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can init our view with a level and depending on the level it will display the right colors like so :&lt;/p&gt;

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

&lt;p&gt;From the top to the bottom : .none (no colors), .weak, .ok, .strong.&lt;/p&gt;

&lt;p&gt;Now instead of having a simple value for the password, we will make a class that will handle holding and checking the password.&lt;br&gt;
We need this class to be bindable so it can notify the view for the changes of the protection level.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class PasswordChecker: BindableObject {
    public let didChange = PassthroughSubject&amp;lt;PasswordChecker, Never&amp;gt;()
    var password: String = "" {
        didSet {
            self.checkForPassword(password: self.password)
        }
    }

    var level: PasswordLevel = .none {
        didSet {
            self.didChange.send(self)
        }
    }

    func checkForPassword(password: String) {
        if password.count == 0 {
            self.level = .none
        } else if password.count &amp;lt; 2 {
            self.level = .weak
        } else if password.count &amp;lt; 6 {
            self.level = .ok
        } else {
            self.level = .strong
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Don't forget to import Combine.&lt;/p&gt;

&lt;p&gt;The class has 2 attributes : the password and the level.&lt;br&gt;
It also has a didChange property to conform to BindableObject. I you don't know what a BindableObject is, &lt;a href="https://dev.to/kevinmaarek/getting-started-with-swiftui-and-combine-dd8"&gt;here&lt;/a&gt; is the post where I explain what this is and how it works.&lt;br&gt;
What we want here is to update the password level on the didSet of the password, so that when the password's value is updated, we set the level according to the setted password. When the level is setted, we want to notify the view that the password level has changed so it can update the SecureLevelView.&lt;/p&gt;

&lt;p&gt;So here, in the &lt;code&gt;checkForPassword&lt;/code&gt; method, I choose to make simple rules : the protection level depends on the number of characters in the password, but you might need to use actual rules, checking on capitalized letters, numbers or special characters with a regexp.&lt;/p&gt;

&lt;p&gt;Now we want to use that class in our view, we just need to remove the password property and replace it with a &lt;code&gt;PasswordChecker&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;struct ContentView : View {

    @State private var name: String = ""
    @State private var email: String = ""
    @ObjectBinding var passwordChecker: PasswordChecker = PasswordChecker()

    var body: some View {
        NavigationView {
            Form {
                Section(header: Text("Your Info")) {
                    TextField($name, placeholder: Text("Name"))
                    TextField($email, placeholder: Text("Email"))
                }
                Section(header: Text("Password")) {
                    TextField($passwordChecker.password, placeholder: Text("Password"))
                    if !self.passwordChecker.password.isEmpty {
                        SecureLevelView(level: self.passwordChecker.level)
                    }
                }
                Section {
                    Button(action: {
                                print("register account")
                            }) {
                                Text("OK")
                            }
                }
            }
            .navigationBarTitle(Text("Registration Form"))
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I chose to hide the SecureLevelView when the password is empty.&lt;/p&gt;

&lt;p&gt;Now this is what we have :&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fje2c67p9xcih6yq814hs.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fje2c67p9xcih6yq814hs.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The last feature I'd like to have is a toggle to make the user accepts the terms and conditions.&lt;br&gt;
I added a new @State Boolean property :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@State private var terms: Bool = false
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and in the section :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                    if self.passwordChecker.level.rawValue &amp;gt;= 2 {
                        Toggle(isOn: $terms) {
                            Text("Accept the terms and conditions")
                        }
                        if self.terms {
                            Button(action: {
                                print("register account")
                            }) {
                                Text("OK")
                            }
                        }
                    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Meaning : if the password protection level is higher than &lt;code&gt;ok&lt;/code&gt; (&lt;code&gt;ok&lt;/code&gt; or &lt;code&gt;strong&lt;/code&gt;), we show the "Accept the terms and conditions" Toggle and only if the toggle is on, then show the validation button.&lt;/p&gt;

&lt;p&gt;I agree, this is a terrible UX. But now you know how to build easy forms and dynamically show info as user types in, using combine.&lt;/p&gt;

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

&lt;p&gt;Hope you enjoyed this little post. You can download the full source &lt;a href="https://github.com/Que20/RegistrationFormSwiftUI" rel="noopener noreferrer"&gt;here&lt;/a&gt; on my github.&lt;/p&gt;

&lt;p&gt;Happy coding !&lt;/p&gt;

</description>
      <category>swift</category>
      <category>swiftui</category>
      <category>form</category>
      <category>ios</category>
    </item>
    <item>
      <title>Property Wrappers in SwiftUI</title>
      <dc:creator>Maarek</dc:creator>
      <pubDate>Fri, 28 Jun 2019 15:36:16 +0000</pubDate>
      <link>https://dev.to/kevinmaarek/property-wrappers-in-swiftui-34ok</link>
      <guid>https://dev.to/kevinmaarek/property-wrappers-in-swiftui-34ok</guid>
      <description>&lt;p&gt;With Swift 5 and SwiftUI, Apple introduced property wrappers. You might have saw one of them on some SwiftUI articles or tutorials : &lt;code&gt;@State&lt;/code&gt;, &lt;code&gt;@BindableObject&lt;/code&gt;, &lt;code&gt;@EnvironmentObject&lt;/code&gt;.&lt;br&gt;
In this post, we’ll try to explain what are these wrappers and when to use them.&lt;/p&gt;

&lt;p&gt;Everything in SwiftUI is struct based. And structs are immutable, those are fixed values. &lt;br&gt;
When a property has an &lt;code&gt;@State&lt;/code&gt; property wrapper, it just tells your struct that the memory management won’t be handled by the struct itself but by another memory manager entity : the SwiftUI Framework. &lt;br&gt;
Let’s picture a practical use case :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;struct ContentView : View {
    var buttonTapped: Bool = false
    var body: some View {
        Button(action: {
            self.buttonTapped.toggle()
        }) {
            Text("Tap the button")
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we want the buttonTapped value to toggle on the tap of the button.&lt;br&gt;
Xcode won’t let me do that saying :&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Cannot use mutating member on immutable value: 'self' is immutable&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Of course, we’re in a struct!&lt;br&gt;
That’s where you want to use the &lt;code&gt;@State&lt;/code&gt; wrapper. The memory, the creation and the storage of the property won’t be managed by the struct itself.&lt;br&gt;
What it actually does is it will be notified that the value has changed and it will re-create the struct with the new value, therefore, the view will be invalidate and be refreshed with the updated value.&lt;/p&gt;

&lt;p&gt;A &lt;code&gt;$&lt;/code&gt; sign before a value means a two way binding. Passing a $value to a View will enable to read the value and update it. Might be useful for TextFields for example, which will read and write the value you passed. Just like that :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;struct ContentView : View {
    @State var input: String = ""
    var body: some View {
        TextField($input)
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;@State&lt;/code&gt; is great for these simple cases. When your view has simple properties like String, Int or Bool value. But what about when you have more complicated objects you want to use ?&lt;br&gt;
Let’s say you have this registration form, that owns 3 fields : email, username, password.&lt;br&gt;
First thing would be to make a struct with these Strings attributes, right ?&lt;/p&gt;

&lt;p&gt;struct Registration {&lt;br&gt;
    var email: String = ""&lt;br&gt;
    var username: String = ""&lt;br&gt;
    var password: String = ""&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;And just store it in your view with a &lt;code&gt;@State&lt;/code&gt; wrapper.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;struct ContentView : View {
    @State var registration: Registration = Registration()
    var body: some View {
        Text(“Hello”)
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It would actually works great as long as you’re using this struct in only one view, but let’s imagine you would have one view, say InfoView, with the email and username fields and another, that would be PasswordView, for the password field. That is where you would be stucked. Both view would need the same  Registration model.&lt;br&gt;
The Registration object will be passed to these two views, but remember, structs have one owner, because structs works as value and not reference. The Registration is a struct. You can’t have an instance of a struct like an object instance. If multiple views (or any kind of objects) owns a struct, every view would have it's own version of it.&lt;/p&gt;

&lt;p&gt;So to make our registration form complete, we would need to transform the struct into a class. So we can work with references. Pass it to every view we would need to. But the thing is : with the &lt;code&gt;@State&lt;/code&gt; wrapper, the the view (struct) gets re-created with updated values, but you can’t do that with a class. The class won’t be “listened” like an @State property would be.&lt;br&gt;
It’s time to import Combine !&lt;br&gt;
In the &lt;a href="https://dev.to/kevinmaarek/getting-started-with-swiftui-and-combine-dd8"&gt;Getting started with SwiftUI and Combine&lt;/a&gt; post, we discovered the Bindable protocol. This is what we need to use in this situation. We’ll make our Registration class Bindable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Registration: Bindable {
    var email: String = ""
    var username: String = ""
    var password: String = ""
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As any Bindable object, you will need a didChange property and call it on any value updated.&lt;br&gt;
We don’t need to pass a Registration object or an error. We just need to notify that the object’s values has changed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Registration: Bindable {
    var didChange = PassthroughSubject&amp;lt;Void, Never&amp;gt;()
        var email: String = "" {
        didSet {
            didChange.send()
        }
    }
    // do the same for each property
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we need to tell SwiftUI to watch for these changes and, juste like with the @State, update the UI by recreating the view.&lt;br&gt;
So just replace @State in your view by @ObjectBinding :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;struct ContentView : View {
    @ObjectBinding var registration: Registration = Registration()
    var body: some View {
        Text(“Hello”)
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we solve the problem of having a complex, referenced type, object to be listened by SwiftUI to update our view. But what about passing this object to another view, just like in our practical use case with the two pages registration form ?&lt;br&gt;
Well, Apple made something really cool for passing object through views : &lt;code&gt;Environment&lt;/code&gt;. This is a way to share objects to make them available where needed.&lt;/p&gt;

&lt;p&gt;Here is how it works :&lt;br&gt;
You just add your Registration object with &lt;code&gt;@EnvironmentObject&lt;/code&gt; :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;struct ContentView : View {
    @EnvironmentObject var registration: Registration
    var body: some View {
        Text(“Hello”)
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You don’t need to initialize it, as your view will assume it's value will be available in the Environment. To add a value into the Environment it is quite simple :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ContentView.environmentObject(Registration())
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can do so in you sceneDelegate or anywhere you call your view.&lt;br&gt;
Every view that gets to use the Registration object need to have a Registration property wrapped with @EnvironmentObject.&lt;/p&gt;

&lt;p&gt;I hope this post helped you to understand the mechanics of SwiftUI and how to use the property wrappers.&lt;br&gt;
I you have any questions, don’t hesitate to leave a comment.&lt;/p&gt;

&lt;p&gt;Happy coding! :)&lt;/p&gt;

</description>
      <category>swiftui</category>
      <category>swift</category>
      <category>combine</category>
    </item>
  </channel>
</rss>
