Skip to content
Merged
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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
### v1.0.0-beta.1 (Sep 2, 2024)
- Fixed the package's `CFBundleShortVersionString` format to comply to the required format
### v1.0.0-beta.2 (Sep 30, 2024)
- Fixed multiple navigationBars appearing issue
6 changes: 3 additions & 3 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ let package = Package(
.package(
name: "SendbirdChatSDK",
url: "https://github.com/sendbird/sendbird-chat-sdk-ios",
from: "4.20.0"
from: "4.21.1"
),
],
targets: [
.binaryTarget(
name: "SendbirdSwiftUI",
url: "https://github.com/sendbird/sendbird-swiftui-ios/releases/download/1.0.0-beta.1/SendbirdSwiftUI.xcframework.zip",
checksum: "cd882856d77ba496eb313b16eeec35d8c981f49dcac3818194badac4a3960183"
url: "https://github.com/sendbird/sendbird-swiftui-ios/releases/download/1.0.0-beta.2/SendbirdSwiftUI.xcframework.zip",
checksum: "097139b0498cf40ad4840f62a6366cd6eea7ffc0683995c03152dd19131e9913"

),
.target(
Expand Down
920 changes: 867 additions & 53 deletions Sample/QuickStartSwiftUI.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions Sample/project.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ options:
packages:
SendbirdChatSDK:
url: https://github.com/sendbird/sendbird-chat-sdk-ios
from: 4.20.0
from: 4.21.1

schemes:
QuickStartSwiftUI:
Expand Down Expand Up @@ -41,7 +41,7 @@ settingGroups:
FRAMEWORK_SEARCH_PATHS: ''
IPHONEOS_DEPLOYMENT_TARGET: '15.0'
LD_RUNPATH_SEARCH_PATHS: ["$(inherited)", "@executable_path/Frameworks", "@loader_path/Frameworks"]
MARKETING_VERSION: '1.0.0-beta.1'
MARKETING_VERSION: '1.0.0-beta.2'
PRODUCT_NAME: "$(TARGET_NAME)"
SDKROOT: iphoneos
SWIFT_VERSION: '5.0'
Expand Down
6 changes: 3 additions & 3 deletions SendbirdSwiftUI.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "SendbirdSwiftUI"
s.version = "1.0.0-beta.1"
s.version = "1.0.0-beta.2"
s.summary = "Sendbird SwiftUI SDK based on SendbirdChatSDK"
s.description = "SendbirdSwiftUI is a framework composed of basic UI components based on SwiftUI and SendbirdChatSDK."
s.homepage = "https://sendbird.com"
Expand All @@ -16,10 +16,10 @@ Pod::Spec.new do |s|
"Kai" => "kai.lee@sendbird.com"
}
s.platform = :ios, "15.0"
s.source = { :http => "https://github.com/sendbird/sendbird-swiftui-ios/releases/download/#{s.version}/SendbirdSwiftUI.zip", :sha1 => "b6615fddbfb97ceec73f837365724f467d28660b" }
s.source = { :http => "https://github.com/sendbird/sendbird-swiftui-ios/releases/download/#{s.version}/SendbirdSwiftUI.zip", :sha1 => "7707988dde5aa55cea4af0f46c4c76f869300699" }
s.ios.vendored_frameworks = 'SendbirdSwiftUI/SendbirdSwiftUI.xcframework'
s.ios.frameworks = ["UIKit", "SwiftUI", "Foundation", "CoreData", "SendbirdChatSDK"]
s.requires_arc = true
s.dependency "SendbirdChatSDK", ">= 4.20.0"
s.dependency "SendbirdChatSDK", ">= 4.21.1"
s.ios.library = "icucore"
end
4 changes: 4 additions & 0 deletions Sources/Constant/SBUStringSet.swift
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,10 @@ public class SBUStringSet {
// MARK: - form type
public static var FormType_Optional = "(optional)" // 3.11.0
public static var FormType_Error_Default = "Please check the value" // 3.11.0
public static var FormType_Error_Required = "This field is required" // 3.27.0
public static var FormType_Fallback_Message = "Form type messages are not available in this version." // 3.27.0
public static var FormType_Submit_Done = "Submitted successfully" // 3.27.0
public static var FormType_No_Reponse = "No response" // 3.27.0

// MARK: - Feedback
public static var Feedback_Comment_Title = "Provide additional feedback (optional)" // 3.15.0
Expand Down
6 changes: 6 additions & 0 deletions Sources/Deprecated/SBUForm.Deprecated.swift
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ extension SBUUserMessageCell {
public func updateFormView(with forms: [SBUForm]?, answers: [SBUForm.Answer]) -> Bool { false }
}

@available(*, unavailable, message: "This model is no longer used internally.")
extension SBUFormViewDelegate {
/// Called when `form` is submitted.
/// - Parameters:
Expand All @@ -199,6 +200,7 @@ extension SBUFormViewDelegate {
func formView(_ view: SBUFormView, didUpdate answer: SBUForm.Answer) { }
}

@available(*, unavailable, message: "This model is no longer used internally.")
extension SBUFormFieldViewDelegate {
/// Called when `SBUForm.Field` is updated.
/// - Parameters:
Expand All @@ -208,13 +210,15 @@ extension SBUFormFieldViewDelegate {
func formFieldView(_ fieldView: SBUFormFieldView, didUpdate updated: SBUForm.Field.Updated) { }
}

@available(*, unavailable, message: "This method is deprecated in 3.27.0")
extension SBUFormViewParams {
@available(*, unavailable, message: "This model is no longer used internally. Changed to use `SendbirdChatSDK.Form`.")
init(messageId: Int64, form: SBUForm) {
fatalError("This model is no longer used internally. Changed to use `SendbirdChatSDK.Form`.")
}
}

@available(*, unavailable, message: "This model is no longer used internally.")
extension SBUFormView {
/// Memory cached answer data.
@available(*, unavailable, message: "This model is no longer used internally. Changed to use `SendbirdChatSDK.Form`.")
Expand All @@ -232,6 +236,7 @@ extension SBUFormView {
public func formFieldView(_ view: SBUFormFieldView, didUpdate updated: SBUForm.Field.Updated) { }
}

@available(*, unavailable, message: "This model is no longer used internally.")
extension SBUFormFieldView {

// MARK: - Configure
Expand Down Expand Up @@ -277,6 +282,7 @@ extension SBUGroupChannelViewController {
public func groupChannelModule(_ listComponent: SBUGroupChannelModule.List, answersFor messageId: Int64?) -> [SBUForm.Answer]? { nil }
}

@available(*, unavailable, message: "This model is no longer used internally.")
extension SBUFormFieldView.StatusType {
@available(*, unavailable, message: "This model is no longer used internally. Changed to use `SendbirdChatSDK.Form`.")
public init(form: SBUForm, field: SBUForm.Field, value: String?) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import UIKit
import SendbirdChatSDK

/// - Since: 3.11.0
@available(*, deprecated, message: "This method is deprecated in 3.27.0")
public protocol SBUFormFieldViewDelegate: AnyObject {
/// Called when `SBUForm.Field` is updated.
/// - Parameters:
Expand All @@ -19,6 +20,7 @@ public protocol SBUFormFieldViewDelegate: AnyObject {
}

/// - Since: 3.11.0
@available(*, deprecated, message: "This method is deprecated in 3.27.0", renamed: "SBUMessageFormItemView")
public class SBUFormFieldView: SBUView, UITextFieldDelegate {
// MARK: - Properties

Expand Down Expand Up @@ -68,6 +70,7 @@ public class SBUFormFieldView: SBUView, UITextFieldDelegate {
}

/// - Since: 3.11.0
@available(*, deprecated, message: "This method is deprecated in 3.27.0", renamed: "SBUMessageFormItemView")
public class SBUSimpleFormFieldView: SBUFormFieldView {

/// A vertical stack view to configure layouts of the fields.
Expand Down Expand Up @@ -156,7 +159,7 @@ public class SBUSimpleFormFieldView: SBUFormFieldView {

self.errorTitleView.sbu_constraint(height: 12)

self.topSpaceView.sbu_constraint(width: 1, height: 8)
self.topSpaceView.sbu_constraint(width: 1, height: 6)
self.bottomSpaceView.sbu_constraint(width: 1, height: 4)

self.inputFieldView
Expand Down Expand Up @@ -261,9 +264,11 @@ public class SBUSimpleFormFieldView: SBUFormFieldView {

}

@available(*, deprecated, message: "This method is deprecated in 3.27.0")
extension SBUFormFieldView {
/// Enum model to indicate the status of the value in the currently entered field.
/// - Since: 3.11.0
@available(*, deprecated, message: "This method is deprecated in 3.27.0")
public enum StatusType {
/// Represents a completed form field with a value.
case done(value: String)
Expand Down Expand Up @@ -341,6 +346,7 @@ extension SBUFormFieldView {
/// Indicates the input type of the field.
/// Can be used to specify the keyboard type.
/// - Since: 3.16.0
@available(*, deprecated, message: "This method is deprecated in 3.27.0")
public enum SBUFormFieldInputType: String, Codable {
case text // default value.
case phone
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import UIKit
import SendbirdChatSDK

/// - Since: 3.11.0
@available(*, deprecated, message: "This method is deprecated in 3.27.0")
public protocol SBUFormViewDelegate: AnyObject {
/// Called when `form` is submitted.
/// - Parameters:
Expand All @@ -20,6 +21,7 @@ public protocol SBUFormViewDelegate: AnyObject {
}

/// - Since: 3.11.0
@available(*, deprecated, message: "This method is deprecated in 3.27.0", renamed: "SBUMessageFormView")
open class SBUFormView: SBUView, SBUFormFieldViewDelegate {
public var theme: SBUMessageCellTheme = SBUTheme.messageCellTheme

Expand Down Expand Up @@ -83,6 +85,7 @@ open class SBUFormView: SBUView, SBUFormFieldViewDelegate {
}

/// - Since: 3.11.0
@available(*, deprecated, message: "This method is deprecated in 3.27.0", renamed: "SBUMessageFormView")
open class SBUSimpleFormView: SBUFormView {
// views

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import SendbirdChatSDK

/// The data model used for configuring ``SBUFormView``.
/// - Since: 3.11.0
@available(*, deprecated, message: "This method is deprecated in 3.27.0")
public struct SBUFormViewParams {
// MARK: - Properties
/// The ID of the message that provides form.
Expand Down
37 changes: 35 additions & 2 deletions Sources/Extension/Array+SBUIKit.swift
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,9 @@ extension Array where Element: BaseMessage {
guard message.updatedAt == 0 else { return nil }
guard message.sendingStatus == .succeeded else { return nil }
guard message.sender?.userId != SBUGlobals.currentUser?.userId else { return nil }

return message
if message.isStreamMessage == true { return message }
if latestMessage.isStreamMessage == true { return message }
return nil
}
}

Expand Down Expand Up @@ -114,3 +115,35 @@ extension Array {
return indices.contains(index) ? self[index] : nil
}
}

extension Array where Element == String {
func toggle(_ value: String) -> [String] {
var copy = self
if let index = copy.firstIndex(of: value) {
copy.remove(at: index)
} else {
copy.append(value)
}
return copy
}
}

extension Array where Element == BaseMessage {
/// A value that determines whether to disable the MessageInputView.
/// The values of sequential messages with `disable_chat_input` enabled are reviewed internally.
/// - Since: 3.27.2
public func getChatInputDisableState(hasNext: Bool?) -> Bool {
if hasNext == true { return false }

var types = [BaseMessage.ChatInputDisableType]()

for element in self {
let type = element.getChatInputDisableType(hasNext: hasNext)
if type == .none { break }
types.append(type)
}

// Component type must be included to exit the disable_chat_input state.
return types.contains(where: { $0 == .component })
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,9 @@
import UIKit
import SendbirdChatSDK

// only internal
fileprivate extension BaseMessage {
func setInMemoryUserInfo<Element>(key: String, data: Element) {
var memory = self.inMemoryUserInfo ?? [:]
memory[key] = data
self.inMemoryUserInfo = memory
}

func getInMemoryUserInfo<Element>(key: String) -> Element? {
self.inMemoryUserInfo?[key] as? Element
}

func getInMemoryUserInfo<Element>(key: String, defaultValue: Element) -> Element {
self.inMemoryUserInfo?[key] as? Element ?? defaultValue
}
}

extension BaseMessage {
static let messageTemplateRetryStatusKey = "messageTemplateRetryStatusKey"
static let messageTemplateImageRetryStatusKey = "messageTemplateImageRetryStatusKey"
static let messageTemplateHasCompositeType = "messageTemplateHasCompositeType"
static let messageTemplateCarouselView = "messageTemplateCarouselView"
}

Expand All @@ -43,12 +25,7 @@ extension BaseMessage {
get { self.getInMemoryUserInfo(key: Self.messageTemplateImageRetryStatusKey, defaultValue: .initialized) }
set { self.setInMemoryUserInfo(key: Self.messageTemplateImageRetryStatusKey, data: newValue) }
}

var hasMessageTemplateCompositeType: Bool {
get { self.getInMemoryUserInfo(key: Self.messageTemplateHasCompositeType, defaultValue: false) }
set { self.setInMemoryUserInfo(key: Self.messageTemplateHasCompositeType, data: newValue) }
}


var messageTemplateCarouselView: UIView? {
get { self.getInMemoryUserInfo(key: Self.messageTemplateCarouselView, defaultValue: nil) }
set { self.setInMemoryUserInfo(key: Self.messageTemplateCarouselView, data: newValue) }
Expand Down
81 changes: 72 additions & 9 deletions Sources/Extension/ChatSDK/BaseMessage+SBUIKit.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,19 +50,82 @@ extension BaseMessage {

/// container type of message template
/// - Since: 3.21.0
public var asUiSettingContainerType: SBUMessageContainerType {
if self.hasMessageTemplateCompositeType == true { return .full }

switch self.asExtendedMessagePayload?.uiSettings?.containerType {
case .wide: return .wide
case .full: return self.hasMessageTemplate ? .full : .`default`
default: return .`default`
}
}
@available(*, deprecated, message: "`asUiSettingContainerType` has been deprecated since 3.27.2.")
public var asUiSettingContainerType: SBUMessageContainerType { .`default` }

/// Function to decode to custom view data using genric type.
/// - Since: 3.11.0
public func decodeCustomViewData<ViewData: Decodable>() throws -> ViewData? {
try self.asExtendedMessagePayload?.decodeCustomViewData()
}

/// Indicates if the message is a stream (being updated) message.
/// - Since: 3.26.0
public var isStreamMessage: Bool {
StreamData.make(self).stream == true
}
}

extension BaseMessage {
func setInMemoryUserInfo<Element>(key: String, data: Element) {
var memory = self.inMemoryUserInfo ?? [:]
memory[key] = data
self.inMemoryUserInfo = memory
}

func getInMemoryUserInfo<Element>(key: String) -> Element? {
self.inMemoryUserInfo?[key] as? Element
}

func getInMemoryUserInfo<Element>(key: String, defaultValue: Element) -> Element {
self.inMemoryUserInfo?[key] as? Element ?? defaultValue
}

fileprivate struct StreamData: Codable {
let stream: Bool?

static func make(_ message: BaseMessage) -> StreamData {
guard let jsonData = message.data.data(using: .utf8) else { return StreamData(stream: false) }
return (try? JSONDecoder().decode(StreamData.self, from: jsonData)) ?? StreamData(stream: false)
}
}
}

extension BaseMessage {
/// A value that determines whether to disable the MessageInputView.
/// Additionally, other properties are checked as well.
/// - Since: 3.27.0
@available(*, deprecated, message: "Use `getChatInputDisableState(hasNext:)` in [BaseMessage]") // 3.27.2
public func getChatInputDisabledState(hasNext: Bool?) -> Bool {
getChatInputDisableType(hasNext: hasNext) != .none
}

func getChatInputDisableType(hasNext: Bool?) -> ChatInputDisableType {
guard let extendedMessagePayload = self.asExtendedMessagePayload else { return .none }
guard extendedMessagePayload.disableChatInput == true else { return .none }

if hasNext == true { return .none }

if let form = self.messageForm,
form.isValidVersion == true,
form.isSubmitted == false,
SendbirdUI.config.groupChannel.channel.isFormTypeMessageEnabled == true {
return .component // message form => component
}

if extendedMessagePayload.suggestedReplies?.hasElements == true,
SendbirdUI.config.groupChannel.channel.isSuggestedRepliesEnabled == true {
return .component // suggested replies => component
}

// normal message => not component
return .message
}

enum ChatInputDisableType {
case component
case message
case none
}

}
Loading