Skip to content

Instantly share code, notes, and snippets.

@KunalKumarSwift
Created May 14, 2025 03:02
Show Gist options
  • Save KunalKumarSwift/7e58c5848b16f634abcaeae19506c278 to your computer and use it in GitHub Desktop.
Save KunalKumarSwift/7e58c5848b16f634abcaeae19506c278 to your computer and use it in GitHub Desktop.
import SwiftUI
@main
struct MyApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
MockFilenameGeneratorView()
}
}
}
import SwiftUI
struct MockFilenameGeneratorView: View {
@StateObject var viewModel = MockFilenameViewModel()
let httpMethods = ["GET", "POST", "PUT", "PATCH", "DELETE"]
var body: some View {
if isMac {
VStack {
formContent
.padding()
.frame(minWidth: 600, minHeight: 400)
}
}
else {
NavigationView {
formContent
.navigationTitle("Mock Filename Tool")
}
}
}
private var formContent: some View {
Form {
Section(header: Text("Request Info")) {
Picker("HTTP Method", selection: $viewModel.methodInput) {
ForEach(httpMethods, id: \.self) { method in
Text(method)
}
}
.pickerStyle(SegmentedPickerStyle())
TextField("Request URL", text: $viewModel.urlInput)
#if os(iOS)
.keyboardType(.URL)
.autocorrectionDisabled()
#endif
TextEditor(text: $viewModel.jsonBodyInput)
.frame(height: 100)
.overlay(RoundedRectangle(cornerRadius: 5).stroke(Color.gray.opacity(0.4)))
.padding(.top, 4)
}
Button("Generate Filename") {
viewModel.generateFilename()
}
Section(header: Text("Generated Filename")) {
Text(viewModel.filenameOutput)
.font(.system(.body, design: .monospaced))
.padding(.vertical, 4)
.contextMenu {
Button("Copy") {
copyToClipboard(viewModel.filenameOutput)
}
}
}
}
}
}
import SwiftUI
import Foundation
class MockFilenameViewModel: ObservableObject {
@Published var urlInput: String = ""
@Published var methodInput: String = "GET"
@Published var jsonBodyInput: String = ""
@Published var filenameOutput: String = ""
func generateFilename() {
guard let url = URL(string: urlInput) else {
filenameOutput = "Invalid URL"
return
}
let method = methodInput.uppercased()
let pathComponent = processPathSegments(url: url)
let paramString = parameterString(from: url, jsonString: jsonBodyInput)
let fullName = [
method,
pathComponent,
paramString
]
.filter { !$0.isEmpty }
.joined(separator: "_")
filenameOutput = "\(fullName).json"
}
/// Process path segments like /users/123/orders/uuid
private func processPathSegments(url: URL) -> String {
let segments = url.pathComponents.filter { $0 != "/" && !$0.isEmpty }
return segments.map { segment in
// Check if it's a keyword or a typed token
if isLikelyTypeToken(segment) {
return typeToken(for: segment)
} else {
return segment
}
}.joined(separator: "_")
}
/// Determine whether a segment looks like a dynamic token (e.g., int, uuid, etc.)
private func isLikelyTypeToken(_ segment: String) -> Bool {
// Check if it's a known type like int, uuid, etc.
// You could also add heuristics (e.g., numbers are often IDs)
return typeToken(for: segment) != "{string}"
}
private func parameterString(from url: URL, jsonString: String) -> String {
var allParams: [(String, String)] = []
// Query parameters
if let items = URLComponents(url: url, resolvingAgainstBaseURL: false)?.queryItems {
for item in items {
if let value = item.value {
allParams.append((item.name, typeToken(for: value)))
}
}
}
// JSON Body parameters
if let data = jsonBodyInput.data(using: .utf8),
let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any] {
for (key, value) in json {
allParams.append((key, typeToken(for: "\(value)")))
}
}
return allParams
.sorted { $0.0 < $1.0 }
.map { "\($0)=\($1)" }
.joined(separator: "_")
}
private func typeToken(for value: String) -> String {
let trimmed = value.trimmingCharacters(in: .whitespacesAndNewlines)
let uuidPattern = #"^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$"#
let intPattern = #"^-?\d+$"#
let doublePattern = #"^-?\d*\.\d+$"#
let boolPattern = #"^(true|false)$"#
if matches(pattern: uuidPattern, in: trimmed) {
return "{uuid}"
} else if matches(pattern: intPattern, in: trimmed) {
return "{int}"
} else if matches(pattern: doublePattern, in: trimmed) {
return "{double}"
} else if matches(pattern: boolPattern, in: trimmed.lowercased()) {
return "{bool}"
} else {
return "{string}"
}
}
private func matches(pattern: String, in text: String) -> Bool {
let regex = try? NSRegularExpression(pattern: pattern, options: [])
let range = NSRange(text.startIndex..<text.endIndex, in: text)
return regex?.firstMatch(in: text, options: [], range: range) != nil
}
}
import Foundation
var isMac: Bool {
#if targetEnvironment(macCatalyst)
return true
#else
return ProcessInfo.processInfo.isMacCatalystApp || ProcessInfo.processInfo.operatingSystemVersionString.contains("macOS")
#endif
}
import SwiftUI
func copyToClipboard(_ text: String) {
#if canImport(UIKit)
// iOS + Mac Catalyst
UIPasteboard.general.string = text
#elseif canImport(AppKit)
// macOS only
let pasteboard = NSPasteboard.general
pasteboard.clearContents()
pasteboard.setString(text, forType: .string)
#endif
}
func matches(pattern: String, in value: String) -> Bool {
// 1. Compile the regex pattern with case-insensitive matching
let regex = try? NSRegularExpression(pattern: pattern, options: [.caseInsensitive])
// 2. Convert the input string to an NSRange covering the full string
let range = NSRange(location: 0, length: value.utf16.count)
// 3. Use the regex to search for a match in the string
return regex?.firstMatch(in: value, options: [], range: range) != nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment