Pull to refresh

How to Make an E-commerce App in SwiftUI

Level of difficultyMedium
Reading time4 min
Views1.1K

In this guide, I'm going to walk you through how to create a simple e-commerce app using SwiftUI and Firebase. The app will include basic functionalities such as product listing, shopping cart, and user authentication.

Before we get started, you should have the following installed:

  • Xcode

  • Firebase SDK

  • CocoaPods (for installing Firebase SDK)

Step 1: Setting up the Xcode Project

First, I'll create a new Xcode project. I'll select the "App" option under "iOS".

File -> New -> Project -> iOS -> App

I'll name it "EcommerceApp" and choose SwiftUI for the interface and Swift for the language.

Step 2: Setting up Firebase

  1. I'll go to the Firebase console.

  2. Click "Add project", then follow the on-screen instructions to create a new project.

Once my project is ready, I need to add an iOS app to it.

  1. In the Project Overview page, I'll click the iOS icon to add an iOS app to my Firebase project.

  2. I'll fill in the iOS bundle ID which is found in my Xcode project settings. Then, follow the steps to download the GoogleService-Info.plist file.

  3. I'll drag the downloaded GoogleService-Info.plist file into my Xcode project root.

Now, it's time to install the Firebase SDK using CocoaPods. I'll open the Terminal, navigate to my project root, and type:

pod init

This command will create a Podfile. I'll open it and add:

pod 'Firebase/Auth'
pod 'Firebase/Firestore'

Then, I'll run:

pod install

Now, I'll open the .xcworkspace file.

In the AppDelegate.swift, I'll import Firebase and add FirebaseApp.configure() in didFinishLaunchingWithOptions:

import UIKit
import Firebase

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    FirebaseApp.configure()
    return true
  }
  // ...
}

Step 3: Creating User Authentication

First, I need to create a simple login view. In the Firebase Console, I'll enable the Email/Password sign-in method in the Authentication section.

In ContentView.swift, I'll add:

import SwiftUI
import FirebaseAuth

struct ContentView: View {
  @State private var email = ""
  @State private var password = ""
  
  var body: some View {
    VStack {
      TextField("Email", text: $email)
        .padding()
        .autocapitalization(.none)
      SecureField("Password", text: $password)
        .padding()
      Button(action: {
        Auth.auth().signIn(withEmail: email, password: password) { authResult, error in
          if let error = error {
            print(error.localizedDescription)
          }
        }
      }) {
        Text("Login")
      }
      .padding()
    }
  }
}

Step 4: Product Listing

Let's assume I have a products collection in Firestore, where each document has name, price, and description fields.

I will create a Product struct and a ProductView:

struct Product: Identifiable {
  var id: String
  var name: String
  var price: Double
  var description: String
}

struct ProductView: View {
  var product: Product
  
  var body: some View {
    VStack(alignment: .leading) {
      Text(product.name)
        .font(.headline)
      Text(product.description)
        .font(.subheadline)
      Text("$\(product.price)")
        .font(.title)
    }
    .padding()
  }
}

Then, I'll create a ProductListView to fetch and list the products:

import FirebaseFirestore

struct ProductListView: View {
  @State private var products = [Product]()
  
  var body: some View {
    List(products) { product in
      ProductView(product: product)
    }
    .onAppear() {
      fetchProducts()
    }
  }
  
  func fetchProducts() {
    Firestore.firestore().collection("products").getDocuments() { querySnapshot, error in
      if let error = error {
        print(error.localizedDescription)
        return
      }
      
      self.products = querySnapshot?.documents.compactMap { document -> Product? in
        let data = document.data()
        
        guard let name = data["name"] as? String,
              let price = data["price"] as? Double,
              let description = data["description"] as? String
        else {
          return nil
        }
        
        return Product(id: document.documentID, name: name, price: price, description: description)
      } ?? []
    }
  }
}

Step 5: Shopping Cart

First, I'll create a Cart model and a CartView. In the CartView, I'll list all the products in the cart and calculate the total price:

struct CartProduct: Identifiable {
  var id: String
  var product: Product
  var quantity: Int
}

struct CartView: View {
  @State private var cartProducts = [CartProduct]()
  
  var body: some View {
    VStack {
      List(cartProducts) { cartProduct in
        HStack {
          Text(cartProduct.product.name)
          Spacer()
          Text("x\(cartProduct.quantity)")
          Text("$\(cartProduct.product.price * Double(cartProduct.quantity))")
        }
        .padding()
      }
      
      Text("Total: $\(cartProducts.reduce(0) { $0 + $1.product.price * Double($1.quantity) })")
        .font(.headline)
        .padding()
    }
  }
  
  func fetchCart() {
    // Here, I'll fetch cart products from Firestore...
  }
}

In the ProductView, I'll add an "Add to Cart" button:

struct ProductView: View {
  var product: Product
  
  var body: some View {
    VStack(alignment: .leading) {
      Text(product.name)
        .font(.headline)
      Text(product.description)
        .font(.subheadline)
      Text("$\(product.price)")
        .font(.title)
      Button(action: {
        addToCart(product)
      }) {
        Text("Add to Cart")
      }
    }
    .padding()
  }
  
  func addToCart(_ product: Product) {
    // Here, I'll add the product to the cart in Firestore...
  }
}

In both fetchCart() and addToCart(_:), I'll need to implement the logic to interact with Firestore. The cart could be a subcollection in each user document, where each document in the cart collection represents a cart product, with productId, quantity, and addedAt fields.

Conclusion

While this is a simplified example, it covers the core features of an e-commerce app: user authentication, product listing, and a shopping cart. Check out iOS app templates for ready-to-use codebases if you want to save time and energy.

Tags:
Hubs:
Rating0
Comments1

Articles