frida-swift

April 5, 2026 · View on GitHub

Swift bindings for Frida — the dynamic instrumentation toolkit.

frida-swift lets you use Frida from Swift or SwiftUI through fully async/await-based APIs and structured concurrency instead of delegates.


🧩 Install

Apple platforms (macOS, iOS)

Build and install the framework locally:

make

Then either:

  • Copy build/Frida/Frida.framework into your Xcode project, or

  • Run:

    make install
    

    for a shared installation. You may first want to configure the prefix:

    ./configure --prefix=/your/installation/prefix
    

Linux (and other non-Apple platforms)

Install Frida as a system library so it's available via pkg-config:

pkg-config --cflags --libs frida-core-1.0

Then add the Swift package dependency as usual — Package.swift will automatically use the system library instead of the binary xcframework.


🖥️ Example (SwiftUI)

Here’s a minimal SwiftUI view that lists connected devices and lets you tap to attach:

import Frida
import SwiftUI

struct DevicesView: View {
    @StateObject private var model = DeviceListModel(manager: DeviceManager())
    @State private var selectedDevice: Device?
    @State private var session: Session?

    var body: some View {
        NavigationStack {
            List(model.devices, id: \.id) { device in
                Button {
                    Task {
                        selectedDevice = device
                        session = try? await device.attach(to: 12345)
                    }
                } label: {
                    VStack(alignment: .leading) {
                        Text(device.name)
                            .font(.headline)
                        Text(device.kind.rawValue)
                            .font(.subheadline)
                            .foregroundStyle(.secondary)
                    }
                }
            }
            .navigationTitle("Frida Devices")
            .overlay {
                if model.devices.isEmpty {
                    ProgressView("Searching for devices…")
                }
            }
        }
    }
}

Key points

  • DeviceListModel wraps DeviceManager and updates reactively as devices are added or removed.
  • The view stays in sync with live Frida device hot-plug events.
  • You can call async APIs like device.attach(to:) directly from SwiftUI actions.

🚀 Example (Async / Test-style)

For non-SwiftUI contexts, use the async streams directly:

func testFullCycle() async throws {
    let manager = DeviceManager()

    for await devices in await manager.snapshots() {
        guard let local = devices.first(where: { \$0.kind == .local }) else { continue }

        let session = try await local.attach(to: 12345)
        let script = try await session.createScript("""
            console.log("hello");
            send(1337);
        """)

        Task {
            for await event in script.events {
                switch event {
                case .message(let message, _):
                    print("Message:", message)
                case .destroyed:
                    print("Script destroyed")
                }
            }
        }

        try await script.load()
        break
    }
}

Notes

  • DeviceManager emits live device snapshots via await manager.snapshots().
  • Events are delivered through AsyncStream.
  • All APIs support structured concurrency and Task cancellation.

🧠 Design Philosophy

frida-swift aims to be:

  • Swifty — embracing async/await, actors, and AsyncSequence instead of callbacks.
  • Zero boilerplate — no manual threading or delegate wiring.
  • Faithful to Frida — same capabilities as the C APIs, expressed in idiomatic Swift.

API stability is not yet guaranteed — we’re still refining the concurrency model before freezing the surface.


⚖️ License

frida-swift is distributed under the wxWindows Library Licence, Version 3.1. See the accompanying COPYING file for full license text.