Premium projects bundle

Buy the 14 premium projects bundle for $1000. The bundle contains projects in the following technologies:

  • Node JS and Mongo DB
  • PHP & MySQL, Laravel
  • Vue JS
  • Android apps

Project’s list

  1. Single page chat application – Vue JS, Node JS, Mongo DB
  2. E-commerce single page application – Vue JS, Node JS, Mongo DB
  3. Chat app – Android, Web admin panel
  4. Email marketing tool – Laravel, Vue JS
  5. Financial ledger – Vue JS, Node JS, Mongo DB
  6. Image sharing web app – Node JS, Mongo DB / MySQL
  7. Movie ticket booking site – PHP & MySQL, MVC
  8. Realtime blog in Node JS and Mongo DB
  9. File transfer web app – Node JS + Mongo DB
  10. Realtime customer support chat widget
  11. Video streaming website – Node JS, Mongo DB
  12. Picture competition web app – Node JS, Mongo DB
  13. Questionnaire – Node JS, Mongo DB
  14. Blog website – Laravel, Google Adsense approved

You can buy each project separately too as well. Besides getting all the pro features of all 14 projects, we also provide additional services to them.

Secure payment

We allow users to make payments easily and securely using their bank accounts. You can contact us here and we will send you an invoice to make the payment.

Source code

Complete source code is included in all the projects. You will enjoy the pro version of each project.

Support

If you encounter any problem in installing the project or deployment, our technical support team is here. You can schedule a meeting with them and they will be able to assist you over AnyDesk or TeamViewer.

Use as a college project

If you are a student and are looking to get ready-to-go projects to learn about code and how real projects work, this will be beneficial for you. Also, Node JS projects are good learning points for students in advanced programming.

Customize as you want

Once you download the projects, you can customize them as per your needs. You can change the color theme, add new features to it, etc.

Get help in deployment

Once projects are set up in your local host, we will be here if you needed any help in deployment to the live server. For Node JS projects, we will assist you in deployment to Heroku. And for Mongo DB projects, we will help you with a deployment to mongodb.com.

Price: $1000

Out TrustPilot reviews

TrustPilot-reviews
TrustPilot-reviews

Password protect ZIP file in Mac OS X

In this article, we will show you how you can password protect your zip file in Mac OS X. To create a ZIP file and set the password to it using Mac, you simply need to follow the following steps:

  1. Open Terminal
  2. Open folder where target file is located by running the command:
    • cd “path of folder”
  3. Run the following command:
    • zip -er “my-file.zip” “target file or folder”
  4. It will ask password twice.

It may take longer for large files. You can then use the encrypted file on all iOS-based devices like Mac, iPhone, iPad, etc.

Learn how to password protect a ZIP file in PHP from this tutorial.

If you are a windows user, you can use the 7-zip software to password-protect the files.

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′]

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′]

Local storage Swift UI – CRUD

Local storage means the data that is stored inside the app. You do not need an internet connection to create or read data from local storage. We will create a simple iOS app in Swift UI that allows you to create, read, update, and delete values in local storage. For that, we are going to use a built-in class in Swift called UserDefaults.

Note: UserDefaults class must only be used to store singular values, for example, last_login, name, email, etc. It should NOT be used to store data in the tabular form like MySQL, or in embedded form like Mongo DB.

Local Storage

We will create a simple Swift file named LocalStorage.swift. This file will handle the creating, fetching, updating and deleting the data from local storage.

//
//  LocalStorage.swift
//  Local storage CRUD
//
//  Created by Adnan Afzal on 16/11/2020.
//  Copyright © 2020 Adnan Afzal. All rights reserved.
//

import Foundation

class LocalStorage {
    
    private static let myKey: String = "myKey"
    
    public static var myValue: String {
        set {
            UserDefaults.standard.set(newValue, forKey: myKey)
        }
        get {
            return UserDefaults.standard.string(forKey: myKey) ?? ""
        }
    }
    
    public static func removeValue() {
        UserDefaults.standard.removeObject(forKey: myKey)
    }
    
}

  1. We are creating a static constant named myKey which will hold the name of data.
  2. Then we are creating a static variable named myValue and it has getter and setter. They will automatically be called when we try to save or fetch the value from it.
  3. UserDefaults.standard.string this function returns an optional value, so we have to tell the default value using ?? “”. Here we are setting empty value as default.
  4. Lastly, a static function named removeValue() is created which will remove that value from UserDefaults.

We have made the variables and functions static, so we can use them without creating an object of the LocalStorage class.

You can use the same technique to add as more values as required.

Main Swift UI view

First, we will create a view where we will show 4 buttons to create, view, update, and delete data from UserDefaults. In your main ContentView file, create a navigation view, and inside it create 4 navigation links horizontally.

Right now, we are creating navigation link for AddView only. We will create navigation links for others later in this article.

NavigationView {
    HStack { 
        NavigationLink (destination: AddView(), label: {
            Text("Add")
        })
    }
}
  1. destination: is the view which will be displayed when this navigation link is clicked
  2. label: is the view that will be displayed to the user.

Add value to local storage

Now create a new Swift UI view file named AddView.swift. In this view, we will create an input field and a button which when clicked will save the text field value in local storage.

To get the value from the text field in Swift UI, we will use the @State property wrapper. First, create a @State variable of type String inside your AddView struct:

@State var value: String = ""

Now we can bind this variable in text field’s text value.

VStack {
    TextField("Enter value", text: $value)

    Button(action: {
        LocalStorage.myValue = self.value
    }, label: {
        Text("Save")
    })
}
  1. VStack will show the views vertically.
  2. TextField field is created and its value is bound with our value variable.
  3. Button is created with the text “Save” which when clicked will set the myValue variable from LocalStorage class to our value variable.

The setter inside LocalStorage myValue variable will automatically be called when we assign the value. The code inside setter saves the value in UserDefaults.

Get value from local storage

First, we will create a navigation link in our main view to move to a new view to show value from local storage.

// ContentView.swift

NavigationLink (destination: DataView(), label: {
    Text("View")
})

Now create a new Swift UI view file named DataView.swift. This file will simply fetch the value and show it in text view.

Text(LocalStorage.myValue)

This will automatically called the getter inside LocalStorage myValue variable. The getter is fetching the value from UserDefaults. If the value is not found, then it is setting the default value to empty string.

Edit value in local storage

First, we will create a navigation link in our main view to move to a new view to update the value in local storage.

// ContentView.swift

NavigationLink (destination: EditView(), label: {
    Text("View")
})

Now create a new Swift UI view file named EditView.swift. Editing the value is almost similar to adding the value. But it has 2 steps:

  1. Show the existing value in text field.
  2. Update the value from text field.

Again, we will create a @State property wrapper in this view:

@State var value: String = ""

Then, we will create VStack to show text field and a button vertically. Bound the value variable to text field’s value. Create a button with a text “Update” and setting the local storage value to text field value (same as we did for adding value).

But when the view is loaded, you need to show the existing value in the text field. You can do that by adding an onAppear function to your main view (VStack in my case). In the perform parameter, we will fetch the value from local storage and assign it to our value variable.

As the text field’s text is bound to value variable, so when it’s value is changed, the text field’s text will automatically be changed.

VStack {
    TextField("Enter value", text: $value)
    Button(action: {
        LocalStorage.myValue = self.value
    }, label: {
        Text("Update")
    })
}
.onAppear(perform: {
    self.value = LocalStorage.myValue
})

Delete a value from local storage

We do not need to create a navigation link to delete. We will simply create a button that when clicked will call the function removeValue() from LocalStorage class.

Button(action: {
    LocalStorage.removeValue()
}, label: {
    Text("Delete")
})

Your local storage CRUD operation in Swift UI is done here.

[wpdm_package id=’870′]

Send value from one view to another – Swift UI

We will create a text field in one view and send its value into another view. We will be taking an example of a search, you write a text to search in one view and the second view will show you the text you had written on the first view.

Note: When implementing a complete search functionality, you usually show the searched data based on a text query. But this is just an example of how you can implement this.

Video tutorial:

@State property wrapper

We will create 2 @State property wrappers, one to save the value from the text field and the second to show the search page when the user hits the return key.

// string variable to store search query
@State var searchedText: String = ""

// boolean variable to show search view
@State var showSearch: Bool = false

Text field

Now we will create a text field and binds its value to our first variable. As the user types in the input field, we will have its value in that variable.

TextField("Search here...", text: $searchedText, onCommit: {
    // this will be called when the search is clicked
    self.showSearch = true
})
.padding(8)
.keyboardType(.webSearch)
.background(Color(.systemGray6))
.disableAutocorrection(true)
.cornerRadius(5)

Following are the things which needs to understand from above code:

  1. TextField’s first parameter is the string that will be shown to the user.
  2. The second parameter is the binding which will store the text field value in the given variable.
  3. onCommit: is called when the user hits the return key. In this callback, we are setting the showSearch value to true. Note: We will come back to this later.
  4. padding(8): sets the margin between text content and text field borders.
  5. keyboardType(.webSearch): will show a full keyboard with a search icon on bottom right.
  6. background(Color(.systemGray6)): will set the background color of text field to light gray.
  7. disableAutocorrection(true): will disable the auto-correction on this field.
  8. cornerRadius(5): this will make the corners of the text field a little rounded rather than squares.

Pass value to next view

Now we will pass this text field value to next view. This can be done using navigation link:

// goto search view
NavigationLink (destination: SearchView(searchedText: $searchedText), isActive: $showSearch) {
    EmptyView()
}

destination is the view which will be shown when the value in isActive becomes true.

Right now, you will get an error in SearchView because we haven’t created that view yet. Also, we are sending searchedText as a parameter which means that we have to create a @Binding property wrapper in search view.

The EmptyView() is the label that is shown in the first view. But we don’t want any text to be displayed on the initial value, so we are making it an empty view.

When using navigation link, you must wrap your outer parent with navigation view. So your view body will be like this:

NavigationView {
    VStack {
        
        // goto search view
        NavigationLink (destination: SearchView(searchedText: $searchedText), isActive: $showSearch) {
            EmptyView()
        }
        
        TextField("Search here...", text: $searchedText, onCommit: {
            // this will be called when the search is clicked
            self.showSearch = true
        })
        .padding(8)
        .keyboardType(.webSearch)
        .background(Color(.systemGray6))
        .disableAutocorrection(true)
        .cornerRadius(5)
        
    }.padding()
}

Search view

Now, create another view file in your project named SearchView.swift. As we are sending a searched text in its constructor, so we must add a @Binding variable in it:

// @Binding is used when variables need to be passed between 2 views
@Binding var searchedText: String

Now, you might get the error in your preview provider code. It is because we need to pass the value from here as well. Replace your preview provider body code with the following:

// when using @Binding, @State static must be used to show preview
@State static var searchedText: String = ""

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

Now, inside the body of view, we are simply displaying the searched value in a text. But you can use it in any way you want.

// show searched text in this view
        
VStack {
    Text(self.searchedText)
}

That’s how you can send value from one view to another using Swift UI.

[wpdm_package id=’865′]

Show an alert with callback Swift UI

To show an alert with callback in Swift UI, you need 3 things:

  1. A boolean state variable that tells when to show the alert message.
  2. A string state variable that tells the title of the alert.
  3. A string state variable that tells the content of an alert message.

Video tutorial:

So let’s go ahead and create these 3 variables in your view:

@State var showAlert: Bool = false
@State var alertTitle: String = ""
@State var alertMessage: String = ""

When the variable becomes true, an alert will be displayed with a title and a message.

// main layout
VStack {

    // when clicked will show the alert
    Button(action: {
        
        // set title of alert
        self.alertTitle = "Error"

        // set message of alert
        self.alertMessage = "Please try again"
        
        // this line will actually show the alert
        self.showAlert = true
        
    }, label: {
        // text to show in button
        Text("Show alert")
    })
    
    // bind showAlert here
}.alert(isPresented: $showAlert, content: {

    // alert dialog
    Alert(
        title: Text(self.alertTitle),
        message: Text(self.alertMessage),
        dismissButton: .default(Text("OK")) {

            // this will be called when the dismiss button is clicked
            print("dismissed")
        }
    )
})

Show API data in XCode preview – Swift UI

You won’t be able to preview your layout in your XCode preview in Swift UI when you are receiving data from the server. So we are going to show you how you can preview the layout with the data from your API.

Video tutorial:

API to return JSON data

First, create an API that will return the JSON in a pretty format. We are going to create that API in PHP. You can find the sample database in the attachment below.

<?php

    $conn = mysqli_connect("localhost:8889", "root", "root", "classicmodels");

    $result = mysqli_query($conn, "SELECT * FROM customers");

    $data = array();
    while ($row = mysqli_fetch_object($result))
    {
        array_push($data, $row);
    }

    header("Content-Type: application/json");

    echo json_encode($data, JSON_PRETTY_PRINT);

?>

It does the following things:

  1. Connect with the database.
  2. Fetch records from the customer’s table.
  3. Create a new empty array.
  4. Loop through all records from the database.
  5. Push in the array.
  6. Return the response as JSON pretty format.

If you run this file in your browser using XAMPP, WAMP, or MAMP, you will see all the data in JSON format. Copy all the content from the browser.

Create a JSON file in the XCode project

Now create a new file in your XCode project named “data.json”, you must select “Empty” while creating a new file in your XCode project. And paste the copied content into that file.

Create model class

Now in your View where you want to show the data, first create a model class that will hold the values you want to show in your List view.

// ResponseModel.swift

class ResponseModel: Codable, Identifiable {
    var customerName: String? = ""
    var country: String? = ""
}

Model class must implement Codable and Identifiable protocols.

Create an array of models

Inside your View class, create an array of these models and initialize it as an empty array.

@State var models: [ResponseModel] = []

List view

Now create a List view and show these 2 variables from the model class in the Text view.

VStack {
    List (models) { (model) in
        Text(model.customerName ?? "").bold()
        Text(model.country ?? "")
    }
}

This is the syntax to create a list view from an array. We are making the customer name to bold so we can differentiate between the customer name and country.

The layout could be different as per your need.

Read JSON file and Decode it into the model

Now we need to fill this “models” array with data from the JSON file we saved in our project. Following is the code that will read the JSON file from the XCode project and decode the JSON data into an array of models.

guard let url: URL = Bundle.main.url(forResource: "data", withExtension: "json") else {
    print("data.json not found")
    return
}

do {
    
    let data: Data = try Data(contentsOf: url)
    
    self.models = try JSONDecoder().decode([ResponseModel].self, from: data)
    
} catch {
    print(error.localizedDescription)
}

It does the following:

  1. Get the file from the bundle named “data.json”. The guard statement will throw an error if the file is not found. The bundle will return a URL object.
  2. Create a do-catch block that will throw an error if the data is not decodable to ResponseModel class.
  3. Convert the URL into a Data object.
  4. Decode the Data object into an array of ResponseModel class and assign it to the “models” array.

As “models” is a @State variable so it will automatically render the List view when the data is added to the model’s array.

Render List view

You can run the above inside your VStack’s onAppear function like below:

VStack {
    List (models) { (model) in
        Text(model.customerName ?? "").bold()
        Text(model.country ?? "")
    }
}.onAppear(perform: {

    // above code here

});

Conclusion

This is really helpful because when you are developing an app, you have to preview the layout you are designing in XCode, instead of re-running the app again and again to see the output.

You can do this with every API whose data you want to show in your Swift UI app. So that’s how you can show your API data in your XCode preview.

Learn how to create a search bar with history in Swift UI and SQLite.

Search bar Swift UI with history – SQLite

[wpdm_package id=’866′]

Get data from API and show in list – Swift UI, PHP

We will create a simple iOS app in Swift UI that will call an API request, developed in PHP, to the HTTP server. The API will return an array of records in JSON format, which we will decode in Swift class objects as an array. Then we will display that list in a list view.

If you prefer a video tutorial:

Our API will be in PHP and we will call it from our Swift UI app. So, create a file in your htdocs (for XAMPP), or www (for MAMP or WAMP) folder and paste the following code in it. We have created a folder named “test” and inside it, the file name is “swiftui-get-data-from-api.php”:

<?php

    $conn = mysqli_connect("localhost:8889", "root", "root", "classicmodels");

    // get data from database
    $result = mysqli_query($conn, "SELECT * FROM customers");

    // adding in array
    $data = array();
    while ($row = mysqli_fetch_object($result))
    {
        array_push($data, $row);
    }

    // send as response
    echo json_encode($data);

?>

For that, you need to create a database named “classicmodels” in your phpMyAdmin and import the SQL file attached below. You need to create and login into your account in order to download that file. You can see the output from the link:

http://localhost/test/swiftui-get-data-from-api.php

This might be changed and it depends on the path of your file. You will see a lot of data, for example, we want to show only customerName and country in our Swift UI app. So you need to create a model file in your project using XCode and paste the following code into it:

// ResponseModel.swift
class ResponseModel: Codable, Identifiable {
    var customerName: String? = ""
    var country: String? = ""
}

Now in your View file where you want to show the list, you can paste the following code:

@State var models: [ResponseModel] = []
    
var body: some View {
    // Create VStack
    VStack {
        // now show in list
        // to show in list, model class must be identifiable
        
        List (self.models) { (model) in
            HStack {
                // they are optional
                Text(model.customerName ?? "").bold()
                Text(model.country ?? "")
            }
        }
        
    }.onAppear(perform: {
        // send request to server
        
        guard let url: URL = URL(string: "http://localhost:8888/test/swiftui-get-data-from-api.php") else {
            print("invalid URL")
            return
        }
        
        var urlRequest: URLRequest = URLRequest(url: url)
        urlRequest.httpMethod = "GET"
        URLSession.shared.dataTask(with: urlRequest, completionHandler: { (data, response, error) in
            // check if response is okay
            
            guard let data = data else {
                print("invalid response")
                return
            }
            
            // convert JSON response into class model as an array
            do {
                self.models = try JSONDecoder().decode([ResponseModel].self, from: data)
            } catch {
                print(error.localizedDescription)
            }
            
        }).resume()
    })
}

All the code is self-explanatory and comments are also added to explain difficult lines. But if you still face any issues in following this tutorial, please let us know.

[wpdm_package id=’847′]

Pick image from gallery and upload to server – SwiftUI and PHP

Learn how to upload image from SwiftUI app. We will not be using any external library in this tutorial. All code is done in native SwiftUI. We will use a picker from an iPhone gallery and upload it to your server. We will be using SwiftUI for developing the app and PHP for uploading the image to the server.

First, you need to create a file in your project named ImagePicker.swift and paste the following content in it:

//
//  ImagePicker.swift
//
//  Created by Adnan Afzal on 30/10/2020.
//  Copyright © 2020 Adnan Afzal. All rights reserved.
//

import Foundation
import SwiftUI

extension View {
    public func asUIImage() -> UIImage {
        let controller = UIHostingController(rootView: self)
        
        controller.view.frame = CGRect(x: 0, y: CGFloat(Int.max), width: 1, height: 1)
        UIApplication.shared.windows.first!.rootViewController?.view.addSubview(controller.view)
        
        let size = controller.sizeThatFits(in: UIScreen.main.bounds.size)
        controller.view.bounds = CGRect(origin: .zero, size: size)
        controller.view.sizeToFit()
        
        // here is the call to the function that converts UIView to UIImage: `.asImage()`
        let image = controller.view.asUIImage()
        controller.view.removeFromSuperview()
        return image
    }
}

extension UIView {
// This is the function to convert UIView to UIImage
    public func asUIImage() -> UIImage {
        let renderer = UIGraphicsImageRenderer(bounds: bounds)
        return renderer.image { rendererContext in
            layer.render(in: rendererContext.cgContext)
        }
    }
}

struct ImagePicker: UIViewControllerRepresentable {

    @Environment(\.presentationMode)
    var presentationMode

    @Binding var image: Image?

    class Coordinator: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate {

        @Binding var presentationMode: PresentationMode
        @Binding var image: Image?

        init(presentationMode: Binding<PresentationMode>, image: Binding<Image?>) {
            _presentationMode = presentationMode
            _image = image
        }

        func imagePickerController(_ picker: UIImagePickerController,
                                   didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
            let uiImage = info[UIImagePickerController.InfoKey.originalImage] as! UIImage
            image = Image(uiImage: uiImage)
            presentationMode.dismiss()

        }

        func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
            presentationMode.dismiss()
        }

    }

    func makeCoordinator() -> Coordinator {
        return Coordinator(presentationMode: presentationMode, image: $image)
    }

    func makeUIViewController(context: UIViewControllerRepresentableContext<ImagePicker>) -> UIImagePickerController {
        let picker = UIImagePickerController()
        picker.delegate = context.coordinator
        return picker
    }

    func updateUIViewController(_ uiViewController: UIImagePickerController,
                                context: UIViewControllerRepresentableContext<ImagePicker>) {

    }

}

Now we have created a video tutorial to help you done this task. You can follow the video below:

[wpdm_package id=’867′]