You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

语音指令解析与定时器触发方案咨询及代码优化需求

Hey Mike, sorry to hear you’ve been stuck on this for 3 months—let’s break this down step by step to fix your parsing issues, validate commands properly, and outline a solid architecture for your voice analysis system.

Fixing Your Core Parsing Logic

Your current regex and parsing code has a few gaps: it only catches numeric minutes, mishandles Swift string ranges, and cleans task content too rigidly. Let’s rewrite and improve it.

1. Support Both Numeric and Text-Based Time Values

First, create a mapping for text-based numbers to integers, then expand your regex to match both numeric and text minute values:

private let textNumberToInt: [String: Int] = [
    "one": 1, "two": 2, "three": 3, "four": 4, "five": 5,
    "six": 6, "seven": 7, "eight": 8, "nine": 9, "ten": 10
]

2. Fix Range Handling & Regex Matching

NSRegularExpression uses UTF-16 ranges, but your original code used UTF-8 counts—this causes crashes with multi-byte characters. We’ll safely convert NSRange to Swift String ranges and extract time values correctly.

3. Clean Task Content Intelligently

Instead of hardcoding a range to remove "to", we’ll strip the matched time string, trim whitespace, and handle optional leading "to " gracefully.

Revised Parsing Function

var timeValue: Int = 0
var taskValue: String = ""

private let textNumberToInt: [String: Int] = [
    "one": 1, "two": 2, "three": 3, "four": 4, "five": 5,
    "six": 6, "seven": 7, "eight": 8, "nine": 9, "ten": 10
]

func parseVoiceCommand(_ inputText: String) -> (Int?, String?) {
    // Regex to match either numeric (e.g., "20 minutes") or text-based (e.g., "five minutes") time values
    let pattern = "(\\d+|one|two|three|four|five|six|seven|eight|nine|ten)\\s+minute(s)?"
    guard let regex = try? NSRegularExpression(pattern: pattern, options: .caseInsensitive) else {
        print("Invalid regex pattern")
        return (nil, nil)
    }
    
    let fullRange = NSRange(inputText.startIndex..., in: inputText)
    guard let match = regex.firstMatch(in: inputText, options: [], range: fullRange) else {
        print("No valid time match found")
        return (nil, nil)
    }
    
    // Extract time string and convert to Int
    let timeMatchRange = Range(match.range(at: 1), in: inputText)!
    let timeString = String(inputText[timeMatchRange]).lowercased()
    let extractedTime: Int?
    
    if let numericTime = Int(timeString) {
        extractedTime = numericTime
    } else {
        extractedTime = textNumberToInt[timeString]
    }
    
    // Clean task content: remove the matched time string, trim whitespace, remove leading "to " if present
    let cleanedTask = inputText.replacingCharacters(in: Range(match.range, in: inputText)!, with: "")
        .trimmingCharacters(in: .whitespacesAndNewlines)
        .replacingOccurrences(of: "^to\\s+", with: "", options: .regularExpression)
    
    // Update global variables (optional—you might prefer to use the returned tuple instead)
    if let time = extractedTime {
        timeValue = time
    }
    taskValue = cleanedTask
    
    return (extractedTime, cleanedTask)
}
Command Validation

Before triggering a timer, add checks to ensure the command is valid:

  • Ensure extractedTime is greater than 0 (no zero or negative timers)
  • Ensure cleanedTask isn’t empty (avoid timers with no task description)

Example validation logic:

func validateAndTriggerTimer(from inputText: String) {
    guard let (time, task) = parseVoiceCommand(inputText),
          time > 0,
          !task.isEmpty else {
        print("Invalid command: please provide a valid positive time and task")
        return
    }
    
    // Trigger timer here
    startTimer(with: time, task: task)
}
Timer Trigger Logic

For reliable timer execution, use either Timer (for UI-related timers) or DispatchQueue (for background tasks). Here’s a safe implementation:

func startTimer(with minutes: Int, task: String) {
    let seconds = TimeInterval(minutes * 60)
    
    // Use DispatchQueue for background-safe execution
    DispatchQueue.global().asyncAfter(deadline: .now() + seconds) { [weak self] in
        // Trigger your task completion action (e.g., show a notification)
        self?.handleTimerCompletion(task: task)
    }
    
    // Optional: Update UI to show active timer
    DispatchQueue.main.async {
        print("Timer started: \(minutes) minutes for task: \(task)")
    }
}

func handleTimerCompletion(task: String) {
    DispatchQueue.main.async {
        // Show local notification or alert
        print("Timer finished! Task: \(task)")
        // Example: Trigger a local notification
        let content = UNMutableNotificationContent()
        content.title = "Timer Complete"
        content.body = "Time to \(task)"
        let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: nil)
        UNUserNotificationCenter.current().add(request)
    }
}
Voice Analysis System Architecture Suggestions

For a scalable system beyond basic regex parsing, use a layered architecture:

  • Speech-to-Text Layer: Use Apple’s Speech framework to handle voice transcription (it’s built-in and optimized for iOS/macOS)
  • Semantic Parsing Layer:
    • For simple commands: Use regex as we did, but expand patterns to support more variations (e.g., "set a timer for X minutes to Y", "remind me in X minutes about Y")
    • For complex commands: Use Apple’s NLProcessing framework (iOS 15+) to perform entity recognition (identify time values) and intent classification (determine the user wants a timer)
  • Task Scheduler Layer: Manage active timers, persist tasks to UserDefaults or Core Data, and handle pause/cancel actions
  • Execution Layer: Trigger notifications, UI updates, or other actions when timers complete

This layered approach makes it easier to add features (like supporting hours, days, or different command types) without rewriting core logic.


内容的提问来源于stack exchange,提问作者MikeMaus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 11:47:45