Skip to content

Ai Ai Asking

Mr.P edited this page Aug 29, 2026 · 2 revisions

AI Asking

Send a text question to the selected AI provider, correlate callbacks with the returned question identifier, and render either accumulated or incremental answer text.

AI asking request lifecycle

A request may receive its identifier synchronously or through a callback, followed by streamed answer updates and one terminal callback.

  1. Validate Question — Trim the input and reject an empty prompt before creating a request.
  2. Configure Agent — Optionally select the provider-specific agent identifier.
  3. Send Question — Call AIBudsAISDK.send and retain any synchronously returned identifier.
  4. Start Answering — Capture the question identifier when the provider starts answering.
  5. Stream Answer — Prefer fullText when present; otherwise append the deltaText update.
  6. Finish or Fail — Re-enable UI and close request state from the terminal callback.

Prerequisites

  • Initialize AIBudsAISDK, select a registered provider, and complete authentication when required.
  • Confirm that the selected provider implements AIAskingServiceAPI.
  • Dispatch callback-driven UI work to the main queue.

API Reference

Framework

AIBudsAI.xcframework

Import

Swift

import AIBudsAI
import AIBudsAIFoundation

Objective-C

#import <AIBudsAI/AIBudsAI-Swift.h>

Declaration

Swift

/// Sends a text question to the currently selected AI service and receives
/// the answer as a stream of updates.
///
/// - Parameters:
///   - question: The question or prompt to send.
///   - config: Configuration for the request. Defaults to `.default`.
///   - onStartAnswering: Called when the service starts answering. The
///     question identifier may be `nil` if it has not yet been assigned.
///   - onAnswer: Called for each answer update.
///     - questionId: The identifier of the question being answered.
///     - deltaText: Newly generated text in this update, if available.
///     - fullText: The accumulated answer text, if available.
///     - isFinal: `true` when this is the final answer update.
///   - onFinishAnswering: Called when answering finishes successfully.
///   - onError: Called when validation fails or the provider reports an error.
/// - Returns: The question identifier when the request is created; otherwise `nil`.
public static func send(question: String,
                          config: AIAskingConfig = .default,
                onStartAnswering: ((_ questionId: String?) -> Void)? = nil,
                        onAnswer: ((
                            _ questionId: String,
                            _ deltaText: String?,
                            _ fullText: String?,
                            _ isFinal: Bool
                        ) -> Void)? = nil,
               onFinishAnswering: ((_ questionId: String) -> Void)? = nil,
                         onError: ((_ questionId: String, _ error: Error) -> Void)? = nil) -> String?

Objective-C

/// Sends a text question and streams answer updates.
///
/// - Parameters:
///   - question: The question or prompt to send.
///   - config: Configuration for this request.
///   - onStartAnswering: Called when the provider starts answering.
///   - onAnswer: Returns the question ID, delta text, accumulated text, and
///     whether this is the final answer update.
///   - onFinishAnswering: Called when answering finishes successfully.
///   - onError: Called for synchronous validation or provider errors.
/// - Returns: The question identifier when created; otherwise `nil`.
+ (NSString * _Nullable)sendQuestion:(NSString * _Nonnull)question
                              config:(AIBudsAIAskingConfig * _Nonnull)config
                    onStartAnswering:(void (^ _Nullable)(NSString * _Nullable))onStartAnswering
                            onAnswer:(void (^ _Nullable)(NSString * _Nonnull, NSString * _Nullable, NSString * _Nullable, BOOL))onAnswer
                   onFinishAnswering:(void (^ _Nullable)(NSString * _Nonnull))onFinishAnswering
                             onError:(void (^ _Nullable)(NSString * _Nonnull, NSError * _Nonnull))onError;

See send and AIAskingConfig.

Configuration

AIAskingConfig.specifiedAgent is optional and provider-specific. Leave it nil to use the provider's normal agent selection. Do not assume an agent identifier from the Demo is valid for another account or provider.

Usage Examples

The examples follow AIAskingDemoController: they accept either a full accumulated answer or a delta, preserve the latest non-empty question identifier, and separate the final answer update from request completion.

Swift

let question = input.trimmingCharacters(in: .whitespacesAndNewlines)
guard !question.isEmpty else { return }

let config = AIAskingConfig()
config.specifiedAgent = selectedAgentID

var activeQuestionID: String?
var answer = ""

let returnedID = AIBudsAISDK.send(
    question: question,
    config: config,
    onStartAnswering: { questionID in
        DispatchQueue.main.async {
            activeQuestionID = questionID ?? activeQuestionID
        }
    },
    onAnswer: { questionID, deltaText, fullText, isFinal in
        DispatchQueue.main.async {
            activeQuestionID = questionID
            if let fullText {
                answer = fullText
            } else if let deltaText {
                answer += deltaText
            }
            render(answer: answer, isFinalUpdate: isFinal)
        }
    },
    onFinishAnswering: { questionID in
        DispatchQueue.main.async {
            activeQuestionID = questionID
            setAsking(false)
        }
    },
    onError: { questionID, error in
        DispatchQueue.main.async {
            if !questionID.isEmpty { activeQuestionID = questionID }
            setAsking(false)
            show(error)
        }
    }
)

activeQuestionID = returnedID ?? activeQuestionID

Objective-C

NSString *question =
    [self.input stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceAndNewlineCharacterSet];
if (question.length == 0)
    return;

AIBudsAIAskingConfig *config = [[AIBudsAIAskingConfig alloc] init];
config.specifiedAgent = self.selectedAgentID;

__block NSString *activeQuestionID = nil;
__block NSString *answer = @"";

NSString *returnedID = [AIBudsAISDK sendQuestion:question
    config:config
    onStartAnswering:^(NSString *questionID) {
        dispatch_async(dispatch_get_main_queue(), ^{
            activeQuestionID = questionID ?: activeQuestionID;
        });
    }
    onAnswer:^(NSString *questionID, NSString *deltaText, NSString *fullText, BOOL isFinal) {
        dispatch_async(dispatch_get_main_queue(), ^{
            activeQuestionID = questionID;
            answer = fullText ?: [answer stringByAppendingString:deltaText ?: @""];
            [self renderAnswer:answer isFinalUpdate:isFinal];
        });
    }
    onFinishAnswering:^(NSString *questionID) {
        dispatch_async(dispatch_get_main_queue(), ^{
            activeQuestionID = questionID;
            [self setAsking:NO];
        });
    }
    onError:^(NSString *questionID, NSError *error) {
        dispatch_async(dispatch_get_main_queue(), ^{
            if (questionID.length > 0)
                activeQuestionID = questionID;
            [self setAsking:NO];
            [self showError:error];
        });
    }];

activeQuestionID = returnedID ?: activeQuestionID;

Error Handling

send can return nil and invoke onError synchronously when validation fails before a request is created. In that case the error callback's question identifier is empty. Disable duplicate submission while a request is active and restore UI state from both terminal callbacks.

Notes

  • isFinal marks the last streamed answer update; use onFinishAnswering as successful request completion.
  • A provider can supply fullText, deltaText, or both. Prefer fullText to avoid duplicating accumulated text.
  • The public API does not currently expose a cancellation method for an active asking request.

AIBuds SDK iOS Wiki

Clone this wiki locally