Skip to content

1.46.0 Release#1129

Merged
github-actions[bot] merged 27 commits intomainfrom
release/1.46.0
Apr 21, 2026
Merged

1.46.0 Release#1129
github-actions[bot] merged 27 commits intomainfrom
release/1.46.0

Conversation

@Stream-SDK-Bot
Copy link
Copy Markdown
Collaborator

🔄 Changed

  • Added optional leave reasons to Call.leave and CallViewModel.hangUp, and propagated them through the WebRTC leave flow so SFU leave requests include explicit end-of-call context. #1100
  • Added an optional join interception hook so apps can delay or abort call entry after the join response is applied locally. #1108
  • Exposed participantAutoLeavePolicy on CallKitAdapter and CallKitService so CallKit flows can share the same auto-leave rules as CallViewModel.

🐞 Fixed

  • Prevent abrupt call endings caused by audio-session readiness timing. #1098
  • Prevent repeated screen-sharing permission prompts on reconnection after screen capture is denied. #1102
  • Prevent hanging up while a call is still joining from briefly showing the in-call UI after the join finishes in the background. #1101
  • Delay microphone and camera permission prompts until the app is in the foreground and the WebRTC join has completed. #1103
  • Prevent outgoing ringing time from being counted toward call duration. #1106
  • Replay buffered subscriber ICE trickles during join so remote audio does not wait for a later subscriber ICE restart before becoming audible. #1111
  • Fix join-call timeout caused by a PassthroughSubject race where the response was emitted before the subscription was established. #1113
  • CallKit-managed calls now respect the configured participantAutoLeavePolicy. #1112
  • Prevent CallViewModel from entering .inCall from participant updates before the call is ready, while preserving the CallKit join handoff to .inCall. #1109
  • Handle CallKit ringing edge cases by ending already-handled incoming calls with explicit leave reasons when they were answered, rejected, missed, or ended elsewhere. #1115

Stream Bot and others added 27 commits April 1, 2026 15:01
@Stream-SDK-Bot Stream-SDK-Bot requested a review from a team as a code owner April 20, 2026 21:25
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 20, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 797506ad-2370-4214-b695-bcea7482dffa

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch release/1.46.0

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown

1 Warning
⚠️ Big PR

Generated by 🚫 Danger

@github-actions
Copy link
Copy Markdown

Public Interface

+ public extension RejectionReasonProviding

+ public final class CallJoinInterceptionError: ClientError, @unchecked Sendable

+ public protocol CallJoinIntercepting: Sendable



 public class Call: @unchecked Sendable, WSEventsSubscriber  
-   @discardableResult public func join(create: Bool = false,options: CreateCallOptions? = nil,ring: Bool = false,notify: Bool = false,callSettings: CallSettings? = nil,policy: WebRTCJoinPolicy = .default)async throws -> JoinCallResponse
+   @discardableResult public func join(create: Bool = false,options: CreateCallOptions? = nil,ring: Bool = false,notify: Bool = false,callSettings: CallSettings? = nil,policy: WebRTCJoinPolicy = .default,joinInterceptor: CallJoinIntercepting? = nil)async throws -> JoinCallResponse
-   public func leave()
+   public func leave(reason: String? = nil)

 @MainActor open class CallViewModel: ObservableObject  
-   public var participants: [CallParticipant]
+   public var callJoinInterceptor: CallJoinIntercepting?
-   public var participantAutoLeavePolicy: ParticipantAutoLeavePolicy
+   public var participants: [CallParticipant]
-   
+   public var participantAutoLeavePolicy: ParticipantAutoLeavePolicy
- 
+   
-   public init(participantsLayout: ParticipantsLayout = .grid,callSettings: CallSettings? = nil)
+ 
-   
+   public init(participantsLayout: ParticipantsLayout = .grid,callSettings: CallSettings? = nil)
- 
+   
-   public func toggleCameraEnabled()
+ 
-   public func toggleMicrophoneEnabled()
+   public func toggleCameraEnabled()
-   public func toggleCameraPosition()
+   public func toggleMicrophoneEnabled()
-   public func toggleAudioOutput()
+   public func toggleCameraPosition()
-   public func toggleSpeaker()
+   public func toggleAudioOutput()
-   public func startCall(callType: String,callId: String,members: [Member],team: String? = nil,ring: Bool = false,maxDuration: Int? = nil,maxParticipants: Int? = nil,startsAt: Date? = nil,backstage: BackstageSettingsRequest? = nil,customData: [String: RawJSON]? = nil,video: Bool? = nil)
+   public func toggleSpeaker()
-   public func joinCall(callType: String,callId: String,customData: [String: RawJSON]? = nil)
+   public func startCall(callType: String,callId: String,members: [Member],team: String? = nil,ring: Bool = false,maxDuration: Int? = nil,maxParticipants: Int? = nil,startsAt: Date? = nil,backstage: BackstageSettingsRequest? = nil,customData: [String: RawJSON]? = nil,video: Bool? = nil)
-   public func joinAndRingCall(callType: String,callId: String,members: [Member],team: String? = nil,maxDuration: Int? = nil,maxParticipants: Int? = nil,startsAt: Date? = nil,customData: [String: RawJSON]? = nil,video: Bool? = nil)
+   public func joinCall(callType: String,callId: String,customData: [String: RawJSON]? = nil)
-   public func enterLobby(callType: String,callId: String,members: [Member])
+   public func joinAndRingCall(callType: String,callId: String,members: [Member],team: String? = nil,maxDuration: Int? = nil,maxParticipants: Int? = nil,startsAt: Date? = nil,customData: [String: RawJSON]? = nil,video: Bool? = nil)
-   public func acceptCall(callType: String,callId: String,customData: [String: RawJSON]? = nil)
+   public func enterLobby(callType: String,callId: String,members: [Member])
-   public func rejectCall(callType: String,callId: String)
+   public func acceptCall(callType: String,callId: String,customData: [String: RawJSON]? = nil)
-   public func changeTrackVisibility(for participant: CallParticipant,isVisible: Bool)
+   public func rejectCall(callType: String,callId: String)
-   public func updateTrackSize(_ trackSize: CGSize,for participant: CallParticipant)
+   public func changeTrackVisibility(for participant: CallParticipant,isVisible: Bool)
-   public func startScreensharing(type: ScreensharingType,includeAudio: Bool = true)
+   public func updateTrackSize(_ trackSize: CGSize,for participant: CallParticipant)
-   public func stopScreensharing()
+   public func startScreensharing(type: ScreensharingType,includeAudio: Bool = true)
-   public func hangUp()
+   public func stopScreensharing()
-   public func setVideoFilter(_ videoFilter: VideoFilter?)
+   public func hangUp(reason: String? = nil)
-   public func update(participantsLayout: ParticipantsLayout)
+   public func setVideoFilter(_ videoFilter: VideoFilter?)
-   public func setActiveCall(_ call: Call?,file: StaticString = #file,function: StaticString = #function,line: UInt = #line)
+   public func update(participantsLayout: ParticipantsLayout)
-   public func update(participantsSortComparators: [StreamSortComparator<CallParticipant>])
+   public func setActiveCall(_ call: Call?,file: StaticString = #file,function: StaticString = #function,line: UInt = #line)
+   public func update(participantsSortComparators: [StreamSortComparator<CallParticipant>])

 open class CallKitService: NSObject, CXProviderDelegate, @unchecked Sendable  
-   open internal lazy var callController
+   open var participantAutoLeavePolicy: ParticipantAutoLeavePolicy
-   open internal lazy var callProvider
+   open internal lazy var callController
-   
+   open internal lazy var callProvider
- 
+   
-   override public init()
+ 
-   
+   override public init()
- 
+   
-   open func reportIncomingCall(_ cid: String,localizedCallerName: String,callerId: String,hasVideo: Bool = false,completion: @Sendable @escaping (Error?) -> Void)
+ 
-   open func callAccepted(_ response: CallAcceptedEvent)
+   open func reportIncomingCall(_ cid: String,localizedCallerName: String,callerId: String,hasVideo: Bool = false,completion: @Sendable @escaping (Error?) -> Void)
-   open func callRejected(_ response: CallRejectedEvent)
+   open func callAccepted(_ response: CallAcceptedEvent)
-   open func callEnded(_ cId: String,ringingTimedOut: Bool)
+   open func callRejected(_ response: CallRejectedEvent)
-   open func callParticipantLeft(_ response: CallSessionParticipantLeftEvent)
+   open func callEnded(_ cId: String,ringingTimedOut: Bool,leaveReason: String? = nil)
-   open func providerDidReset(_ provider: CXProvider)
+   open func callParticipantLeft(_ response: CallSessionParticipantLeftEvent)
-   open func provider(_ provider: CXProvider,didActivate audioSession: AVAudioSession)
+   open func providerDidReset(_ provider: CXProvider)
-   public func provider(_ provider: CXProvider,didDeactivate audioSession: AVAudioSession)
+   open func provider(_ provider: CXProvider,didActivate audioSession: AVAudioSession)
-   open func provider(_ provider: CXProvider,perform action: CXAnswerCallAction)
+   public func provider(_ provider: CXProvider,didDeactivate audioSession: AVAudioSession)
-   open func provider(_ provider: CXProvider,perform action: CXEndCallAction)
+   open func provider(_ provider: CXProvider,perform action: CXAnswerCallAction)
-   open func provider(_ provider: CXProvider,perform action: CXSetMutedCallAction)
+   open func provider(_ provider: CXProvider,perform action: CXEndCallAction)
-   open func requestTransaction(_ action: CXAction)async throws 
+   open func provider(_ provider: CXProvider,perform action: CXSetMutedCallAction)
-   open func checkIfCallWasHandled(callState: GetCallResponse)-> Bool
+   open func requestTransaction(_ action: CXAction)async throws 
-   open func setUpRingingTimer(for callState: GetCallResponse)
+   open func checkIfCallWasHandled(callState: GetCallResponse)-> String?
-   open func didUpdate(_ streamVideo: StreamVideo?)
+   open func setUpRingingTimer(for callState: GetCallResponse)
-   
+   open func didUpdate(_ streamVideo: StreamVideo?)
- 
+   
-   public enum Event  
+ 
-   
+   public enum Event  
-     case idle
+   
-     case accept
+     case idle
-     case joining(Call)
+     case accept
-     case joined
+     case joining(Call)
-     case reject
+     case joined
+     case reject

 public struct CallDurationView: View  
-   @MainActor public init(_ viewModel: CallViewModel)
+   public init(_ viewModel: CallViewModel,showRingingDuration: Bool = true)

 open class CallKitAdapter  
-   public var availabilityPolicy: CallKitAvailabilityPolicy
+   open var participantAutoLeavePolicy: ParticipantAutoLeavePolicy
-   public var streamVideo: StreamVideo?
+   public var availabilityPolicy: CallKitAvailabilityPolicy
-   
+   public var streamVideo: StreamVideo?
- 
+   
-   public init()
+ 
-   
+   public init()
- 
+   
-   open func registerForIncomingCalls()
+ 
-   open func unregisterForIncomingCalls()
+   open func registerForIncomingCalls()
+   open func unregisterForIncomingCalls()

- public enum CallRecordingType: String  
+ public enum CallRecordingType: String, Sendable  

@Stream-SDK-Bot
Copy link
Copy Markdown
Collaborator Author

SDK Size

title previous release current release diff status
StreamVideo 10.24 MB 10.24 MB +1 KB 🟢
StreamVideoSwiftUI 2.47 MB 2.47 MB 0 KB 🟢
StreamVideoUIKit 2.6 MB 2.6 MB 0 KB 🟢
StreamWebRTC 11.09 MB 11.09 MB 0 KB 🟢

@github-actions
Copy link
Copy Markdown

Build for regression testing №334 has been uploaded to TestFlight 🎁

@Stream-SDK-Bot
Copy link
Copy Markdown
Collaborator Author

StreamVideo XCSize

Object Diff (bytes)
Call.o +3712
StreamVideo.o +2480
Publisher+AsyncStream.o +1888
WebRTCCoordinator+Joining.o +1136
WebRTCAuthenticator.o +1048
Show 8 more objects
Object Diff (bytes)
WebRTCCoordinator+PeerConnectionPreparing.o +796
CallKitService.o +584
WebRTCMigrationStatusObserver.o +548
RTCPeerConnectionCoordinator.o +484
Task+Timeout.o -139
Call+JoiningStage.o -100
OperationQueue+TaskOperations.o -68
Call+Stage.o +42

@sonarqubecloud
Copy link
Copy Markdown

@ipavlidakis
Copy link
Copy Markdown
Contributor

/merge release

@testableapple
Copy link
Copy Markdown
Contributor

Publication of the release has been launched 👍

@github-actions github-actions Bot merged commit 4be15a9 into main Apr 21, 2026
15 checks passed
@github-actions github-actions Bot deleted the release/1.46.0 branch April 21, 2026 08:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants