Skip to content

1.22.0 Release #797

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 21 commits into from
May 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
4c6086e
Add snapshot postfix to v1.21.1
testableapple Apr 28, 2025
077807a
Fix swiftlint issues (#780)
testableapple Apr 28, 2025
0db6951
[CI] Testing infra refactoring (#782)
testableapple Apr 29, 2025
e32dd86
[Fix]Remove unnecessary operation during tests and fix flakiness (#784)
ipavlidakis Apr 29, 2025
c6f3761
[Enhancement]Allow deeplinks from new domain (#785)
ipavlidakis Apr 29, 2025
f54d137
[CI] Reduce E2E test batches (#786)
testableapple Apr 29, 2025
0e9296e
[CI] Update TestFlight app version on manual uploading (#787)
testableapple Apr 29, 2025
9ca60e9
[CI] Fix manual TestFlight upload detection
testableapple Apr 29, 2025
f11bfee
[CI] Log the version is being uploaded to TestFlight
testableapple Apr 29, 2025
c15a3dc
Generated protobufs updates for Stats (#788)
martinmitrevski Apr 29, 2025
17bc7ca
Updated StatsOptions model (#789)
martinmitrevski Apr 29, 2025
2c94228
Fixed broken tests (#790)
martinmitrevski Apr 29, 2025
503a0b4
[Fix]Deeplink UI tests (#793)
ipavlidakis Apr 30, 2025
b2537e7
[Fix]Ringing flow issues (#792)
ipavlidakis Apr 30, 2025
5ca26ad
[Fix]Picture-in-Picture store thread access (#794)
ipavlidakis Apr 30, 2025
e6a3386
[CI] Bump fastlane plugin version
testableapple May 1, 2025
3b136e1
[Enhancement]Implement proximity policies (#770)
ipavlidakis May 1, 2025
92c7658
Enable OSLogs showing when running before app is running
ipavlidakis May 2, 2025
53c9ce2
[Fix]Picture-in-Picture trigger and lifecycle (#796)
ipavlidakis May 5, 2025
2d0bf37
[Enhancement]Publish media based on capablities
ipavlidakis May 5, 2025
1c1ff61
Bump 1.22.0
May 5, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .github/workflows/cron-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ jobs:
STREAM_SDK_TEST_ACCOUNT_EMAIL: ${{ secrets.STREAM_SDK_TEST_ACCOUNT_EMAIL }}
STREAM_SDK_TEST_ACCOUNT_PASSWORD: ${{ secrets.STREAM_SDK_TEST_ACCOUNT_PASSWORD }}
STREAM_SDK_TEST_ACCOUNT_OTP_SECRET: ${{ secrets.STREAM_SDK_TEST_ACCOUNT_OTP_SECRET }}
STREAM_VIDEO_SECRET: ${{ secrets.STREAM_VIDEO_SECRET }}
- name: Allure TestOps Upload
if: success() || failure()
run: bundle exec fastlane allure_upload launch_id:$LAUNCH_ID
Expand Down Expand Up @@ -149,7 +148,6 @@ jobs:
runs-on: ${{ matrix.os }}
env:
XCODE_VERSION: ${{ matrix.xcode }}
STREAM_VIDEO_SECRET: ${{ secrets.STREAM_VIDEO_SECRET }}
steps:
- uses: actions/checkout@v4.1.1
- uses: ./.github/actions/bootstrap
Expand Down
5 changes: 1 addition & 4 deletions .github/workflows/smoke-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@ jobs:
name: Test LLC (Debug)
runs-on: macos-15
if: ${{ github.event.inputs.record_snapshots_swiftui != 'true' && github.event.inputs.record_snapshots_uikit != 'true' }}
env:
STREAM_VIDEO_SECRET: ${{ secrets.STREAM_VIDEO_SECRET }}
steps:
- uses: actions/checkout@v4.1.1
with:
Expand Down Expand Up @@ -257,7 +255,7 @@ jobs:
ALLURE_TOKEN: ${{ secrets.ALLURE_TOKEN }}
strategy:
matrix:
batch: [0, 1]
batch: [0]
fail-fast: false
steps:
- uses: actions/checkout@v4.1.1
Expand All @@ -280,7 +278,6 @@ jobs:
STREAM_SDK_TEST_ACCOUNT_EMAIL: ${{ secrets.STREAM_SDK_TEST_ACCOUNT_EMAIL }}
STREAM_SDK_TEST_ACCOUNT_PASSWORD: ${{ secrets.STREAM_SDK_TEST_ACCOUNT_PASSWORD }}
STREAM_SDK_TEST_ACCOUNT_OTP_SECRET: ${{ secrets.STREAM_SDK_TEST_ACCOUNT_OTP_SECRET }}
STREAM_VIDEO_SECRET: ${{ secrets.STREAM_VIDEO_SECRET }}
- name: Allure TestOps Upload
if: env.LAUNCH_ID != '' && (success() || failure())
run: bundle exec fastlane allure_upload launch_id:$LAUNCH_ID
Expand Down
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

### πŸ”„ Changed

# [1.22.0](https://github.com/GetStream/stream-video-swift/releases/tag/1.22.0)
_May 05, 2025_

### βœ… Added
- You can now configure policies based on the the device's proximity information. Those policies can be used to toggle speaker and video. [#770](https://github.com/GetStream/stream-video-swift/pull/770)

### 🐞 Fixed
- Fix ringing flow issues. [#792](https://github.com/GetStream/stream-video-swift/pull/792)
- Fix a few points that were negatively affecting Picture-in-Picture lifecycle. [#796](https://github.com/GetStream/stream-video-swift/pull/796)

# [1.21.1](https://github.com/GetStream/stream-video-swift/releases/tag/1.21.1)
_April 25, 2025_

Expand Down
49 changes: 46 additions & 3 deletions DemoApp/Sources/Components/AppEnvironment.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ extension AppEnvironment {
case demo
case legacy
case prontoFrankfurtC2
case livestream
case custom(baseURL: BaseURL, apiKey: String, token: String)

var url: URL {
Expand All @@ -55,6 +56,8 @@ extension AppEnvironment {
URL(string: "https://getstream.io")!
case .legacy:
URL(string: "https://stream-calls-dogfood.vercel.app")!
case .livestream:
URL(string: "https://livestream-react-demo.vercel.app")!
case let .custom(baseURL, _, _):
baseURL.url
}
Expand All @@ -72,6 +75,8 @@ extension AppEnvironment {
return "Staging"
case .legacy:
return "Legacy"
case .livestream:
return "Livestream"
case .demo:
return "Demo"
case let .custom(_, apiKey, _):
Expand All @@ -94,6 +99,9 @@ extension AppEnvironment {
.appendingPathComponent("join")
.appendingPathComponent(callId)
.addQueryParameter("type", value: callType)
case .livestream:
return url
.appending(.init(name: "id", value: callId))
default:
return url
.appendingPathComponent("join")
Expand All @@ -107,7 +115,8 @@ extension AppEnvironment {
.prontoStaging,
.staging,
.demo,
.legacy
.legacy,
.livestream
]
}

Expand Down Expand Up @@ -258,6 +267,7 @@ extension AppEnvironment {
case staging
case demo
case legacy
case livestream

var deeplinkURL: URL {
switch self {
Expand All @@ -269,6 +279,8 @@ extension AppEnvironment {
return BaseURL.demo.url
case .legacy:
return BaseURL.legacy.url
case .livestream:
return BaseURL.livestream.url
}
}

Expand All @@ -282,18 +294,20 @@ extension AppEnvironment {
return "Demo"
case .legacy:
return "Legacy"
case .livestream:
return "Livestream"
}
}
}

static var supportedDeeplinks: [SupportedDeeplink] = {
switch configuration {
case .debug:
return [.pronto, .demo, .staging, .legacy]
return [.pronto, .demo, .staging, .legacy, .livestream]
case .test:
return [.pronto, .demo, .staging, .legacy]
case .release:
return [.demo]
return [.demo, .livestream]
}
}()
}
Expand Down Expand Up @@ -577,6 +591,35 @@ extension AppEnvironment {
static var preferredCallType: String?
}

extension AppEnvironment {

enum ProximityPolicyDebugConfiguration: Hashable, Debuggable, Sendable, CaseIterable {
case speaker, video

var title: String {
switch self {
case .speaker:
return "Speaker"
case .video:
return "Video"
}
}

var value: ProximityPolicy {
switch self {
case .speaker:
return SpeakerProximityPolicy()
case .video:
return VideoProximityPolicy()
}
}
}

static var proximityPolicies: Set<ProximityPolicyDebugConfiguration> = {
[.speaker, .video]
}()
}

extension String: Debuggable {
var title: String {
self
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ enum AuthenticationProvider {
return "demo"
case .prontoFrankfurtC2:
return "pronto-fra-c2"
case .livestream:
return "demo"
case .custom:
return ""
}
Expand Down
92 changes: 53 additions & 39 deletions DemoApp/Sources/Components/Deeplinks/DeeplinkAdapter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,51 +37,65 @@ struct DeeplinkAdapter {
guard canHandle(url: url) else {
return (.empty, nil)
}

let pathComponentsCount = url.pathComponents.endIndex

// Fetch the callId from the path components
// e.g https://getstream.io/join/path-call-id
let callPathId: String? = {
if
url.host == AppEnvironment.BaseURL.livestream.url.host,
let callId = url.queryParameters["id"] ?? url.queryParameters["view"] {
return (
DeeplinkInfo(
url: url,
callId: callId,
callType: .livestream,
baseURL: AppEnvironment.BaseURL.livestream
),
nil
)
} else {
let pathComponentsCount = url.pathComponents.endIndex

// Fetch the callId from the path components
// e.g https://getstream.io/join/path-call-id
let callPathId: String? = {
guard
pathComponentsCount >= 2,
url.pathComponents[pathComponentsCount - 2] == "join",
let callId = url.pathComponents.last
else {
return nil
}
return callId
}()

// Fetch the callId from the query parameters
// e.g https://getstream.io/video/demos?id=parameter-call-id
let callParameterId = url.queryParameters["id"]

guard
pathComponentsCount >= 2,
url.pathComponents[pathComponentsCount - 2] == "join",
let callId = url.pathComponents.last
// Use the the callPathId with higher priority if it's available.
let callId = callPathId ?? callParameterId
else {
return nil
log.warning("Unable to handle deeplink because id was missing.")
return (.empty, nil)
}
return callId
}()

// Fetch the callId from the query parameters
// e.g https://getstream.io/video/demos?id=parameter-call-id
let callParameterId = url.queryParameters["id"]

guard
// Use the the callPathId with higher priority if it's available.
let callId = callPathId ?? callParameterId
else {
log.warning("Unable to handle deeplink because id was missing.")
return (.empty, nil)
}
let callType = url.queryParameters["type"] ?? "default"

let callType = url.queryParameters["type"] ?? "default"
log.debug("Deeplink handled was: \(url)")
let host = url.host
let baseURL: AppEnvironment.BaseURL = AppEnvironment
.BaseURL
.allCases
.first { $0.url.host == host } ?? AppEnvironment.baseURL

log.debug("Deeplink handled was: \(url)")
let host = url.host
let baseURL: AppEnvironment.BaseURL = AppEnvironment
.BaseURL
.allCases
.first { $0.url.host == host } ?? AppEnvironment.baseURL

return (
DeeplinkInfo(
url: url,
callId: callId,
callType: callType,
baseURL: baseURL
),
nil
)
return (
DeeplinkInfo(
url: url,
callId: callId,
callType: callType,
baseURL: baseURL
),
nil
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,13 @@ final class OSLogDestination: BaseLogDestination, @unchecked Sendable {

switch logDetails.level {
case .debug:
logger.debug("\(formattedMessage)")
logger.debug("\(formattedMessage, privacy: .public)")
case .info:
logger.notice("\(formattedMessage)")
logger.notice("\(formattedMessage, privacy: .public)")
case .warning:
logger.warning("\(formattedMessage)")
logger.warning("\(formattedMessage, privacy: .public)")
case .error:
logger.critical("\(formattedMessage)")
logger.critical("\(formattedMessage, privacy: .public)")
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import SwiftUI

struct DemoCallModifier<Factory: ViewFactory>: ViewModifier {

@Injected(\.appearance) private var appearance

var viewFactory: Factory
var viewModel: CallViewModel
var chatViewModel: DemoChatViewModel
Expand All @@ -27,32 +29,16 @@ struct DemoCallModifier<Factory: ViewFactory>: ViewModifier {

func body(content: Content) -> some View {
contentView(content)
.modifier(ThermalStateViewModifier())
}

@MainActor
@ViewBuilder
private func contentView(_ rootView: Content) -> some View {
if
let call = viewModel.call,
call.callType == .livestream {
ZStack {
rootView
LivestreamPlayer(
viewFactory: viewFactory,
type: call.callType,
id: call.callId,
joinPolicy: .none,
showsLeaveCallButton: true,
onFullScreenStateChange: { [weak viewModel] in viewModel?.hideUIElements = $0 }
)
}
} else {
VideoViewOverlay(
rootView: rootView,
viewFactory: viewFactory,
viewModel: viewModel
)
.modifier(ThermalStateViewModifier())
}
DemoVideoViewOverlay(
rootView: rootView,
viewFactory: viewFactory,
viewModel: viewModel
)
}
}
Loading
Loading