Skip to content

Commit 0507721

Browse files
Fix the Swift translations in the AIT guides
Translated using the translate-examples-to-swift skill in the as-yet-unmerged PR #3192. I've reviewed them.
1 parent de2bf59 commit 0507721

2 files changed

Lines changed: 137 additions & 72 deletions

File tree

src/pages/docs/guides/ai-transport/anthropic-message-per-response.mdx

Lines changed: 87 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,14 @@ await channel.subscribe((message) => {
628628
console.log('Subscriber ready, waiting for tokens...');
629629
```
630630

631+
{/* Swift example test harness
632+
ID: anthropic-message-per-response-1
633+
To verify: copy this comment into a Swift file, paste the example code into the function body, run `swift build`
634+
635+
@MainActor
636+
func example_anthropic_message_per_response_1() async throws {
637+
// --- example code starts here ---
638+
*/}
631639
```client_swift
632640
import Ably
633641
@@ -640,37 +648,48 @@ let channel = realtime.channels.get("ai:{{RANDOM_CHANNEL_NAME}}")
640648
// Track responses by message serial
641649
var responses: [String: String] = [:]
642650
643-
// Subscribe to receive messages
644-
channel.subscribe { message in
645-
guard let serial = message.serial else { return }
646-
647-
switch message.action {
648-
case .create:
649-
// New response started
650-
print("\n[Response started] \(serial)")
651-
responses[serial] = message.data as? String ?? ""
652-
653-
case .messageAppend:
654-
// Append token to existing response
655-
let current = responses[serial] ?? ""
656-
let token = message.data as? String ?? ""
657-
responses[serial] = current + token
658-
659-
// Display token as it arrives
660-
print(token, terminator: "")
661-
662-
case .update:
663-
// Replace entire response content
664-
responses[serial] = message.data as? String ?? ""
665-
print("\n[Response updated with full content]")
666-
667-
default:
668-
break
669-
}
651+
// Subscribe to receive messages and wait for the channel to attach
652+
try await withCheckedThrowingContinuation { (continuation: CheckedContinuation<Void, any Error>) in
653+
channel.subscribe(attachCallback: { error in
654+
if let error {
655+
continuation.resume(throwing: error)
656+
} else {
657+
continuation.resume()
658+
}
659+
}, callback: { message in
660+
MainActor.assumeIsolated {
661+
guard let serial = message.serial else { return }
662+
guard let data = message.data as? String else { return }
663+
664+
switch message.action {
665+
case .create:
666+
// New response started
667+
print("\n[Response started] \(serial)")
668+
responses[serial] = data
669+
670+
case .append:
671+
// Append token to existing response
672+
let current = responses[serial] ?? ""
673+
responses[serial] = current + data
674+
675+
// Display token as it arrives
676+
print(data, terminator: "")
677+
678+
case .update:
679+
// Replace entire response content
680+
responses[serial] = data
681+
print("\n[Response updated with full content]")
682+
683+
default:
684+
break
685+
}
686+
}
687+
})
670688
}
671689
672690
print("Subscriber ready, waiting for tokens...")
673691
```
692+
{/* --- end example code --- */}
674693

675694
```client_java
676695
import io.ably.lib.realtime.AblyRealtime;
@@ -909,6 +928,14 @@ await channel.subscribe((message) => {
909928
});
910929
```
911930

931+
{/* Swift example test harness
932+
ID: anthropic-message-per-response-2
933+
To verify: copy this comment into a Swift file, paste the example code into the function body, run `swift build`
934+
935+
@MainActor
936+
func example_anthropic_message_per_response_2(realtime: ARTRealtime) async throws {
937+
// --- example code starts here ---
938+
*/}
912939
```client_swift
913940
// Use rewind to receive recent historical messages
914941
let channelOptions = ARTRealtimeChannelOptions()
@@ -918,29 +945,41 @@ let channel = realtime.channels.get("ai:{{RANDOM_CHANNEL_NAME}}", options: chann
918945
919946
var responses: [String: String] = [:]
920947
921-
channel.subscribe { message in
922-
guard let serial = message.serial else { return }
923-
924-
switch message.action {
925-
case .create:
926-
responses[serial] = message.data as? String ?? ""
927-
928-
case .messageAppend:
929-
let current = responses[serial] ?? ""
930-
let token = message.data as? String ?? ""
931-
responses[serial] = current + token
932-
print(token, terminator: "")
933-
934-
case .update:
935-
// Historical messages contain full concatenated response
936-
responses[serial] = message.data as? String ?? ""
937-
print("\n[Historical response]: \(responses[serial] ?? "")")
938-
939-
default:
940-
break
941-
}
948+
// Subscribe and wait for the channel to attach
949+
try await withCheckedThrowingContinuation { (continuation: CheckedContinuation<Void, any Error>) in
950+
channel.subscribe(attachCallback: { error in
951+
if let error {
952+
continuation.resume(throwing: error)
953+
} else {
954+
continuation.resume()
955+
}
956+
}, callback: { message in
957+
MainActor.assumeIsolated {
958+
guard let serial = message.serial else { return }
959+
guard let data = message.data as? String else { return }
960+
961+
switch message.action {
962+
case .create:
963+
responses[serial] = data
964+
965+
case .append:
966+
let current = responses[serial] ?? ""
967+
responses[serial] = current + data
968+
print(data, terminator: "")
969+
970+
case .update:
971+
// Historical messages contain full concatenated response
972+
responses[serial] = data
973+
print("\n[Historical response]: \(responses[serial] ?? "")")
974+
975+
default:
976+
break
977+
}
978+
}
979+
})
942980
}
943981
```
982+
{/* --- end example code --- */}
944983

945984
```client_java
946985
import io.ably.lib.realtime.AblyRealtime;

src/pages/docs/guides/ai-transport/anthropic-message-per-token.mdx

Lines changed: 50 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,14 @@ await channel.subscribe('stop', (message) => {
613613
console.log('Subscriber ready, waiting for tokens...');
614614
```
615615

616+
{/* Swift example test harness
617+
ID: anthropic-message-per-token-1
618+
To verify: copy this comment into a Swift file, paste the example code into the function body, run `swift build`
619+
620+
@MainActor
621+
func example_anthropic_message_per_token_1() async throws {
622+
// --- example code starts here ---
623+
*/}
616624
```client_swift
617625
import Ably
618626
@@ -625,34 +633,52 @@ let channel = realtime.channels.get("{{RANDOM_CHANNEL_NAME}}")
625633
// Track responses by ID
626634
var responses: [String: String] = [:]
627635
628-
// Handle response start
629-
channel.subscribe("start") { message in
630-
guard let responseId = message.extras?.headers?["responseId"] as? String else { return }
631-
print("\n[Response started] \(responseId)")
632-
responses[responseId] = ""
633-
}
634-
635-
// Handle tokens
636-
channel.subscribe("token") { message in
637-
guard let responseId = message.extras?.headers?["responseId"] as? String,
638-
let token = message.data as? String else { return }
639-
640-
// Append token to response
641-
responses[responseId, default: ""] += token
642-
643-
// Display token as it arrives
644-
print(token, terminator: "")
645-
}
646-
647-
// Handle response stop
648-
channel.subscribe("stop") { message in
649-
guard let responseId = message.extras?.headers?["responseId"] as? String else { return }
650-
let finalText = responses[responseId] ?? ""
651-
print("\n[Response completed] \(responseId)")
636+
// Subscribe to all events and handle by message name
637+
try await withCheckedThrowingContinuation { (continuation: CheckedContinuation<Void, any Error>) in
638+
channel.subscribe(attachCallback: { error in
639+
if let error {
640+
continuation.resume(throwing: error)
641+
} else {
642+
continuation.resume()
643+
}
644+
}) { message in
645+
MainActor.assumeIsolated {
646+
guard let extras = (try? message.extras?.toJSON()) as? [String: Any],
647+
let headers = extras["headers"] as? [String: Any],
648+
let responseID = headers["responseId"] as? String else { return }
649+
650+
switch message.name {
651+
case "start":
652+
// Handle response start
653+
print("\n[Response started] \(responseID)")
654+
responses[responseID] = ""
655+
656+
case "token":
657+
// Handle tokens
658+
guard let token = message.data as? String else { return }
659+
660+
// Append token to response
661+
let currentText = responses[responseID] ?? ""
662+
responses[responseID] = currentText + token
663+
664+
// Display token as it arrives
665+
print(token, terminator: "")
666+
667+
case "stop":
668+
// Handle response stop
669+
let finalText = responses[responseID]
670+
print("\n[Response completed] \(responseID)")
671+
672+
default:
673+
break
674+
}
675+
}
676+
}
652677
}
653678
654679
print("Subscriber ready, waiting for tokens...")
655680
```
681+
{/* --- end example code --- */}
656682

657683
```client_java
658684
import io.ably.lib.realtime.AblyRealtime;

0 commit comments

Comments
 (0)