How to Use gRPC in Your iOS App with a Node.js Server

How to Use gRPC in Your iOS App with a Node.js Server How to Use gRPC in Your iOS App with a Node.js Server

Today we will discuss and implement a CRUD operation of gRPC in an iOS Swift project. We will create an Xcode project and show a list of Students in a UITableView. Before starting, let's look up what gRPC is and how it works.

What is gRPC?

gRPC is a Remote Procedure Call framework that is open source, language-neutral, uses compact binary (Protocol Buffers) instead of JSON, is HTTP/2 based, and supports three communication patterns:

PatternDescription
UnarySingle request → single response
Server / Client StreamingOne-sided streaming
Bidirectional StreamingBoth sides stream simultaneously
I will mainly focus on the iOS Client implementation here. For more details on the protocol itself, read the official docs.

Step 1 — Set Up the Node.js Server

I built a small gRPC server in Node.js for testing. Download the full repo: github.com/avijitmobi/demo-grpc-student-node-crud

Make sure Node.js is installed. Then run:

bash
npm install
npm run server

The server starts at localhost:8000. You'll see output confirming the gRPC server is running.


Step 2 — Install the Proto Compiler (protoc)

The proto compiler converts .proto files into language-specific code. Follow these steps on macOS:

  1. Download the proto buffer compiler from github.com/protocolbuffers/protobuf
  2. Extract the compressed file
  3. Open Terminal and cd into the extracted folder
  4. Run the installation commands (below)
  5. Confirm with protoc --version
bash
./configure
make
make check
sudo make install
which protoc

# Confirm:
protoc --version
# Output: libprotoc 3.20.1
Terminal — setting protobuf folder as current directory
Snapshot 1 — Setting the protobuf folder as current directory
Terminal — confirming protoc installation
Snapshot 2 — Confirming successful installation
Important: Use the same proto compiler version on both the server and client to avoid compatibility issues.

Step 3 — Install Swift Protobuf Plugin

We need Apple's Swift protobuf plugin to generate Swift code from .proto files.

Option A — Homebrew (recommended)

bash
brew install swift-protobuf

# Verify:
protoc-gen-swift --version

Option B — From source

bash
git clone https://github.com/apple/swift-protobuf.git
cd swift-protobuf
swift build -c release
Swift Protobuf plugin installed successfully
Snapshot 3 — Swift Protobuf plugin verified

Step 4 — Understanding the .proto File

Here's a quick overview of the Student proto file structure. Key concepts:

  • proto3 — we use syntax version 3
  • service — defines the RPC methods available on client and server
  • message — the struct/class equivalent, defines the data model
  • repeated — means an array/list of items
Proto file structure showing service and message definitions
Snapshot 4 — The Student proto file structure

Step 5 — Generate Swift Protocol Buffer Files

Navigate your Terminal to the folder containing the .proto file and run:

bash
# Generate the data model (.pb.swift)
protoc --swift_out=. student.proto

# Generate the service client (.grpc.swift)
protoc student.proto --grpc-swift_out=Client=true,Server=false:.

This generates two files: student.pb.swift (data models) and student.grpc.swift (service client). Do not edit these files — they are auto-generated.

Generated Swift pb and grpc files in Xcode project
Snapshot 5 — Generated .pb.swift and .grpc.swift files in Xcode

Step 6 — Add gRPC-Swift via CocoaPods

ruby
# Podfile
pod 'gRPC-Swift', '~> 1.0.0'
bash
pod install
open YourProject.xcworkspace

Step 7 — Create the GRPC Repository

Create GRPCRepository.swift and implement the server connection:

swift
import Foundation
import GRPC
import NIO

class GRPCRepository {

    // 1. Channel connects us to the gRPC server
    var channel: GRPCChannel!

    // 2. Thread management via NIO event loop group
    let group = MultiThreadedEventLoopGroup(numberOfThreads: 1)

    init() {
        // 3. Start connection to local Node.js gRPC server
        channel = try! GRPCChannelPool.with(
            target: .host("localhost", port: 8000),
            transportSecurity: .plaintext,
            eventLoopGroup: group
        )
    }

    // 4. Service client from generated proto code
    var studentClient: Student_StudentServiceClient {
        return Student_StudentServiceClient(channel: channel)
    }

    // 5. Fetch all students from the server
    func fetchStudents(completion: @escaping ([Student_Student]?, Error?) -> Void) {
        let call = studentClient.findStudent(Student_Empty())
        call.response.whenComplete { result in
            switch result {
            case .success(let response): completion(response.students, nil)
            case .failure(let error):    completion(nil, error)
            }
        }
    }

    deinit {
        try? group.syncShutdownGracefully()
    }
}

Step 8 — Display Students in UITableView

swift
import UIKit

class StudentListViewController: UITableViewController {

    var students: [Student_Student] = []
    let repo = GRPCRepository()

    override func viewDidLoad() {
        super.viewDidLoad()
        title = "Students"
        fetchData()
    }

    func fetchData() {
        repo.fetchStudents { [weak self] students, error in
            guard let self = self else { return }
            if let students = students {
                DispatchQueue.main.async {
                    self.students = students
                    self.tableView.reloadData()
                }
            }
        }
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return students.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
        let student = students[indexPath.row]
        cell.textLabel?.text = student.name
        cell.detailTextLabel?.text = "ID: \(student.id)"
        return cell
    }
}
Final result — student list from gRPC rendered in UITableView
Final result — student list fetched via gRPC, rendered in UITableView

Download the Source Code

Happy Coding! You can comment below if you faced any problems getting this running.
 All Articles
Share: