makeStream: мост от коллбэка в три строки 😎
🔥 SE-0388 (Swift 5.9) отдаёт стрим и его continuation одним вызовом — больше не нужно вытаскивать continuation из замыкания инициализатора через implicitly unwrapped optional. Приятная деталь: оно бэкдеплоится. Аннотации @available(SwiftStdlib 5.1) + @backDeployed(before: 5.9), то есть нужен компилятор 5.9, а работает от iOS 13 / macOS 10.15.
⚠️ А вот finish() — не опциональная вежливость. Continuation это структура, у неё нет deinit; автоматическая терминация висит на deinit самого AsyncStream. Значит, если потребитель итерируется — а он тем самым держит стрим живым, — и ваш объект умирает, просто выбросив continuation, последовательность не завершится и его await повиснет навсегда. Вызывайте finish() в deinit. Ещё две мелочи: деструктуризация кортежа в два let-свойства легальна в классе, но в структуре компилятор откажет («binding multiple 'let' stored properties from a single initializer expression in a struct is unsupported»). И Continuation конформит Sendable безусловно, а вот сам AsyncStream — только @unchecked Sendable where Element: Sendable.
#Swift #SwiftConcurrency #AsyncSequence #iOSDevelopment #AsyncAwait