WP Carousel slider plugin height issue [Fixed]

WP Carousel Slider is a WordPress plugin developed by Sayful Islam. This plugin allows you to create carousel images in your blog post. You can display your media images, gallery, custom URLs, blog posts, or WooCommerce products in the carousel.

It works as sliders, so you need to create a new slider, and add images to that slider. A shortcode will be generated for each slider, you just need to place that shortcode in your post where you want to show the slider. Sliders created from this plugin can also be used as widgets.

In this article, I am going to discuss a solution to a problem that occurs when you try to add images with different heights in your slider under the following configurations:

SettingValue
Carousel Image sizeOriginal uploaded image
Auto WidthDisabled
Columns1
Columns: Desktop1
Columns: Small desktop1
Columns: Tablet1
Columns: Small tablet1
Columns: Mobile1

If you are using the above settings and if you upload the images with different heights in a slider, then you might see that slider has been given a height of the largest image which will create a lot of empty space at the bottom of the smaller height images.

Moreover, when you scroll between carousel items, the height of the carousel is not auto-adjusted. Let me explain how you can solve this.

Solution:

You need to make 1 change in the plugin file. When it comes to editing the plugin files, there are 2 options.

1. WordPress admin panel

From your WordPress admin panel, go to “Plugins > Plugin Editor” and select the “Carousel Slider” plugin. When this plugin is selected, go to the following path:

assets/js/frontend.js

2. File manager

If you prefer to use file manager instead of making the changes from the WordPress admin panel, then you need to go to the following path:

wp-content/plugins/carousel-slider/assets/js/frontend.js

Replace the content of the “frontend.js” file with the following:

Before applying the solution, please prepare a backup of this file. Copy the content of this file and paste it into your computer’s Notepad.

If you have prepared the backup of this file, feel free to replace the file’s code with the following:

function setOwlStageHeight(event) {
    var maxHeight = 0;
    jQuery('.owl-item.active').each(function () { // LOOP THROUGH ACTIVE ITEMS
        var thisHeight = parseInt( jQuery(this).height() );
        maxHeight=(maxHeight>=thisHeight?maxHeight:thisHeight);
    });
    jQuery('.owl-carousel').css('height', maxHeight );
    jQuery('.owl-stage-outer').css('height', maxHeight ); // CORRECT DRAG-AREA SO BUTTONS ARE CLICKABLE
}

jQuery("body")
    .find(".carousel-slider")
    .each(function () {
        let a = jQuery(this),
            e = a.data("auto-width"),
            t = parseInt(a.data("stage-padding"));
        if (
            ((t = t > 0 ? t : 0),
            jQuery().owlCarousel &&
                (a.owlCarousel({
                    stagePadding: t,
                    nav: a.data("nav"),
                    dots: a.data("dots"),
                    margin: a.data("margin"),
                    loop: a.data("loop"),
                    autoplay: a.data("autoplay"),
                    autoplayTimeout: a.data("autoplay-timeout"),
                    autoplaySpeed: a.data("autoplay-speed"),
                    autoplayHoverPause: a.data("autoplay-hover-pause"),
                    slideBy: a.data("slide-by"),
                    lazyLoad: a.data("lazy-load"),
                    autoWidth: e,
                    navText: [
                        '<svg class="carousel-slider-nav-icon" viewBox="0 0 20 20"><path d="M14 5l-5 5 5 5-1 2-7-7 7-7z"></path></use></svg>',
                        '<svg class="carousel-slider-nav-icon" viewBox="0 0 20 20"><path d="M6 15l5-5-5-5 1-2 7 7-7 7z"></path></svg>',
                    ],
                    responsive: {
                        320: { items: a.data("colums-mobile") },
                        600: { items: a.data("colums-small-tablet") },
                        768: { items: a.data("colums-tablet") },
                        993: { items: a.data("colums-small-desktop") },
                        1200: { items: a.data("colums-desktop") },
                        1921: { items: a.data("colums") },
                    },
                    autoHeight: true,
                    onInitialized: setOwlStageHeight,
                    onResized: setOwlStageHeight,
                    onTranslated: setOwlStageHeight
                }),
                "hero-banner-slider" === a.data("slide-type")))
        ) {
            let e = a.data("animation");
            e.length &&
                (a.on("change.owl.carousel", function () {
                    a.find(".carousel-slider-hero__cell__content")
                        .removeClass("animated " + e)
                        .hide();
                }),
                a.on("changed.owl.carousel", function (t) {
                    setTimeout(function () {
                        jQuery(t.target)
                            .find(".carousel-slider-hero__cell__content")
                            .eq(t.item.index)
                            .show()
                            .addClass("animated " + e);
                    }, a.data("autoplay-speed"));
                }));
        }
        jQuery().magnificPopup &&
            ("product-carousel" === a.data("slide-type")
                ? jQuery(this).find(".magnific-popup").magnificPopup({ type: "ajax" })
                : "video-carousel" === a.data("slide-type")
                ? jQuery(this).find(".magnific-popup").magnificPopup({ type: "iframe" })
                : jQuery(this)
                      .find(".magnific-popup")
                      .magnificPopup({ type: "image", gallery: { enabled: !0 }, zoom: { enabled: !0, duration: 300, easing: "ease-in-out" } }));
    });

After replacing the above code, you need to refresh your browser cache in order to see the effect. Press the following keys to remove the browser cache:

Windows / Linuxctrl + shift + delete
Maccommand (⌘) + shift + delete

When you hit the above keys, you will see a pop-up asking which data you want to delete. You will have 3 options and you need to check the “Cached files and images” option. Also, make sure to select “All time” from the “Time range” option.

Now refresh the post where you have placed the shortcode for the WP Carousel Slider plugin, and you will know that the carousel will adjust itself dynamically with the height of the currently active image.

Custom keyboard view for typing secure passwords using HTML and CSS

When people use someone else’s computer and try to log in to their account on any website, they are afraid that the other person might have installed a Keylogging software that tracks all the keys pressed, and hence they will know his password. But if you show a custom keyboard view for a password field on your website, it will create a whole new level of confidence in users towards your website.

So let’s learn how you can do this.

This is what we are going to create:

First, you need to create a password field, you probably also have a username or email field as well.

<input type="password" name="password" id="password">

Then create a table with a full keyboard view.

Numeric keyboard:

First, we will create a full numeric keyboard that appears on top of most laptops.

<table class="keyboard">
    <tr>
        <td>
            ~<br><span data-shift="~" data-initial="`">`</span>
        </td>
        <td>
            !<br><span data-shift="!" data-initial="1">1</span>
        </td>
        <td>
            @<br><span data-shift="@" data-initial="2">2</span>
        </td>
        <td>
            #<br><span data-shift="#" data-initial="3">3</span>
        </td>
        <td>
            $<br><span data-shift="$" data-initial="4">4</span>
        </td>
        <td>
            %<br><span data-shift="%" data-initial="5">5</span>
        </td>
        <td>
            ^<br><span data-shift="^" data-initial="6">6</span>
        </td>
        <td>
            &<br><span data-shift="&" data-initial="7">7</span>
        </td>
        <td>
            *<br><span data-shift="*" data-initial="8">8</span>
        </td>
        <td>
            (<br><span data-shift="(" data-initial="9">9</span>
        </td>
        <td>
            )<br><span data-shift=")" data-initial="0">0</span>
        </td>
        <td>
            _<br><span data-shift="_" data-initial="-">-</span>
        </td>
        <td>
            +<br><span data-shift="+" data-initial="=">=</span>
        </td>
        <td><span>delete</span></td>
    </tr>
</table>

We have written the normal key in the <span> tag and the shift key directly in <td>. Also, we have given data-shift and data-initial attribute so we can know which character to use when the shift key is pressed and which character to use when the shift key is released.

1st row (QWERTY):

This will be the very first row on your keyboard. You can compare it with your keyboard. Create a new <tr> tag in your table:

<tr>
    <td></td>
    <td data-shift="Q"><span>q</span></td>
    <td data-shift="W"><span>w</span></td>
    <td data-shift="E"><span>e</span></td>
    <td data-shift="R"><span>r</span></td>
    <td data-shift="T"><span>t</span></td>
    <td data-shift="Y"><span>y</span></td>
    <td data-shift="U"><span>u</span></td>
    <td data-shift="I"><span>i</span></td>
    <td data-shift="O"><span>o</span></td>
    <td data-shift="P"><span>p</span></td>
    <td>
        {<br><span data-shift="{" data-initial="[">[</span>
    </td>
    
    <td>
        }<br><span data-shift="}" data-initial="]">]</span>
    </td>

    <td>
        |<br><span data-shift="|" data-initial="\">\</span>
    </td>
</tr>

It also has data-shift and data-initial attributes that tell that the character will be uppercase when the shift key is pressed, and lowercase when the shift key is released.

2nd row (ASDF):

Similarly, we are going to create a second row of the keyboard.

<tr>
    <td></td>
    <td data-shift="A"><span>a</span></td>
    <td data-shift="S"><span>s</span></td>
    <td data-shift="D"><span>d</span></td>
    <td data-shift="F"><span>f</span></td>
    <td data-shift="G"><span>g</span></td>
    <td data-shift="H"><span>h</span></td>
    <td data-shift="J"><span>j</span></td>
    <td data-shift="K"><span>k</span></td>
    <td data-shift="L"><span>l</span></td>
    <td>
        :<br><span data-shift=":" data-initial=";">;</span>
    </td>

    <td>
        "<br><span data-shift='"' data-initial="'">'</span>
    </td>
</tr>

3rd row:

This will be the last row of the keyboard, usually right above the space bar.

<tr>
    <td id="key-shift"><span>shift</span></td>
    <td data-shift="Z"><span>z</span></td>
    <td data-shift="X"><span>x</span></td>
    <td data-shift="C"><span>c</span></td>
    <td data-shift="V"><span>v</span></td>
    <td data-shift="B"><span>b</span></td>
    <td data-shift="N"><span>n</span></td>
    <td data-shift="M"><span>m</span></td>
    
    <td>
        <<br><span data-shift="<" data-initial=",">,</span>
    </td>

    <td>
        ><br><span data-shift=">" data-initial=".">.</span>
    </td>
    
    <td>
        ?<br><span data-shift="?" data-initial="/">/</span>
    </td>
</tr>

Note that it has an ID attribute to the shift key, that is so we can highlight the shift key when it is pressed.

Applying styles

To make the keyboard view looks nice, we are going to apply some styles. But you can style the keyboard as you want.

.keyboard {
    margin-top: 10px;
    table-layout: fixed;
    width: 200px;
}
.keyboard,
.keyboard td {
    border: 1px solid black;
    border-collapse: collapse;
}
.keyboard td {
    padding: 25px;
    cursor: pointer;

    width: 30px;
    overflow: hidden;
}
.keyboard td:hover,
.keyboard td.active {
    background: black;
    color: white;
}

This will make your keyboard look nice and readable.

Javascript

The real power of this keyboard view comes with Javascript. Following is the complete Javascript code that will make this static keyboard view functional.

var isShift = false;

window.addEventListener("load", function () {
    var tds = document.querySelectorAll(".keyboard td");
    for (var a = 0; a < tds.length; a++) {
        tds[a].addEventListener("click", function () {

            /* get key node */
            var node = this.querySelector("span");
            if (node == null) {
                return;
            }

            if (node.innerHTML == "delete") {
                simulateBackspace(document.getElementById("password"));
            } else if (node.innerHTML == "shift") {
                /* toggle the isShift variable */
                isShift = !isShift;
                toggleShift();
            } else {
                /* check if it is an alphabet */
                if ((/[a-zA-Z]/).test(node.innerHTML)) {
                    document.getElementById("password").value += node.innerHTML;
                } else {

                    /* show initial value if the shift is off.
                     * show shift value if shift is on. */
                    if (isShift) {
                        document.getElementById("password").value += node.getAttribute("data-shift");
                    } else {
                        document.getElementById("password").value += node.getAttribute("data-initial");
                    }
                }
                
                if (isShift) {
                    isShift = false;
                    toggleShift();
                }
            }
        });
    }
});

function toggleShift() {
    /* make all alphabets capital or small based on new isShift value */
    var keys = document.querySelectorAll(".keyboard span");
    for (var b = 0; b < keys.length; b++) {
        /* keys must not be shift or delete */
        if (keys[b].innerHTML != "shift" && keys[b].innerHTML != "delete" && keys[b].innerHTML != "") {

            /* check if it is an alphabet */
            if ((/[a-zA-Z]/).test(keys[b].innerHTML)) {
                if (isShift) {
                    keys[b].innerHTML = keys[b].innerHTML.toUpperCase();
                } else {
                    keys[b].innerHTML = keys[b].innerHTML.toLowerCase();
                }
            }
        }
    }

    /* highlight the shift button if on. */
    if (isShift) {
        document.getElementById("key-shift").className = "active";
    } else {
        document.getElementById("key-shift").className = "";
    }
}

function simulateBackspace(element) {
    var start = element.selectionStart, end = element.selectionEnd, event;

    if (!element.setRangeText) { return; }
    if (start >= end) {
      if (start <= 0 || !element.setSelectionRange) { return; }
      element.setSelectionRange(start - 1, start);
    }

    element.setRangeText("");
    event = document.createEvent("HTMLEvents");
    event.initEvent("input", true, false);
    element.dispatchEvent(event);
}

That’s how you can create a fully functional custom numeric keyboard view. Comments have been added with each line for an explanation. You can customize this as much as you want. If you face any problems feel free to ask in the comment section below.

[wpdm_package id=’1173′]

PayPal and Stripe – Javascript

Whether you are creating an E-commerce website or simply wanted to receive payments from your website using PayPal and Stripe, this script already contains all the source code you need to show Stripe and PayPal payment buttons and receive payments directly in your Stripe and PayPal accounts.

It also has a full shopping cart implementation, where you can add products to the cart, update quantities, remove products from the cart and move to checkout.

Demo

Home page

Here you can add products to the shopping cart and also you can remove products from the shopping cart.

When you add or remove a product from the shopping cart, you will see the shopping cart badge on top updating its values in real-time.

Shopping cart

On clicking the above “Cart” button you will be redirected to the shopping cart page where you can change the number of products and can also remove the product from the shopping cart.

You can also see the grand total at the bottom right that changes in real-time as you change the quantity of product or when you remove a product from the shopping cart.

Checkout

Here you can make the payment using Stripe or Paypal.

Fully documented code

Comments have been added with each line of code for explanation.

Separate file for each function

To manage the code, each payment method is separated in its own file. So you can easily change and modify the code as per your needs.

Convert POST request into AJAX, Javascript – Laravel

Suppose you have a form in your Laravel project that when submit sends the data to the server for processing. But when the form is submitted, your browser has to refresh the whole page which means that it needs to load all the CSS, JS, and image files again and also render all the HTML in the browser again. So you need to convert this POST request into an AJAX request to prevent the page from reloading.

I am using a form with a text field and an input type file so you can know how to send an image in an AJAX request.

<form method="POST" action="{{ url('/form-submit') }}" enctype="multipart/form-data" onsubmit="return onsubmitForm(this);">
    {{ csrf_field() }}

    <input type="text" name="name">
    <input type="file" name="file" accept="image/*">

    <input type="submit">
</form>

CSRF field is required in Laravel for POST requests. onsubmit event is attached to the form and it will call a Javascript function to send an AJAX request. Now we need to create that function in Javascript that will send an AJAX request to the server along with all the data in the form:

<script>
    // create function in Javascript
    function onsubmitForm(form) {

        // create AJAX instance
        var ajax = new XMLHttpRequest();

        // open the request
        ajax.open("POST", form.getAttribute("action"), true);

        // listen for response from server
        ajax.onreadystatechange = function () {
            // when the request is successfull
            if (this.readyState == 4 && this.status == 200) {
                // convert the JSON response into Javascript object
                var data = JSON.parse(this.responseText);

                // show the response
                alert(data.status + " - " + data.message);
            }

            // if the request fails
            if (this.status == 500) {
                alert(this.responseText);
            }
        };

        // create form data object
        var formData = new FormData(form);

        // send the request
        ajax.send(formData);

        // prevent the form from submitting
        return false;
    }
</script>

Comments have been added with each line for an explanation. Now we need to create a route in our web.php file inside the routes folder in Laravel 9.

use Illuminate\Http\Request;

Route::get('/', function () {
    return view('welcome');
});

// this is the route I will make it to return JSON data
Route::post("/form-submit", function (Request $request) {

    $request->validate([
        "name" => "required",
        "file" => "required|image"
    ]);

    DB::table("users")->insert([
        "name" => $request->name
    ]);

    $request->file("file")->storeAs("/public", $request->file("file")->getClientOriginalName());

    // return redirect()->back();

    // return the response in JSON
    return response()->json([
        "status" => "success",
        "message" => "Task has been done"
    ]);
});

First, we are validating that the request must have name and file fields and the file must be an image. Then we are inserting the data from the text field in the users table. You can find the sample database in the attachments below.

Then we are storing the image in a public/storage folder. You need to run the following command in order to make this work:

php artisan storage:link

Lastly, we are sending the response back in JSON format. That’s how you can convert a POST request into an AJAX request in Laravel.

[wpdm_package id=’951′]

Prevent form resubmission alert POST method – PHP

When you submit a form with a POST request and if you refresh that page, you will see an alert that says “Confirm form resubmission”. This is not good for the user experience. You cannot use the GET method because it will make the URL look bad. But we still need to prevent this form resubmission alert dialog.

So using this technique, you can achieve both. Submit the form without making the URL bad, and prevent the “form resubmission” alert.

Suppose you have a form with an input field that sends a POST request like the following:

<form method="POST" action="form-submit.php" onsubmit="return onFormSubmit(this);">
    <input type="text" name="name">
    <input type="submit">
</form>

Attach an event named “onsubmit” to the form tag that calls a Javascript function named “onFormSubmit”. The return statement is used to prevent the form from submitting. Now, create that function in Javascript:

<script>
    function onFormSubmit(form) {

        // create data object with all form values
        var data = {
            "name": form.name.value
        };

        // convert in JSON
        var jsonData = JSON.stringify(data);

        // save in cookies
        document.cookie = "my_form=" + jsonData;

        // redirect to form's action
        window.location.href = form.getAttribute("action");

        // prevent form from submitting
        return false;
    }
</script>

Comments have been added with each line for an explanation. You can write all your form fields in the data object. If you have an input type=”file” field in your form, you can add it to the data object by calling the files property like the following:

var data = {
    "image": form.image.files[0]
};

For multiple files, you can simply remove the [0] from the above line and it will add all files in the data object.

Now on server-side, do the following to get the values:

<?php

    // get in server side
    $my_form = $_COOKIE["my_form"];

    // decode from JSON
    $my_form = json_decode($my_form);

    // get single value
    $name = $my_form->name;

    print_r($name);
?>

As we were storing the values in cookies using Javascript, so we can get them from cookies using PHP.

As we were storing the values in JSON string using Javascript. So, we can get them by decoding from JSON string using PHP.

That’s how you can prevent the “form resubmission” alert and also keep your URL clean from GET request.

[wpdm_package id=’949′]

Posted in PHP

Custom sort associative array – PHP

Suppose you have an associative array in PHP with key-value pair. If you loop through it, all the values will be displayed in the order they are added to the array. To learn how to customize the sorting of an associative array, keep reading this. We will teach you how you can custom sort an associative array in PHP. You can easily sort the numeric key though.

We will use a database called “classicmodels”, which can be found in the source files attached below. First, we will connect with the database and get all the columns of the desired table.

<?php

    $conn = mysqli_connect("localhost:8889", "root", "root", "classicmodels");
    $result = mysqli_query($conn, "SELECT * FROM customers");

    $columns = [];
    while ($row = mysqli_fetch_object($result))
    {
        foreach ($row as $col_name => $col_value)
        {
            array_push($columns, $col_name);
        }
        break;
    }
    mysqli_data_seek($result, 0);

If you do print_r($columns); after this, then you will see all the column names of that table. Now create an array that holds the desired sorting of columns.

$columns_order = [
    "customerNumber" => "ID",
    "customerName" => "Name",
    "salesRepEmployeeNumber" => "Sales rep Employee ID",
    "contactFirstName" => "Contact peron name",
    "phone" => "Mobile",
    "addressLine1" => "Address line 1",
    "addressLine2" => "Address line 2",
    "city" => "City",
    "state" => "State",
    "postalCode" => "Zip code",
    "country" => "Country",
    "creditLimit" => "Credit limit"
];

The key of each element is the name of the column in the database. And the value is the text that will be shown against that column. Now comes the most important part, to display the first table row which is usually the heading, do a foreach loop on this array and display the value in TH:

<table>
    <tr>
        <?php foreach ($columns_order as $key => $value): ?>
            <th>
                <?php echo $value; ?>
            </th>
        <?php endforeach; ?>
    </tr>
</table>

To display the data as in new order, loop through each record in the database. Then run a nested foreach loop like above, and show the values based on the key of an associative array:

<?php while ($row = mysqli_fetch_object($result)): ?>
    <tr>
        <?php foreach ($columns_order as $key => $value): ?>
            <td>
                <?php echo $row->{$key}; ?>
            </td>
        <?php endforeach; ?>
    </tr>
<?php endwhile; ?>

Try changing the order of columns from $columns_order array. You can also try deleting columns from this array, so if you want to remove some columns from the table tag, you can simply remove that from $columns_order array.

That’s how you can custom sort an associative array in PHP. Learn how to custom sort data from MySQL database following this tutorial.

[wpdm_package id=’942′]

How to view error from AJAX, Javascript – Laravel

When you are calling an AJAX in Laravel, you will see a “500 – Internal Server Error” if there is an error in your PHP code. To see the actual error, kindly follow this article. We will teach you in this tutorial, how you can view error from your AJAX request.

Suppose I am calling an AJAX request in Laravel using core Javascript (no jQuery), then your code will be like this:

Javascript AJAX

var ajax = new XMLHttpRequest();
ajax.open("POST", document.getElementById("base-url").value + "/ajax-test", true);

ajax.onreadystatechange = function () {
    if (this.readyState == 4 && this.status == 200) {
        console.log(this.responseText);
    }

    if (this.status == 500) {
        console.log(this.responseText);
    }
};

var formData = new FormData();
formData.append("_token", document.querySelector("meta[name=_token]").content);
ajax.send(formData);

Line #1: I have created an AJAX object.

Line #2: I have opened the AJAX request with the POST method and the URL where the request will be sent. The third parameter (true, false) is the asynchronous boolean.

Note: All modern browsers recommend this value to be true.

Line #4: An event listener that will be called each time the status of request is changed.

#5: Check if the request is successful and the response has been received from server.

#6: Display the response from the server in browser console.

#9: Check if there is an internal server error. If yes, then display that error in line #10.

#14: New form data object is created that will send the data with an AJAX request.

#15: A CSRF (cross-side request forgery) token is appended in the form data object. We will create that meta tag later in this article.

Note: Every POST request in Laravel requires a CSRF token to be sent along with request.

Line #16: Sending the AJAX request along with form data object values.

You can create the hidden base URL and CSRF token tags as follows:

<input type="hidden" id="base-url" value="{{ url('/') }}">
<meta name="_token" content="{{ csrf_token() }}">

Now, whatever the error you are having on your server-side, in route, or in the controller, you will see that in your browser console window.

jQuery AJAX

If you are using jQuery to send an AJAX request and not seeing the actual error from your server-side, then change your jQuery AJAX function to the following:

$.ajax({
    url: document.getElementById("base-url").value + "/ajax-test",
    method: "POST",
    data: formData,
    processData: false,
    contentType: false,
    success: function (response) {
        console.log(response);
    },
    error: function (xhr) {
        console.log(xhr.responseText);
    }
});

Now, if you have an error in your AJAX request, you can view it in the “error” callback. Learn how to convert a simple POST request into an AJAX request following this tutorial.

[wpdm_package id=’938′]

Search bar Swift UI with history – SQLite

SQLite is used to store the data locally inside the app in SQL structure. It is a relational local database. You can use this database to store data inside the app using Swift and Swift UI. We will be creating a simple search bar in an iOS app in Swift UI to search animals from an array and save the user’s searched strings in the SQLite database.

We will be using a library called SQLite by Stephen Celis. To install this library, you must have Cocoapods installed in your system.

Installation

You can install Cocoapods in your system by simply running the following command in your terminal:

sudo gem install cocoapods

First, you need to open a command prompt (Terminal) at the root of your XCode project and run the following command in it:

pod init

Now you will see a new file created at the root of your project named Podfile. Open that file in your text editor and add the line to install the library. Following will be the content of your Podfile:

# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'
 
target 'SQLite_Database' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!
 
  # Pods for SQLite_Database
  pod 'SQLite.swift', '~> 0.12.0'
 
end

After that, run the following command in your Terminal to install this library:

pod update

Once installed, close your XCode and re-open but this time double-click on the file which has an extension “.xcworkspace“. This file will be created only after the pod has been installed/updated.

Create a search bar

First, we will create a search bar using TextField. Then, when the user hits submit, we will send the searched value in the next view.

In the second view, we will get the value from the text field of the first view and search that value in an array. Then, display all the records that matched the searched string and display them in the list view.

Create a state variable in your content view:

// variable to goto search view
@State var gotoSearchPage: Bool = false

// value that is searched from the text field
@State var searchedText: String = ""

Following will be the content of your content view’s body:

// live tracking of input field value
let binding = Binding<String>(get: {
    self.searchedText
}, set: { (value) in
    self.searchedText = value
})

// navigation view to goto search view
return NavigationView {

    VStack (alignment: .leading, spacing: 10) {
    
        // navigation link to goto search view
        NavigationLink (destination: SearchView(searchedText: self.$searchedText), isActive: self.$gotoSearchPage) {
            EmptyView()
        }
    
        // search field
        TextField("Search ...", text: binding, onCommit: {
        
            // goto search view when search icon is clicked
            self.gotoSearchPage = true
        
        })
            .padding(7)
            .padding(.horizontal, 5)
            .background(Color(.systemGray6))
            .cornerRadius(8)
            .disableAutocorrection(true)
            .keyboardType(.webSearch)
        
    }
    .padding(20)
    .navigationBarTitle("Search - SQLite")
}

This will create a text field where you can enter your query, on hitting the “search icon” it should take you to the search view which we will create in the next step.

Create a search view

Now, we need to create a search view where we will perform the searching and display the filtered records in a list view.

Create a modal class for Animal:

//
//  Animal.swift
//  Search bar with history
//
//  Created by Adnan Afzal on 02/12/2020.
//  Copyright © 2020 Adnan Afzal. All rights reserved.
//

import Foundation

class Animal: Identifiable {
    var id: Int64 = 0
    var name: String = ""
    
    init() {
        //
    }
    
    init(name: String) {
        self.name = name
    }
}

Create a new file named SearchView.swift and paste the following code in it:

//
//  SearchView.swift
//  Search bar with history
//
//  Created by Adnan Afzal on 02/12/2020.
//  Copyright © 2020 Adnan Afzal. All rights reserved.
//

import SwiftUI

struct SearchView: View {
    
    // get searched value from the previous view
    @Binding var searchedText: String
    
    // a list of all items (change this variable as per your need)
    @State var animals: [Animal] = []
    
    // list of items that matched the searched text
    @State var searchedArray: [Animal] = []
    
    var body: some View {
        
        VStack {
            
            // show searched text
            Text("\(searchedText)").bold()
            
            // show items that matched the searched text in list view
            List (self.searchedArray) { (item) in
                Button(action: {
                    //
                }, label: {
                    Text(item.name)
                })
            }
        }.onAppear(perform: {
        
            // make the items empty when the page loads
            self.animals.removeAll()
            
            // add the data that needs to be searched (you can put your own array items here)
            self.animals.append(Animal(name: "Lion"))
            self.animals.append(Animal(name: "Tiger"))
            self.animals.append(Animal(name: "Rhino"))
            self.animals.append(Animal(name: "Elephant"))
            self.animals.append(Animal(name: "Cheetah"))
            self.animals.append(Animal(name: "Polar bear"))
            self.animals.append(Animal(name: "Leopard"))
            self.animals.append(Animal(name: "Wolf"))
            
            // empty the searched array
            self.searchedArray.removeAll()
            
            // find all the elements that matched the searched string
            for animal in self.animals {
                if (animal.name.lowercased().contains(self.searchedText.lowercased())) {
                    self.searchedArray.append(animal)
                }
            }
        })
        
    }
}

struct SearchView_Previews: PreviewProvider {

    // when using @Binding, use this in preview provider
    @State static var searchedText: String = ""

    static var previews: some View {
        SearchView(searchedText: $searchedText)
    }
}

Comments have been added on each line to explain each line individually. Now, at this point, you will be able to perform the search and see the animals which contain the name field that matches with the text field value you entered in the first view.

Show search history

Now, we need to show the search history in the content view. For that, first, we have to save each searched string in the SQLite database.

Create a separate class named “DB_Manager” that will hold all the functions for the SQLite database.

//
//  DB_Manager.swift
//  Search bar with history
//
//  Created by Adnan Afzal on 02/12/2020.
//  Copyright © 2020 Adnan Afzal. All rights reserved.
//

import Foundation

// import library
import SQLite

class DB_Manager {

    // sqlite instance
    private var db: Connection!
     
    // table instance
    private var animals: Table!
 
    // columns instances of table
    private var id: Expression<Int64>!
    private var name: Expression<String>!
    
    // constructor of this class
    init () {
         
        // exception handling
        do {
             
            // path of document directory
            let path: String = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first ?? ""
 
            // creating database connection
            db = try Connection("\(path)/my_animals.sqlite3")
             
            // creating table object
            animals = Table("animals")
             
            // create instances of each column
            id = Expression<Int64>("id")
            name = Expression<String>("name")
             
            // check if the animal's table is already created
            if (!UserDefaults.standard.bool(forKey: "is_db_created")) {
 
                // if not, then create the table
                try db.run(animals.create { (t) in
                    t.column(id, primaryKey: true)
                    t.column(name)
                })
                 
                // set the value to true, so it will not attempt to create the table again
                UserDefaults.standard.set(true, forKey: "is_db_created")
            }
             
        } catch {
            // show error message if any
            print(error.localizedDescription)
        }
         
    }

    // check if record already exists in SQLite
    public func isExists(searchedText: String) -> Bool {
     
        var isExists: Bool = false
         
        // exception handling
        do {
     
            // get animal using ID
            let animal: AnySequence<Row> = try db.prepare(animals.filter(name.lowercaseString == searchedText.lowercased()))
     
            // get row
            animal.forEach({ (rowValue) in
                isExists = true
            })
            
        } catch {
            print(error.localizedDescription)
        }
     
        return isExists
    }
    
    // add a new row in SQLite
    public func addAnimal(nameValue: String) {
        do {
            try db.run(animals.insert(name <- nameValue))
        } catch {
            print(error.localizedDescription)
        }
    }
    
}

Comments have been added with each line for an explanation. Now, in your search view inside the onAppear() function, check if the searched string already exists in the SQLite database. If NOT, then add the searched text in the SQLite database.

// add the searched text in SQLite database if NOT exists
let isExists: Bool = DB_Manager().isExists(searchedText: self.searchedText)
if (!isExists) {
    DB_Manager().addAnimal(nameValue: self.searchedText)
}

Now, we need to show the search history in the main content view when the user clicks on the search bar text field. So, create 2 state wrapper properties in your content view:

// variable to show search history view
@State var showSearchHistoryView: Bool = false

// array of history array
@State var history: [Animal] = []

And inside the body, we need to track the live text change of the input field. We have already created a binding variable inside the body of the content view. Change the binding variable inside the content view body to the following:

// live tracking of input field value
let binding = Binding<String>(get: {
    self.searchedText
}, set: { (value) in
    self.searchedText = value
    
    // show history if the text field is not empty
    self.showSearchHistoryView = !self.searchedText.isEmpty
})

Now, when the showSearchHistoryView variable is true, we need to display a list of all previously searched strings. So, create a list view under an if condition below the search bar text field:

// show history view only when a variable is true
if (self.showSearchHistoryView) {
    
    // create list view to show all history items
    List (self.history) { (model) in
    
        // show history text
        HStack {
        
            Image(systemName: "arrow.counterclockwise")
        
            Button(action: {
                self.searchedText = model.name
                self.gotoSearchPage = true
            }, label: {
                Text(model.name)
            })

        }
    }
}

This will display a counter clock icon that represents that it is data from history, a button that shows the previously searched string, and which when clicked will move to the search view.

Now, we need to load the data in our history array. So, attach an onAppear() event to your VStack and fetch the data from the SQLite database and save it in the history array.

// load data in history models array
.onAppear(perform: {
    self.history = DB_Manager().getAnimals()
})

Now, we need to create a function named getAnimals() in our DB_Manager class that will fetch the records from the SQLite database.

// return array of animal models
public func getAnimals() -> [Animal] {
     
    // create empty array
    var animalModels: [Animal] = []
 
    // get all animals in descending order
    animals = animals.order(id.desc)
 
    // exception handling
    do {
 
        // loop through all animals
        for animal in try db.prepare(animals) {
 
            // create new model in each loop iteration
            let animalModel: Animal = Animal()
 
            // set values in model from database
            animalModel.id = animal[id]
            animalModel.name = animal[name]
 
            // append in new array
            animalModels.append(animalModel)
        }
    } catch {
        print(error.localizedDescription)
    }
 
    // return array
    return animalModels
}

Comments have been added with each line for an explanation. If you run the code now, you will be able to view all the searched strings in a list view, upon click it will take you to the search view screen.

At this point, the search bar in Swift UI is completed. But you can go further and add the delete functionality. So user can remove his searched queries.

Delete history

Now, we need a function to delete the string from search history. First, create a button inside your history list after the counter-clock icon and button in your content view:

... counter-clock icon and button

// show delete button
Spacer()
Button(action: {
    
    // delete history item from SQLite
    DB_Manager().deleteAnimal(idValue: model.id)
    
    // refresh the list view
    self.history = DB_Manager().getAnimals()
    
}, label: {
    Text("Delete")
        .foregroundColor(Color.red)
})// by default, buttons are full width.
// to prevent this, use the following
.buttonStyle(PlainButtonStyle())

Now, we need to create a function named deleteAnimal() in our DB_Manager class that will delete the row from the SQLite database.

// function to delete animal from search history
public func deleteAnimal(idValue: Int64) {
    do {
    
        // get animal using ID
        let animal: Table = animals.filter(id == idValue)
         
        // run the delete query
        try db.run(animal.delete())
        
    } catch {
        print(error.localizedDescription)
    }
}

Run the code now, and you will be able to see a delete button at the end of each history row. Upon clicking, it will remove the row from the SQLite database and from the list view as well.

So you have successfully created a search bar in Swift UI along with search history.

You can also learn to create a UICollectionView with a search bar from the following tutorial.

UICollectionview with Search Bar – Swift iOS

[wpdm_package id=’929′]

How to generate SSH keys from cPanel and use it in Terminal

Following are the steps to generate SSH keys from cPanel and use them in your Command Prompt or Terminal:

  1. Open your cPanel home page.
  2. Goto “SSH access” under the “Security” section.
  3. Click on “Manager SSH keys”.
  4. Click on “Generate a new key”.
  5. Enter the key name e.g. “my_test_key”.
  6. Set password and hit “Generate key”.
  7. Now, download the public and private keys into your system.
  8. Then click on the “Manage” button against your newly created public key.
  9. Click on the “Authorize” button.
  10. Now, open your Terminal in the folder where you downloaded the public and private keys.
  11. And run the command:
    • ssh -i {your_key_name} {your_cpanel_username}@{your_shared_ip_address}
    • and hit enter.
  12. If you get an error: Permission for keys are too open then run the command:
    • chmod -R 600 {your_key_name}
    • where my_test_key is the name of your key you set during creation.
  13. If you did not get that error, then you will be asked to enter a password. Simply enter the password you set during the creation of the key and it will enter you in the SSH in your Terminal.

SSH is mostly required when you are deploying your project from localhost to the server. Frameworks like Laravel require most of the command-line work. In situations like these, you can generate SSH keys and easily connect with your live server using your command prompt (CMD) or terminal.

Sometimes you were unable to delete a file or folder from the cPanel file manager, so you can delete it from SSH by running the following command:

rm -rf name_of_file_or_folder

Swift UI SQLite – Create, Read, Update and Delete in Swift

SQLite is used to store the data locally inside the app in SQL structure. It is a relational local database. You can use the SQLite database to store data inside the app using Swift and Swift UI.

We will be creating a simple iOS app in Swift UI to create, read, update, and delete users from the SQLite database.

We will be using a library called SQLite by Stephen Celis. To install this library, you must have Cocoapods installed in your system.

Installation

You can install Cocoapods in your system by simply running the following command in your terminal:

sudo gem install cocoapods

First, you need to open a command prompt (Terminal) at the root of your XCode project and run the following command in it:

pod init

Now you will see a new file created at the root of your project named Podfile. Open that file in your text editor and add the line to install the library. Following will be the content of your Podfile:

# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

target 'SQLite_Database' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!

  # Pods for SQLite_Database
  pod 'SQLite.swift', '~> 0.12.0'

end

After that, run the following command in your Terminal to install this library:

pod update

Once installed, close your XCode and re-open but this time double-click on the file which has an extension “.xcworkspace“. This file will be created only after the pod has been installed/updated.

1. Add user

First, we will create a model class that will hold the data structure for each user. Create a file named “UserModel.swift” and paste the following code in it:

//
//  UserModel.swift
//  SQLite_Database
//
//  Created by Adnan Afzal on 24/11/2020.
//  Copyright © 2020 Adnan Afzal. All rights reserved.
//

import Foundation

class UserModel: Identifiable {
    public var id: Int64 = 0
    public var name: String = ""
    public var email: String = ""
    public var age: Int64 = 0
}

Your model class must conform to Identifiable protocol in order to show the users in List view.

DB_Manager.swift

To handle the database functions, we will create a separate file named “DB_Manager.swift“. In this class, we will create the database, tables and it’s columns in the constructor.

//
//  DB_Manager.swift
//  SQLite_Database
//
//  Created by Adnan Afzal on 24/11/2020.
//  Copyright © 2020 Adnan Afzal. All rights reserved.
//

import Foundation

// import library
import SQLite

class DB_Manager {
    
    // sqlite instance
    private var db: Connection!
    
    // table instance
    private var users: Table!

    // columns instances of table
    private var id: Expression<Int64>!
    private var name: Expression<String>!
    private var email: Expression<String>!
    private var age: Expression<Int64>!
    
    // constructor of this class
    init () {
        
        // exception handling
        do {
            
            // path of document directory
            let path: String = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first ?? ""

            // creating database connection
            db = try Connection("\(path)/my_users.sqlite3")
            
            // creating table object
            users = Table("users")
            
            // create instances of each column
            id = Expression<Int64>("id")
            name = Expression<String>("name")
            email = Expression<String>("email")
            age = Expression<Int64>("age")
            
            // check if the user's table is already created
            if (!UserDefaults.standard.bool(forKey: "is_db_created")) {

                // if not, then create the table
                try db.run(users.create { (t) in
                    t.column(id, primaryKey: true)
                    t.column(name)
                    t.column(email, unique: true)
                    t.column(age)
                })
                
                // set the value to true, so it will not attempt to create the table again
                UserDefaults.standard.set(true, forKey: "is_db_created")
            }
            
        } catch {
            // show error message if any
            print(error.localizedDescription)
        }
        
    }
}

Comments have been added with each line for clarification. Now, in your content view, we will create a navigation link that will move to the AddUserView file.

AddUserView.swift

Open your content view file and place this code inside the body:

// create navigation view
NavigationView {

    VStack {

        // create link to add user
        HStack {
            Spacer()
            NavigationLink (destination: AddUserView(), label: {
                Text("Add user")
            })
        }

        // list view goes here

    }.padding()
    .navigationBarTitle("SQLite")
}

Now, create a new view file named “AddUserView.swift” and paste the following code in it:

//
//  AddUserView.swift
//  SQLite_Database
//
//  Created by Adnan Afzal on 24/11/2020.
//  Copyright © 2020 Adnan Afzal. All rights reserved.
//

import SwiftUI

struct AddUserView: View {
    
    // create variables to store user input values
    @State var name: String = ""
    @State var email: String = ""
    @State var age: String = ""
    
    // to go back on the home screen when the user is added
    @Environment(\.presentationMode) var mode: Binding<PresentationMode>
    
    var body: some View {
        
        VStack {
            // create name field
            TextField("Enter name", text: $name)
                .padding(10)
                .background(Color(.systemGray6))
                .cornerRadius(5)
                .disableAutocorrection(true)
            
            // create email field
            TextField("Enter email", text: $email)
                .padding(10)
                .background(Color(.systemGray6))
                .cornerRadius(5)
                .keyboardType(.emailAddress)
                .autocapitalization(.none)
                .disableAutocorrection(true)
            
            // create age field, number pad
            TextField("Enter age", text: $age)
                .padding(10)
                .background(Color(.systemGray6))
                .cornerRadius(5)
                .keyboardType(.numberPad)
                .disableAutocorrection(true)
            
            // button to add a user
            Button(action: {
                // call function to add row in sqlite database
                DB_Manager().addUser(nameValue: self.name, emailValue: self.email, ageValue: Int64(self.age) ?? 0)
                
                // go back to home page
                self.mode.wrappedValue.dismiss()
            }, label: {
                Text("Add User")
            })
                .frame(maxWidth: .infinity, alignment: .trailing)
                .padding(.top, 10)
                .padding(.bottom, 10)
        }.padding()
        
    }
}

This is a bit lengthy but comments have been added with each line for an explanation.

At this point, you will see an error in the highlighted line. Because we have to create that function in our DB manager class. So, create the following function in your DB_Manager.swift file:

public func addUser(nameValue: String, emailValue: String, ageValue: Int64) {
    do {
        try db.run(users.insert(name <- nameValue, email <- emailValue, age <- ageValue))
    } catch {
        print(error.localizedDescription)
    }
}

If you run the app now, you will a link to add a user view, on that view you will see 3 fields. After filling the fields and hitting the submit button, the data will be saved in the SQLite database and you will be moved to the home view.

However, you will not see the data that has been saved in the database. So now we will show the data in List view.

2. View all users

In your content view, where you want to show all the data from the database, create a state property wrapper:

// array of user models
@State var userModels: [UserModel] = []

Now, create a list view in the content view body after the navigation link for adding a user view:

// create list view to show all users
List (self.userModels) { (model) in

    // show name, email and age horizontally
    HStack {
        Text(model.name)
        Spacer()
        Text(model.email)
        Spacer()
        Text("\(model.age)")
        Spacer()

        // edit and delete button goes here
    }
}

When the content view is loaded, we need to add the data from the database in that userModels array. Attach an onAppear function at the end of your VStack like below:

VStack {
    ...
}
// load data in user models array
.onAppear(perform: {
    self.userModels = DB_Manager().getUsers()
})

Now, we need to create a function named getUsers() in our DB manager class:

// return array of user models
public func getUsers() -> [UserModel] {
    
    // create empty array
    var userModels: [UserModel] = []

    // get all users in descending order
    users = users.order(id.desc)

    // exception handling
    do {

        // loop through all users
        for user in try db.prepare(users) {

            // create new model in each loop iteration
            let userModel: UserModel = UserModel()

            // set values in model from database
            userModel.id = user[id]
            userModel.name = user[name]
            userModel.email = user[email]
            userModel.age = user[age]

            // append in new array
            userModels.append(userModel)
        }
    } catch {
        print(error.localizedDescription)
    }

    // return array
    return userModels
}

This will fetch the users from the SQLite database in descending order (latest users first) and return them as an array of user model classes.

Run the app and now you will see the users that have been added in a tabular format. You can try removing the app from the background and open again, the data will still be there. Data will only be removed when the app is uninstalled.

3. Edit user

Editing the user requires multiple steps:

  1. Get user by ID.
  2. Show user details in input fields.
  3. Update the user in the database using his ID.

First, we need to create 2 state variables at the top of the content view which will tell WHEN the user is selected for editing and WHICH user is selected.

// check if user is selected for edit
@State var userSelected: Bool = false

// id of selected user to edit or delete
@State var selectedUserId: Int64 = 0

Now, in your HStack inside the list view, create a button to edit the user:

// button to edit user
Button(action: {
    self.selectedUserId = model.id
    self.userSelected = true
}, label: {
    Text("Edit")
        .foregroundColor(Color.blue)
    })
    // by default, buttons are full width.
    // to prevent this, use the following
    .buttonStyle(PlainButtonStyle())

This will set the userSelected variable to true, and selectedUserId to the ID of the user you have selected. Now we need to move to the new view to edit the user.

Create a navigation link with an empty view, inside the content view body and before the list view:

// navigation link to go to edit user view
NavigationLink (destination: EditUserView(id: self.$selectedUserId), isActive: self.$userSelected) {
    EmptyView()
}

EditUserView.swift

Create a new view file named EditUserView.swift and paste the following code into it. Pay close attention to the highlighted lines:

//
//  EditUserView.swift
//  SQLite_Database
//
//  Created by Adnan Afzal on 24/11/2020.
//  Copyright © 2020 Adnan Afzal. All rights reserved.
//

import SwiftUI

struct EditUserView: View {
    
    // id receiving of user from previous view
    @Binding var id: Int64
    
    // variables to store value from input fields
    @State var name: String = ""
    @State var email: String = ""
    @State var age: String = ""
    
    // to go back to previous view
    @Environment(\.presentationMode) var mode: Binding<PresentationMode>
    
    var body: some View {
        VStack {
            // create name field
            TextField("Enter name", text: $name)
                .padding(10)
                .background(Color(.systemGray6))
                .cornerRadius(5)
                .disableAutocorrection(true)
            
            // create email field
            TextField("Enter email", text: $email)
                .padding(10)
                .background(Color(.systemGray6))
                .cornerRadius(5)
                .keyboardType(.emailAddress)
                .autocapitalization(.none)
                .disableAutocorrection(true)
            
            // create age field, number pad
            TextField("Enter age", text: $age)
                .padding(10)
                .background(Color(.systemGray6))
                .cornerRadius(5)
                .keyboardType(.numberPad)
                .disableAutocorrection(true)
            
            // button to update user
            Button(action: {
                // call function to update row in sqlite database
                DB_Manager().updateUser(idValue: self.id, nameValue: self.name, emailValue: self.email, ageValue: Int64(self.age) ?? 0)

                // go back to home page
                self.mode.wrappedValue.dismiss()
            }, label: {
                Text("Edit User")
            })
                .frame(maxWidth: .infinity, alignment: .trailing)
                .padding(.top, 10)
                .padding(.bottom, 10)
        }.padding()

        // populate user's data in fields when view loaded
        .onAppear(perform: {
            
            // get data from database
            let userModel: UserModel = DB_Manager().getUser(idValue: self.id)
            
            // populate in text fields
            self.name = userModel.name
            self.email = userModel.email
            self.age = String(userModel.age)
        })
    }
}

struct EditUserView_Previews: PreviewProvider {
    
    // when using @Binding, do this in preview provider
    @State static var id: Int64 = 0
    
    static var previews: some View {
        EditUserView(id: $id)
    }
}

@Binding is used when you want to pass the value from one view to another. In that case, if you are using preview provider, then you have to create the @State variable in it.

At this time, you will be getting error at DB_Manager().updateUser and DB_Manager().getUser because these functions are not yet created in DB manager class.

First, we will create the function to get the single user from SQLite database using his ID. In your DB_Manager.swift:

// get single user data
public func getUser(idValue: Int64) -> UserModel {

    // create an empty object
    let userModel: UserModel = UserModel()
    
    // exception handling
    do {

        // get user using ID
        let user: AnySequence<Row> = try db.prepare(users.filter(id == idValue))

        // get row
        try user.forEach({ (rowValue) in

            // set values in model
            userModel.id = try rowValue.get(id)
            userModel.name = try rowValue.get(name)
            userModel.email = try rowValue.get(email)
            userModel.age = try rowValue.get(age)
        })
    } catch {
        print(error.localizedDescription)
    }

    // return model
    return userModel
}

The filter function at the highlighted line helps to perform the WHERE clause (to filter the data).

Now we need to create a function in the DB manager class to update the user in the SQLite database.

// function to update user
public func updateUser(idValue: Int64, nameValue: String, emailValue: String, ageValue: Int64) {
    do {
        // get user using ID
        let user: Table = users.filter(id == idValue)
        
        // run the update query
        try db.run(user.update(name <- nameValue, email <- emailValue, age <- ageValue))
    } catch {
        print(error.localizedDescription)
    }
}

Here, we are first getting the user object using the filter() function. Then we are running the update query on that user’s object.

Run the app and now you will see an “Edit” button at the end of each user’s record. Clicking on that will take you to another view, from where you will see the user’s data in input fields. Clicking the “Update” button will update the data and move it back to the home view.

4. Delete user

To delete a user from the SQLite database in Swift UI, first, we will create a delete button in the list view like we created the edit button.

// create list view to show all users
List (self.userModels) { (model) in

    // show name, email, and age horizontally
    HStack {
        ... edit button
        
        // button to delete user
        Button(action: {

            // create db manager instance
            let dbManager: DB_Manager = DB_Manager()

            // call delete function
            dbManager.deleteUser(idValue: model.id)

            // refresh the user models array
            self.userModels = dbManager.getUsers()
        }, label: {
            Text("Delete")
                .foregroundColor(Color.red)
        })// by default, buttons are full width.
        // to prevent this, use the following
        .buttonStyle(PlainButtonStyle())
    }
}

The above code should be placed after the edit button in the content view. You can see that we created an instance of DB_Manager class and save it in another variable. Because we need to call 2 functions from DB_Manager class.

The first function will delete the user from the SQLite database, and the second function will update the list view. So the delete user will be removed from view as well.

Create the following function in your DB_Manager class:

// function to delete user
public func deleteUser(idValue: Int64) {
    do {
        // get user using ID
        let user: Table = users.filter(id == idValue)
        
        // run the delete query
        try db.run(user.delete())
    } catch {
        print(error.localizedDescription)
    }
}

If you run the app now, you will see a delete button at the end of each user’s record. Clicking that button will remove the user from the database and from the list view as well. You can try removing the app from the background process and re-open it again, the deleted data will not appear again.

Where you can use SQLite in the iOS app?

You can create a feature to save the search history of users locally in the app. So users can re-search the same thing from search history.

You can cache the frequent data in SQLite, so instead of requesting the data from the server, it will be accessed from inside the app. It will increase the performance of your app.

Or you can simply create a server-less app like “Personal account book-keeping app” using SQLite and Swift UI. These type of apps does not require an internet connection to work and the user can use them even without access to the internet.

[wpdm_package id=’923′]