-
Notifications
You must be signed in to change notification settings - Fork 0
Ai 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.
- Validate Question — Trim the input and reject an empty prompt before creating a request.
- Configure Agent — Optionally select the provider-specific agent identifier.
- Send Question — Call AIBudsAISDK.send and retain any synchronously returned identifier.
- Start Answering — Capture the question identifier when the provider starts answering.
- Stream Answer — Prefer fullText when present; otherwise append the deltaText update.
- Finish or Fail — Re-enable UI and close request state from the terminal callback.
- 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.
AIBudsAI.xcframework
import AIBudsAI
import AIBudsAIFoundation#import <AIBudsAI/AIBudsAI-Swift.h>/// 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?/// 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.
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.
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.
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 ?? activeQuestionIDNSString *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;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.
-
isFinalmarks the last streamed answer update; useonFinishAnsweringas successful request completion. - A provider can supply
fullText,deltaText, or both. PreferfullTextto avoid duplicating accumulated text. - The public API does not currently expose a cancellation method for an active asking request.
AIBuds SDK documentation · Full documentation · API Reference
- Introduction
- Getting Started
- Core Concepts
-
Core Features
- Basic Features
- Device Info
- Find Device
- Physical Operations
- Work Mode
- Work Status
- Wear Detection
- Volume Control
- Music Control
- TWS
- Equalizer
- ANC
- Audio
- Camera
- Remote Camera
- File Import
- Teleprompter
- Segment Navigation
- Live Streaming
- Device Applications
- OTA
- Camera OTA
- Service Auth
- AI Services
- Voice Assistant
- Logging
- Advanced Topics
- Releases
- Troubleshooting