The debugging toolkit your iOS app deserves.
Network inspector. Storage browser. Log viewer. Rules engine. QA checklist. One floating bubble.
Documentation • Quick Start • Install • API • License
Network • Logs • Storage • Rules • QA
Drop one line into your debug build and get a complete debugging suite — no Charles Proxy, no separate logging dashboard, no manual environment switching. Just shake or tap the bubble.
Noober.shared.start() // That's it.Using AI to code? Point your AI assistant (Claude, Cursor, Copilot, etc.) to
AI_INTEGRATION.md— a machine-readable reference with exact API signatures, copy-paste integration patterns, and constraints. It's designed so any AI can integrate Noober into your project in seconds.
|
Captures every |
Rewrite URLs to redirect traffic between servers. Mock responses to test edge cases without a backend. Intercept requests mid-flight — inspect, edit, then proceed or cancel. Five match modes: Host, Contains, Prefix, Exact, Regex. All rules persist across launches. |
|
Register your environments once, switch with one tap. Noober rewrites matching requests automatically. Supports multiple base URLs per environment (API + CDN + WebSocket). Active selection persists across launches. |
Define test items with priority and associated endpoints. Mark pass/fail, attach network requests to failures, track progress. Build-aware — auto-resets when a new build is detected. Share reports. |
|
Browse and edit UserDefaults with type-aware parsing. View Keychain items with lazy-loaded values. Export UserDefaults as JSON. See app info at a glance. |
Structured logs with four levels ( |
|
Test any URL scheme or universal link without leaving the app. Input a URL, tap Fire, see if it opened or failed. Save favorites for reuse. Full history with result badges, timestamps, and persistence across launches. |
Zero dependencies — pure Swift, no third-party libraries. One-line setup — |
Xcode → File → Add Package Dependencies:
https://github.com/noob-programmer1/Noober-iOS.git
Package.swift:
dependencies: [
.package(url: "https://github.com/noob-programmer1/Noober-iOS.git", from: "2.0.0")
],
targets: [
.target(name: "YourApp", dependencies: ["Noober"])
]Warning
Noober is for debugging only. Always wrap with #if DEBUG.
#if DEBUG
import Noober
#endif
@main
struct MyApp: App {
init() {
#if DEBUG
Noober.shared.start()
#endif
}
var body: some Scene {
WindowGroup { ContentView() }
}
}#if DEBUG
import Noober
#endif
@main
struct MyApp: App {
init() {
#if DEBUG
// Switch between servers with one tap
Noober.shared.registerEnvironments([
.init(name: "Production", baseURL: "https://api.example.com"),
.init(name: "Staging", baseURL: "https://api.staging.example.com",
notes: "Uses test payment keys"),
.init(name: "Local", baseURL: "http://localhost:8080"),
])
// QA checklist for the current build
Noober.shared.registerChecklist([
.init("Login flow", notes: "Test email + social",
priority: .high, endpoints: ["/auth/login"]),
.init("Checkout", notes: "With & without saved cards",
priority: .high, endpoints: ["/api/payments"]),
.init("Pull-to-refresh on feed", priority: .normal),
])
Noober.shared.start()
#endif
}
var body: some Scene {
WindowGroup { ContentView() }
}
}Noober.shared.log("User signed in")
Noober.shared.log("Payment failed", level: .error, category: .init("payments"))
Noober.shared.log("Cache miss", level: .debug, category: .init("cache"))Noober — Main singleton
@MainActor
public final class Noober {
public static let shared: Noober
public var isStarted: Bool { get }
public func start()
public func stop()
public func showDebugger()
public func hideDebugger()
public func registerEnvironments(_ environments: [NooberEnvironment])
public func registerChecklist(_ items: [QAChecklistItem])
// Thread-safe — call from any thread
nonisolated public func log(
_ message: String,
level: LogLevel = .info,
category: LogCategory = .general,
file: String = #file,
line: UInt = #line
)
}NooberEnvironment — Server environment definition
public struct NooberEnvironment: Identifiable, Codable, Sendable, Hashable {
public let id: UUID
public let name: String
public let baseURLs: [String]
public let notes: String
// Single base URL
public init(name: String, baseURL: String, notes: String = "")
// Multiple base URLs (positional mapping)
public init(name: String, baseURLs: [String], notes: String = "")
}QAChecklistItem — Test item definition
public struct QAChecklistItem: Sendable {
public let title: String
public let notes: String
public let priority: QAChecklistPriority // .high, .normal, .low
public let endpoints: [String]
public init(
_ title: String,
notes: String = "",
priority: QAChecklistPriority = .normal,
endpoints: [String] = []
)
}LogLevel & LogCategory
public enum LogLevel: String, CaseIterable, Sendable, Comparable {
case debug = "DEBUG"
case info = "INFO"
case warning = "WARN"
case error = "ERROR"
}
public struct LogCategory: RawRepresentable, Hashable, Sendable {
public init(_ rawValue: String)
public static let general: LogCategory
}| Layer | What it does |
|---|---|
| URLProtocol swizzling | Injects NetworkInterceptor into URLSessionConfiguration.default and .ephemeral. Captures all HTTP/HTTPS traffic automatically. |
| WebSocket swizzling | Hooks into URLSessionWebSocketTask to capture sent/received frames, connection status, and close codes. |
| Screen tracking | Swizzles UIViewController.viewDidAppear(_:) to tag each request with the source screen. |
| Rules engine | Evaluates mock → intercept → environment → rewrite rules in order. Mock/intercept short-circuit. Rules persist in UserDefaults. |
| Overlay windows | Bubble lives in a UIWindow at .alert + 1. Debugger at .alert + 2. Custom hit testing passes through non-bubble touches. |
| Thread safety | @MainActor for all stores. nonisolated for logging. os_unfair_lock for screen tracker. NSLock for rule snapshots read by the interceptor. |
Full API docs with guides:
noob-programmer1.github.io/Noober-iOS
Built with Swift-DocC. Source in Sources/Noober/Noober.docc/.
Build docs locally
# Build the DocC archive
xcodebuild docbuild \
-scheme Noober \
-destination 'generic/platform=iOS' \
-derivedDataPath .derivedData
# Transform for static hosting
$(xcrun --find docc) process-archive \
transform-for-static-hosting \
.derivedData/Build/Products/Debug-iphoneos/Noober.doccarchive \
--hosting-base-path Noober-iOS \
--output-path docsDeploy by pushing docs/ to the gh-pages branch. The .nojekyll file in the branch root prevents Jekyll from interfering with DocC's SPA routing.
| Minimum | |
|---|---|
| iOS | 15.0+ |
| Swift | 6.0+ |
| Xcode | 16+ |
| Dependencies | None |
Apache 2.0 — License
Built by Abhishek Agarwal




