Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
5 changes: 3 additions & 2 deletions .github/workflows/smoke-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,9 @@ jobs:

build-old-xcode:
name: Build LLC + UI (Xcode 15)
runs-on: macos-14
if: ${{ github.event.inputs.record_snapshots != 'true' }}
runs-on: macos-15
# if: ${{ github.event.inputs.record_snapshots != 'true' }}
if: false # disable Xcode 15 builds
env:
XCODE_VERSION: "15.4"
steps:
Expand Down
2 changes: 1 addition & 1 deletion .swiftformat
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Stream rules
--header "\nCopyright © {year} Stream.io Inc. All rights reserved.\n"
--swiftversion 5.6
--swiftversion 6.0

--ifdef no-indent
--disable redundantType
Expand Down
2 changes: 1 addition & 1 deletion DemoApp/Extensions/UserDefaults+Shared.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import Foundation

extension UserDefaults {
static let shared = UserDefaults(suiteName: applicationGroupIdentifier)!
static var shared: UserDefaults { UserDefaults(suiteName: applicationGroupIdentifier)! }

var currentUserId: String? {
get { string(forKey: #function) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ struct DemoAppConfig {
}
}

class AppConfig {
class AppConfig: @unchecked Sendable {
/// The Demo App Configuration.
var demoAppConfig: DemoAppConfig

static var shared = AppConfig()
static let shared = AppConfig()

private init() {
// Default DemoAppConfig
Expand Down Expand Up @@ -69,13 +69,13 @@ class AppConfig {
}
}

class UserConfig {
class UserConfig: @unchecked Sendable {
var isInvisible = false
var language: TranslationLanguage?
var typingIndicatorsEnabled: Bool?
var readReceiptsEnabled: Bool?

static var shared = UserConfig()
static let shared = UserConfig()

private init() {}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,7 @@ class DemoLivestreamComposerVC: ComposerVC {
from url: URL,
type: AttachmentType,
info: [LocalAttachmentInfoKey: Any],
extraData: (any Encodable)?
extraData: (Encodable & Sendable)?
) throws {
guard let cid = livestreamChannelController?.channel?.cid else {
return
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import StreamChatUI
import UIKit

/// Delegate protocol for `LivestreamMessageActionsVC`
protocol LivestreamMessageActionsVCDelegate: AnyObject {
@MainActor protocol LivestreamMessageActionsVCDelegate: AnyObject {
func livestreamMessageActionsVC(
_ vc: DemoLivestreamMessageActionsVC,
message: ChatMessage,
Expand Down
4 changes: 1 addition & 3 deletions DemoApp/Screens/UserProfileViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -150,9 +150,7 @@ class UserProfileViewController: UITableViewController, CurrentChatUserControlle
let unreadDetailsView = UnreadDetailsView(
onLoadData: { [weak self](completion: @escaping (Result<CurrentUserUnreads, Error>) -> Void) in
self?.currentUserController.loadAllUnreads { result in
DispatchQueue.main.async {
completion(result)
}
completion(result)
}
},
onDismiss: { [weak self] in
Expand Down
2 changes: 1 addition & 1 deletion DemoApp/Shared/DemoAppCoordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import StreamChat
import StreamChatUI
import UIKit

final class DemoAppCoordinator: NSObject {
@MainActor final class DemoAppCoordinator: NSObject {
internal let window: UIWindow
internal let pushNotifications: PushNotifications

Expand Down
2 changes: 1 addition & 1 deletion DemoApp/Shared/DemoUsers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import Foundation
import StreamChat

var apiKeyString = ProcessInfo.processInfo.environment["CUSTOM_API_KEY"] ?? DemoApiKeys.frankfurtC1.rawValue
nonisolated(unsafe) var apiKeyString = ProcessInfo.processInfo.environment["CUSTOM_API_KEY"] ?? DemoApiKeys.frankfurtC1.rawValue
let applicationGroupIdentifier = "group.io.getstream.iOS.ChatDemoApp"

enum DemoUserType {
Expand Down
17 changes: 7 additions & 10 deletions DemoApp/Shared/StreamChatWrapper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import StreamChatUI
import UIKit
import UserNotifications

final class StreamChatWrapper {
@MainActor final class StreamChatWrapper {
static var shared = StreamChatWrapper(apiKeyString: apiKeyString)

static func replaceSharedInstance(apiKeyString: String) {
Expand Down Expand Up @@ -61,7 +61,7 @@ extension StreamChatWrapper {
// MARK: User Authentication

extension StreamChatWrapper {
func connect(user: DemoUserType, completion: @escaping (Error?) -> Void) {
func connect(user: DemoUserType, completion: @escaping @MainActor(Error?) -> Void) {
switch user {
case let .credentials(userCredentials):
connectUser(credentials: userCredentials, completion: completion)
Expand All @@ -74,7 +74,7 @@ extension StreamChatWrapper {
}
}

func connectUser(credentials: UserCredentials?, completion: @escaping (Error?) -> Void) {
func connectUser(credentials: UserCredentials?, completion: @escaping @MainActor(Error?) -> Void) {
guard let userCredentials = credentials else {
log.error("User credentials are missing")
return
Expand Down Expand Up @@ -121,7 +121,7 @@ extension StreamChatWrapper {
)
}

func logIn(as user: DemoUserType, completion: @escaping (Error?) -> Void) {
func logIn(as user: DemoUserType, completion: @escaping @MainActor(Error?) -> Void) {
// Setup Stream Chat
setUpChat()

Expand All @@ -134,14 +134,11 @@ extension StreamChatWrapper {
} else {
StreamChatWrapper.onRemotePushRegistration?()
}

DispatchQueue.main.async {
completion(error)
}
completion(error)
}
}

func logOut(completion: @escaping () -> Void) {
func logOut(completion: @escaping @MainActor() -> Void) {
guard let client = self.client else {
logClientNotInstantiated()
return
Expand Down Expand Up @@ -192,7 +189,7 @@ extension StreamChatWrapper {
// An object to test the Stream Models transformer.
// By default it is not used. To use it, set it to the `modelsTransformer` property of the `ChatClientConfig`.

class CustomStreamModelsTransformer: StreamModelsTransformer {
final class CustomStreamModelsTransformer: StreamModelsTransformer {
func transform(channel: ChatChannel) -> ChatChannel {
channel.replacing(
name: "Custom Name",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import StreamChat
import UIKit

final class BannerShowingConnectionDelegate {
@MainActor final class BannerShowingConnectionDelegate {
// MARK: - Private Properties

private let view: UIView
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ enum LocationPermissionError: Error {
case permissionRestricted
}

class LocationProvider: NSObject {
class LocationProvider: NSObject, @unchecked Sendable {
private let locationManager: CLLocationManager
private var onCurrentLocationFetch: ((Result<CLLocation, Error>) -> Void)?

Expand Down
4 changes: 2 additions & 2 deletions DemoApp/StreamChat/Components/DemoChatChannelVC.swift
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ final class DemoChatChannelVC: ChatChannelVC, UIGestureRecognizerDelegate {

// MARK: - Loading previous and next messages state handling.

override func loadPreviousMessages(completion: @escaping (Error?) -> Void) {
override func loadPreviousMessages(completion: @escaping @MainActor(Error?) -> Void) {
messageListVC.headerView = loadingViewIndicator
super.loadPreviousMessages(completion: completion)
}
Expand All @@ -81,7 +81,7 @@ final class DemoChatChannelVC: ChatChannelVC, UIGestureRecognizerDelegate {
messageListVC.headerView = nil
}

override func loadNextMessages(completion: @escaping (Error?) -> Void) {
override func loadNextMessages(completion: @escaping @MainActor(Error?) -> Void) {
messageListVC.footerView = loadingViewIndicator
super.loadNextMessages(completion: completion)
}
Expand Down
4 changes: 2 additions & 2 deletions DemoApp/StreamChat/Components/DemoChatThreadVC.swift
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ class DemoChatThreadVC: ChatThreadVC, CurrentChatUserControllerDelegate {

// MARK: - Loading previous and next messages state handling.

override func loadPreviousReplies(completion: @escaping (Error?) -> Void) {
override func loadPreviousReplies(completion: @escaping @MainActor(Error?) -> Void) {
messageListVC.headerView = loadingViewIndicator
super.loadPreviousReplies(completion: completion)
}
Expand All @@ -92,7 +92,7 @@ class DemoChatThreadVC: ChatThreadVC, CurrentChatUserControllerDelegate {
messageListVC.headerView = nil
}

override func loadNextReplies(completion: @escaping (Error?) -> Void) {
override func loadNextReplies(completion: @escaping @MainActor(Error?) -> Void) {
messageListVC.footerView = loadingViewIndicator
super.loadNextReplies(completion: completion)
}
Expand Down
10 changes: 4 additions & 6 deletions DemoApp/StreamChat/DemoAppCoordinator+DemoApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ extension DemoAppCoordinator {
StreamChatWrapper.shared
}

func start(cid: ChannelId? = nil, completion: @escaping (Error?) -> Void) {
func start(cid: ChannelId? = nil, completion: @escaping @MainActor(Error?) -> Void) {
if let user = UserDefaults.shared.currentUser {
showChat(for: .credentials(user), cid: cid, animated: false, completion: completion)
} else {
showLogin(animated: false)
}
}

func showChat(for user: DemoUserType, cid: ChannelId?, animated: Bool, completion: @escaping (Error?) -> Void) {
func showChat(for user: DemoUserType, cid: ChannelId?, animated: Bool, completion: @escaping @MainActor(Error?) -> Void) {
logIn(as: user, completion: completion)

let chatVC = makeChatVC(
Expand Down Expand Up @@ -207,7 +207,7 @@ extension DemoAppCoordinator {
// MARK: - User Auth

private extension DemoAppCoordinator {
func logIn(as user: DemoUserType, completion: @escaping (Error?) -> Void) {
func logIn(as user: DemoUserType, completion: @escaping @MainActor(Error?) -> Void) {
// Store current user id
UserDefaults.shared.currentUserId = user.staticUserId

Expand All @@ -230,9 +230,7 @@ private extension DemoAppCoordinator {

func disconnect() {
chat.client?.disconnect { [weak self] in
DispatchQueue.main.async {
self?.showLogin(animated: true)
}
self?.showLogin(animated: true)
}
}
}
Expand Down
31 changes: 13 additions & 18 deletions DemoShare/DemoShareViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@

import Combine
import CoreServices
import UIKit
import StreamChat
import Social
import StreamChat
import UIKit

@MainActor
class DemoShareViewModel: ObservableObject, ChatChannelControllerDelegate {

private let chatClient: ChatClient
private let userCredentials: UserCredentials
private var channelListController: ChatChannelListController?
Expand Down Expand Up @@ -50,11 +49,11 @@ class DemoShareViewModel: ObservableObject, ChatChannelControllerDelegate {
let client = ChatClient(config: config)
client.setToken(token: Token(stringLiteral: userCredentials.token.rawValue))

self.chatClient = client
chatClient = client
self.userCredentials = userCredentials
self.extensionContext = extensionContext
self.loadChannels()
self.loadImages()
loadChannels()
loadImages()
}

func sendMessage() async throws {
Expand Down Expand Up @@ -110,22 +109,18 @@ class DemoShareViewModel: ObservableObject, ChatChannelControllerDelegate {

func dismissShareSheet() {
loading = false
self.extensionContext?.completeRequest(returningItems: [], completionHandler: nil)
extensionContext?.completeRequest(returningItems: [], completionHandler: nil)
}

nonisolated func channelController(
func channelController(
_ channelController: ChatChannelController,
didUpdateMessages changes: [ListChange<ChatMessage>]
) {
Task {
await MainActor.run {
for change in changes {
if case .update(let item, _) = change {
if messageId == item.id, item.localState == nil {
dismissShareSheet()
return
}
}
for change in changes {
if case .update(let item, _) = change {
if messageId == item.id, item.localState == nil {
dismissShareSheet()
return
}
}
}
Expand All @@ -134,7 +129,7 @@ class DemoShareViewModel: ObservableObject, ChatChannelControllerDelegate {
// MARK: - private

private func loadItem(from itemProvider: NSItemProvider, type: String) async throws -> NSSecureCoding {
return try await withCheckedThrowingContinuation { continuation in
try await withCheckedThrowingContinuation { continuation in
itemProvider.loadItem(forTypeIdentifier: type) { item, error in
if let error = error {
continuation.resume(throwing: error)
Expand Down
6 changes: 3 additions & 3 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// swift-tools-version:5.7
// swift-tools-version:6.0

import Foundation
import PackageDescription
Expand All @@ -25,7 +25,7 @@ let package = Package(
.library(
name: "StreamChatTestMockServer",
targets: ["StreamChatTestMockServer"]
),
)
],
targets: [
.target(
Expand All @@ -52,7 +52,7 @@ let package = Package(
path: "TestTools/StreamChatTestMockServer",
exclude: ["Info.plist"],
resources: [.process("Fixtures")]
),
)
]
)

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
</p>
<p align="center">
<a href="https://getstream.io/chat/docs/sdk/ios/"><img src="https://img.shields.io/badge/iOS-13%2B-lightblue" /></a>
<a href="https://swift.org"><img src="https://img.shields.io/badge/Swift-5.7%2B-orange.svg" /></a>
<a href="https://swift.org"><img src="https://img.shields.io/badge/Swift-6.0%2B-orange.svg" /></a>
<a href="https://github.com/GetStream/stream-chat-swift/actions"><img src="https://github.com/GetStream/stream-chat-swift/actions/workflows/cron-checks.yml/badge.svg" /></a>
<a href="https://sonarcloud.io/summary/new_code?id=GetStream_stream-chat-swift"><img src="https://sonarcloud.io/api/project_badges/measure?project=GetStream_stream-chat-swift&metric=coverage" /></a>
</p>
Expand Down
Loading
Loading