From 8e62dc6ff0265ba3dd3a91a32d9b88619315faea Mon Sep 17 00:00:00 2001 From: Stream Bot Date: Fri, 22 Nov 2024 16:46:34 +0100 Subject: [PATCH 1/5] Added an AI rendering library --- Package.swift | 12 + .../CodeSyntaxHighlighter.swift | 30 ++ .../StreamAITextView.swift | 202 ++++++++++ .../StreamChatAISwiftUI/StreamChatAISwiftUI.h | 15 + .../TextOutputFormat.swift | 49 +++ .../StreamChatAISwiftUITests.swift | 33 ++ StreamChatSwiftUI.xcodeproj/project.pbxproj | 381 +++++++++++++++++- .../xcschemes/xcschememanagement.plist | 5 + 8 files changed, 725 insertions(+), 2 deletions(-) create mode 100644 Sources/StreamChatAISwiftUI/CodeSyntaxHighlighter.swift create mode 100644 Sources/StreamChatAISwiftUI/StreamAITextView.swift create mode 100644 Sources/StreamChatAISwiftUI/StreamChatAISwiftUI.h create mode 100644 Sources/StreamChatAISwiftUI/TextOutputFormat.swift create mode 100644 StreamChatAISwiftUITests/StreamChatAISwiftUITests.swift diff --git a/Package.swift b/Package.swift index d61121b0e..791f241f1 100644 --- a/Package.swift +++ b/Package.swift @@ -13,10 +13,16 @@ let package = Package( .library( name: "StreamChatSwiftUI", targets: ["StreamChatSwiftUI"] + ), + .library( + name: "StreamChatAISwiftUI", + targets: ["StreamChatAISwiftUI"] ) ], dependencies: [ .package(url: "https://github.com/GetStream/stream-chat-swift.git", from: "4.66.0"), + .package(url: "https://github.com/JohnSundell/Splash.git", from: "0.16.0"), + .package(url: "https://github.com/gonzalezreal/swift-markdown-ui.git", from: "2.4.1") ], targets: [ .target( @@ -24,6 +30,12 @@ let package = Package( dependencies: [.product(name: "StreamChat", package: "stream-chat-swift")], exclude: ["README.md", "Info.plist", "Generated/L10n_template.stencil"], resources: [.process("Resources")] + ), + .target( + name: "StreamChatAISwiftUI", + dependencies: [.product(name: "Splash", package: "Splash"), .product(name: "MarkdownUI", package: "swift-markdown-ui")], + exclude: [], + resources: [] ) ] ) diff --git a/Sources/StreamChatAISwiftUI/CodeSyntaxHighlighter.swift b/Sources/StreamChatAISwiftUI/CodeSyntaxHighlighter.swift new file mode 100644 index 000000000..089636f35 --- /dev/null +++ b/Sources/StreamChatAISwiftUI/CodeSyntaxHighlighter.swift @@ -0,0 +1,30 @@ +// +// Copyright © 2024 Stream.io Inc. All rights reserved. +// + +internal import MarkdownUI +internal import Splash +import SwiftUI + +struct SplashCodeSyntaxHighlighter: CodeSyntaxHighlighter { + private let syntaxHighlighter: SyntaxHighlighter + + init(theme: Splash.Theme) { + self.syntaxHighlighter = SyntaxHighlighter(format: TextOutputFormat(theme: theme)) + } + + func highlightCode(_ content: String, language: String?) -> Text { + guard language != nil else { + return Text(content) + } + + return self.syntaxHighlighter.highlight(content) + } +} + +extension CodeSyntaxHighlighter where Self == SplashCodeSyntaxHighlighter { + static func splash(theme: Splash.Theme) -> Self { + SplashCodeSyntaxHighlighter(theme: theme) + } +} + diff --git a/Sources/StreamChatAISwiftUI/StreamAITextView.swift b/Sources/StreamChatAISwiftUI/StreamAITextView.swift new file mode 100644 index 000000000..9d1140f6e --- /dev/null +++ b/Sources/StreamChatAISwiftUI/StreamAITextView.swift @@ -0,0 +1,202 @@ +// +// Copyright © 2024 Stream.io Inc. All rights reserved. +// + +import Combine +import SwiftUI +internal import MarkdownUI +internal import Splash + +public struct StreamAITextView: View { + + var content: String + var isGenerating: Bool + + @State private var displayedText: String = "" + @State private var characterQueue: [Character] = [] + @State private var typingTimer: Timer? + @State private var chunkTimer: Timer? + @State var queue = DispatchQueue(label: "com.streamai.textview") + + public init(content: String, isGenerating: Bool) { + self.content = content + self.isGenerating = isGenerating + } + + public var body: some View { + Markdown(displayedText) + .markdownBlockStyle(\.codeBlock) { + codeBlock($0) + } + .markdownCodeSyntaxHighlighter(.splash(theme: self.theme)) + .onAppear { + if !isGenerating { + self.displayedText = content + return + } + if self.characterQueue.isEmpty { + self.characterQueue.append(contentsOf: content) + } + startTypingTimer() + } + .onDisappear { + typingTimer?.invalidate() + chunkTimer?.invalidate() + } + .onChange(of: characterQueue, perform: { newValue in + if characterQueue.isEmpty && !isGenerating { + self.displayedText = content + } + }) + .addChangeListeners( + content: content, + isGenerating: isGenerating, + onContentChange: { oldValue, newValue in + queue.sync { + if !isGenerating { + if oldValue.isEmpty && !newValue.isEmpty { + self.displayedText = newValue + } + return + } + let newChunk = getNewChunk(oldText: oldValue, newText: newValue) + self.characterQueue.append(contentsOf: newChunk) + } + }, + onIsGeneratingChange: { oldValue, newValue in + queue.sync { + if newValue { + if typingTimer == nil { + if self.characterQueue.isEmpty { + self.characterQueue.append(contentsOf: content) + } + startTypingTimer() + } + } else if oldValue && !newValue { + let newChunk = getNewChunk(oldText: displayedText, newText: content) + self.characterQueue.append(contentsOf: newChunk) + } + } + } + ) + } + + func getNewChunk(oldText: String, newText: String) -> String { + if newText.hasPrefix(oldText) { + // Old text is a prefix of new text + let startIndex = newText.index(newText.startIndex, offsetBy: oldText.count) + let newChunk = String(newText[startIndex...]) + return newChunk + } else { + // Find the longest common prefix + let commonPrefix = oldText.commonPrefix(with: newText) + let startIndex = newText.index(newText.startIndex, offsetBy: commonPrefix.count) + let newChunk = String(newText[startIndex...]) + return newChunk + } + } + + func startTypingTimer() { + typingTimer = Timer.scheduledTimer(withTimeInterval: 0.005, repeats: true) { _ in + guard !self.characterQueue.isEmpty else { return } + let nextCharacter = self.characterQueue.removeFirst() + self.displayedText.append(nextCharacter) + } + } + + @ViewBuilder + private func codeBlock(_ configuration: CodeBlockConfiguration) -> some View { + VStack(spacing: 0) { + HStack { + Text(configuration.language ?? "plain text") + .font(.system(.caption, design: .monospaced)) + .fontWeight(.semibold) + .foregroundColor(Color(theme.plainTextColor)) + Spacer() + + Image(systemName: "clipboard") + .onTapGesture { + copyToClipboard(configuration.content) + } + } + .padding(.horizontal) + .padding(.vertical, 8) + .background { + Color(theme.backgroundColor) + } + + Divider() + + ScrollView(.horizontal) { + configuration.label + .relativeLineSpacing(.em(0.25)) + .markdownTextStyle { + FontFamilyVariant(.monospaced) + FontSize(.em(0.85)) + } + .padding() + } + } + .background(Color(.secondarySystemBackground)) + .clipShape(RoundedRectangle(cornerRadius: 8)) + .markdownMargin(top: .zero, bottom: .em(0.8)) + } + + private var theme: Splash.Theme { + .sunset(withFont: .init(size: 16)) + } + + private func copyToClipboard(_ string: String) { + UIPasteboard.general.string = string + } +} + +struct StreamAITextViewChangeListeners: ViewModifier { + + @State var previousValue: String = "" + + var text: String + var isGenerating: Bool + + var onContentChange: (_ oldValue: String, _ newValue: String) -> Void + var onIsGeneratingChange: (_ oldValue: Bool, _ newValue: Bool) -> Void + + func body(content: Content) -> some View { + if #available(iOS 17.0, *) { + content + .onChange(of: text) { oldValue, newValue in + onContentChange(oldValue, newValue) + } + .onChange(of: isGenerating) { oldValue, newValue in + onIsGeneratingChange(oldValue, newValue) + } + } else { + content + .onChange(of: text) { newValue in + onContentChange(previousValue, newValue) + previousValue = newValue + } + .onChange(of: isGenerating) { newValue in + onIsGeneratingChange(!newValue, newValue) + } + } + } +} + +extension View { + func addChangeListeners( + content: String, + isGenerating: Bool, + onContentChange: @escaping (_ oldValue: String, _ newValue: String) -> Void, + onIsGeneratingChange: @escaping (_ oldValue: Bool, _ newValue: Bool) -> Void + ) -> some View { + self.modifier( + StreamAITextViewChangeListeners( + text: content, + isGenerating: isGenerating, + onContentChange: onContentChange, + onIsGeneratingChange: onIsGeneratingChange + ) + ) + } +} diff --git a/Sources/StreamChatAISwiftUI/StreamChatAISwiftUI.h b/Sources/StreamChatAISwiftUI/StreamChatAISwiftUI.h new file mode 100644 index 000000000..16dd6c66d --- /dev/null +++ b/Sources/StreamChatAISwiftUI/StreamChatAISwiftUI.h @@ -0,0 +1,15 @@ +// +// Copyright © 2024 Stream.io Inc. All rights reserved. +// + +#import + +//! Project version number for StreamChatAISwiftUI. +FOUNDATION_EXPORT double StreamChatAISwiftUIVersionNumber; + +//! Project version string for StreamChatAISwiftUI. +FOUNDATION_EXPORT const unsigned char StreamChatAISwiftUIVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/Sources/StreamChatAISwiftUI/TextOutputFormat.swift b/Sources/StreamChatAISwiftUI/TextOutputFormat.swift new file mode 100644 index 000000000..ae9b9e3ec --- /dev/null +++ b/Sources/StreamChatAISwiftUI/TextOutputFormat.swift @@ -0,0 +1,49 @@ +// +// Copyright © 2024 Stream.io Inc. All rights reserved. +// + +internal import Splash +import SwiftUI + +struct TextOutputFormat: OutputFormat { + private let theme: Theme + + init(theme: Theme) { + self.theme = theme + } + + func makeBuilder() -> Builder { + Builder(theme: self.theme) + } +} + +extension TextOutputFormat { + struct Builder: OutputBuilder { + private let theme: Theme + private var accumulatedText: [Text] + + fileprivate init(theme: Theme) { + self.theme = theme + self.accumulatedText = [] + } + + mutating func addToken(_ token: String, ofType type: TokenType) { + let color = self.theme.tokenColors[type] ?? self.theme.plainTextColor + self.accumulatedText.append(Text(token).foregroundColor(.init(uiColor: color))) + } + + mutating func addPlainText(_ text: String) { + self.accumulatedText.append( + Text(text).foregroundColor(.init(uiColor: self.theme.plainTextColor)) + ) + } + + mutating func addWhitespace(_ whitespace: String) { + self.accumulatedText.append(Text(whitespace)) + } + + func build() -> Text { + self.accumulatedText.reduce(Text(""), +) + } + } +} diff --git a/StreamChatAISwiftUITests/StreamChatAISwiftUITests.swift b/StreamChatAISwiftUITests/StreamChatAISwiftUITests.swift new file mode 100644 index 000000000..7c20421bc --- /dev/null +++ b/StreamChatAISwiftUITests/StreamChatAISwiftUITests.swift @@ -0,0 +1,33 @@ +// +// Copyright © 2024 Stream.io Inc. All rights reserved. +// + +import XCTest +@testable import StreamChatAISwiftUI + +final class StreamChatAISwiftUITests: XCTestCase { + + override func setUpWithError() throws { + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDownWithError() throws { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + func testExample() throws { + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct results. + // Any test you write for XCTest can be annotated as throws and async. + // Mark your test throws to produce an unexpected failure when your test encounters an uncaught error. + // Mark your test async to allow awaiting for asynchronous code to complete. Check the results with assertions afterwards. + } + + func testPerformanceExample() throws { + // This is an example of a performance test case. + self.measure { + // Put the code you want to measure the time of here. + } + } + +} diff --git a/StreamChatSwiftUI.xcodeproj/project.pbxproj b/StreamChatSwiftUI.xcodeproj/project.pbxproj index 09620d43e..f3f3eb9c2 100644 --- a/StreamChatSwiftUI.xcodeproj/project.pbxproj +++ b/StreamChatSwiftUI.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 55; + objectVersion = 70; objects = { /* Begin PBXBuildFile section */ @@ -326,6 +326,9 @@ 846B8E2C2C5B8117006A6249 /* BlockedUsersView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 846B8E2B2C5B8117006A6249 /* BlockedUsersView.swift */; }; 846B8E2E2C5B8130006A6249 /* BlockedUsersViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 846B8E2D2C5B8130006A6249 /* BlockedUsersViewModel.swift */; }; 846D6564279FF0800094B36E /* ReactionUserView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 846D6563279FF0800094B36E /* ReactionUserView.swift */; }; + 846FC1BC2CF0DBC30087C9CD /* StreamChatAISwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 846FC1B42CF0DBC30087C9CD /* StreamChatAISwiftUI.framework */; }; + 846FC1CE2CF0DC2A0087C9CD /* Splash in Frameworks */ = {isa = PBXBuildFile; productRef = 846FC1CD2CF0DC2A0087C9CD /* Splash */; }; + 846FC1D12CF0DC4C0087C9CD /* MarkdownUI in Frameworks */ = {isa = PBXBuildFile; productRef = 846FC1D02CF0DC4C0087C9CD /* MarkdownUI */; }; 847110B628611033004A46D6 /* MessageActions_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 840008BA27E8D64A00282D88 /* MessageActions_Tests.swift */; }; 847305BB28241D8D004AC770 /* ChatChannelHeader_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 847305BA28241D8D004AC770 /* ChatChannelHeader_Tests.swift */; }; 847305BD28243D25004AC770 /* WebView_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 847305BC28243D25004AC770 /* WebView_Tests.swift */; }; @@ -555,6 +558,13 @@ remoteGlobalIDString = 8465FBB42746873A00AF091E; remoteInfo = StreamChatSwiftUI; }; + 846FC1BD2CF0DBC30087C9CD /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 8465FBAC2746873A00AF091E /* Project object */; + proxyType = 1; + remoteGlobalIDString = 846FC1B32CF0DBC20087C9CD; + remoteInfo = StreamChatAISwiftUI; + }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -913,6 +923,8 @@ 846B8E2B2C5B8117006A6249 /* BlockedUsersView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlockedUsersView.swift; sourceTree = ""; }; 846B8E2D2C5B8130006A6249 /* BlockedUsersViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlockedUsersViewModel.swift; sourceTree = ""; }; 846D6563279FF0800094B36E /* ReactionUserView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReactionUserView.swift; sourceTree = ""; }; + 846FC1B42CF0DBC30087C9CD /* StreamChatAISwiftUI.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = StreamChatAISwiftUI.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 846FC1BB2CF0DBC30087C9CD /* StreamChatAISwiftUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = StreamChatAISwiftUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 847305BA28241D8D004AC770 /* ChatChannelHeader_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatChannelHeader_Tests.swift; sourceTree = ""; }; 847305BC28243D25004AC770 /* WebView_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebView_Tests.swift; sourceTree = ""; }; 847305BE28243DF9004AC770 /* mock.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = mock.html; sourceTree = ""; }; @@ -1116,6 +1128,21 @@ C14A465A284665B100EF498E /* SDKIdentifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SDKIdentifier.swift; sourceTree = ""; }; /* End PBXFileReference section */ +/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */ + 846FC1C92CF0DBC30087C9CD /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + publicHeaders = ( + StreamChatAISwiftUI.h, + ); + target = 846FC1B32CF0DBC20087C9CD /* StreamChatAISwiftUI */; + }; +/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */ + +/* Begin PBXFileSystemSynchronizedRootGroup section */ + 846FC1B52CF0DBC30087C9CD /* StreamChatAISwiftUI */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (846FC1C92CF0DBC30087C9CD /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = StreamChatAISwiftUI; sourceTree = ""; }; + 846FC1BF2CF0DBC30087C9CD /* StreamChatAISwiftUITests */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = StreamChatAISwiftUITests; sourceTree = ""; }; +/* End PBXFileSystemSynchronizedRootGroup section */ + /* Begin PBXFrameworksBuildPhase section */ 8400A34E282E6BE30067D3A0 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; @@ -1166,6 +1193,23 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 846FC1B12CF0DBC20087C9CD /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 846FC1CE2CF0DC2A0087C9CD /* Splash in Frameworks */, + 846FC1D12CF0DC4C0087C9CD /* MarkdownUI in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 846FC1B82CF0DBC30087C9CD /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 846FC1BC2CF0DBC30087C9CD /* StreamChatAISwiftUI.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -1557,6 +1601,7 @@ 8465FCBD27468B6900AF091E /* DemoAppSwiftUI */, 8402EAC4282BF69900CCA696 /* StreamChatSwiftUITestsApp */, 8400A352282E6BE30067D3A0 /* StreamChatSwiftUITestsAppTests */, + 846FC1BF2CF0DBC30087C9CD /* StreamChatAISwiftUITests */, 8465FCE5274695B400AF091E /* Frameworks */, ); sourceTree = ""; @@ -1569,6 +1614,8 @@ 8465FCBC27468B6900AF091E /* DemoAppSwiftUI.app */, 8402EAC3282BF69900CCA696 /* StreamChatSwiftUITestsApp.app */, 8400A351282E6BE30067D3A0 /* StreamChatSwiftUITestsAppTests.xctest */, + 846FC1B42CF0DBC30087C9CD /* StreamChatAISwiftUI.framework */, + 846FC1BB2CF0DBC30087C9CD /* StreamChatAISwiftUITests.xctest */, ); name = Products; path = ..; @@ -1578,6 +1625,7 @@ isa = PBXGroup; children = ( 8465FCEB2746A95600AF091E /* StreamChatSwiftUI */, + 846FC1B52CF0DBC30087C9CD /* StreamChatAISwiftUI */, ); path = Sources; sourceTree = ""; @@ -2285,6 +2333,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 846FC1AF2CF0DBC20087C9CD /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ @@ -2403,6 +2458,54 @@ productReference = 8465FCBC27468B6900AF091E /* DemoAppSwiftUI.app */; productType = "com.apple.product-type.application"; }; + 846FC1B32CF0DBC20087C9CD /* StreamChatAISwiftUI */ = { + isa = PBXNativeTarget; + buildConfigurationList = 846FC1CA2CF0DBC30087C9CD /* Build configuration list for PBXNativeTarget "StreamChatAISwiftUI" */; + buildPhases = ( + 846FC1AF2CF0DBC20087C9CD /* Headers */, + 846FC1B02CF0DBC20087C9CD /* Sources */, + 846FC1B12CF0DBC20087C9CD /* Frameworks */, + 846FC1B22CF0DBC20087C9CD /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + fileSystemSynchronizedGroups = ( + 846FC1B52CF0DBC30087C9CD /* StreamChatAISwiftUI */, + ); + name = StreamChatAISwiftUI; + packageProductDependencies = ( + 846FC1CD2CF0DC2A0087C9CD /* Splash */, + 846FC1D02CF0DC4C0087C9CD /* MarkdownUI */, + ); + productName = StreamChatAISwiftUI; + productReference = 846FC1B42CF0DBC30087C9CD /* StreamChatAISwiftUI.framework */; + productType = "com.apple.product-type.framework"; + }; + 846FC1BA2CF0DBC30087C9CD /* StreamChatAISwiftUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 846FC1CB2CF0DBC30087C9CD /* Build configuration list for PBXNativeTarget "StreamChatAISwiftUITests" */; + buildPhases = ( + 846FC1B72CF0DBC30087C9CD /* Sources */, + 846FC1B82CF0DBC30087C9CD /* Frameworks */, + 846FC1B92CF0DBC30087C9CD /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 846FC1BE2CF0DBC30087C9CD /* PBXTargetDependency */, + ); + fileSystemSynchronizedGroups = ( + 846FC1BF2CF0DBC30087C9CD /* StreamChatAISwiftUITests */, + ); + name = StreamChatAISwiftUITests; + packageProductDependencies = ( + ); + productName = StreamChatAISwiftUITests; + productReference = 846FC1BB2CF0DBC30087C9CD /* StreamChatAISwiftUITests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -2410,7 +2513,7 @@ isa = PBXProject; attributes = { BuildIndependentTargetsInParallel = 1; - LastSwiftUpdateCheck = 1330; + LastSwiftUpdateCheck = 1610; LastUpgradeCheck = 1330; TargetAttributes = { 8400A350282E6BE30067D3A0 = { @@ -2431,6 +2534,12 @@ 8465FCBB27468B6900AF091E = { CreatedOnToolsVersion = 13.1; }; + 846FC1B32CF0DBC20087C9CD = { + CreatedOnToolsVersion = 16.1; + }; + 846FC1BA2CF0DBC30087C9CD = { + CreatedOnToolsVersion = 16.1; + }; }; }; buildConfigurationList = 8465FBAF2746873A00AF091E /* Build configuration list for PBXProject "StreamChatSwiftUI" */; @@ -2447,6 +2556,8 @@ 8400A346282C06F90067D3A0 /* XCRemoteSwiftPackageReference "OHHTTPStubs" */, 84E95A75284A486600699FD3 /* XCRemoteSwiftPackageReference "stream-chat-swift" */, 82543C7B2AD41B0400D5F6CD /* XCRemoteSwiftPackageReference "stream-chat-swift-test-helpers" */, + 846FC1CC2CF0DC2A0087C9CD /* XCRemoteSwiftPackageReference "Splash" */, + 846FC1CF2CF0DC4C0087C9CD /* XCRemoteSwiftPackageReference "swift-markdown-ui" */, ); productRefGroup = 8465FBB62746873A00AF091E /* Products */; projectDirPath = ""; @@ -2457,6 +2568,8 @@ 8465FCBB27468B6900AF091E /* DemoAppSwiftUI */, 8402EAC2282BF69900CCA696 /* StreamChatSwiftUITestsApp */, 8400A350282E6BE30067D3A0 /* StreamChatSwiftUITestsAppTests */, + 846FC1B32CF0DBC20087C9CD /* StreamChatAISwiftUI */, + 846FC1BA2CF0DBC30087C9CD /* StreamChatAISwiftUITests */, ); }; /* End PBXProject section */ @@ -2509,6 +2622,20 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 846FC1B22CF0DBC20087C9CD /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 846FC1B92CF0DBC30087C9CD /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ @@ -3056,6 +3183,20 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 846FC1B02CF0DBC20087C9CD /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 846FC1B72CF0DBC30087C9CD /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ @@ -3084,6 +3225,11 @@ target = 8465FBB42746873A00AF091E /* StreamChatSwiftUI */; targetProxy = 8465FCE8274695B400AF091E /* PBXContainerItemProxy */; }; + 846FC1BE2CF0DBC30087C9CD /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 846FC1B32CF0DBC20087C9CD /* StreamChatAISwiftUI */; + targetProxy = 846FC1BD2CF0DBC30087C9CD /* PBXContainerItemProxy */; + }; /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ @@ -3726,6 +3872,191 @@ }; name = Release; }; + 846FC1C32CF0DBC30087C9CD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + BUILD_LIBRARY_FOR_DISTRIBUTION = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = EHV7XZLAHA; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_MODULE_VERIFIER = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MARKETING_VERSION = 1.0; + MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; + MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20"; + PRODUCT_BUNDLE_IDENTIFIER = io.getstream.StreamChatAISwiftUI; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_INSTALL_OBJC_HEADER = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 846FC1C42CF0DBC30087C9CD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + BUILD_LIBRARY_FOR_DISTRIBUTION = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = EHV7XZLAHA; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_MODULE_VERIFIER = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MARKETING_VERSION = 1.0; + MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; + MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20"; + PRODUCT_BUNDLE_IDENTIFIER = io.getstream.StreamChatAISwiftUI; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_INSTALL_OBJC_HEADER = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + 846FC1C52CF0DBC30087C9CD /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + BUILD_LIBRARY_FOR_DISTRIBUTION = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = EHV7XZLAHA; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_MODULE_VERIFIER = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MARKETING_VERSION = 1.0; + MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; + MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20"; + PRODUCT_BUNDLE_IDENTIFIER = io.getstream.StreamChatAISwiftUI; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_INSTALL_OBJC_HEADER = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Profile; + }; + 846FC1C62CF0DBC30087C9CD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = EHV7XZLAHA; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 18.1; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = io.getstream.StreamChatAISwiftUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 846FC1C72CF0DBC30087C9CD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = EHV7XZLAHA; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 18.1; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = io.getstream.StreamChatAISwiftUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + 846FC1C82CF0DBC30087C9CD /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = EHV7XZLAHA; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 18.1; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = io.getstream.StreamChatAISwiftUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Profile; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -3789,6 +4120,26 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 846FC1CA2CF0DBC30087C9CD /* Build configuration list for PBXNativeTarget "StreamChatAISwiftUI" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 846FC1C32CF0DBC30087C9CD /* Debug */, + 846FC1C42CF0DBC30087C9CD /* Release */, + 846FC1C52CF0DBC30087C9CD /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 846FC1CB2CF0DBC30087C9CD /* Build configuration list for PBXNativeTarget "StreamChatAISwiftUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 846FC1C62CF0DBC30087C9CD /* Debug */, + 846FC1C72CF0DBC30087C9CD /* Release */, + 846FC1C82CF0DBC30087C9CD /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ /* Begin XCRemoteSwiftPackageReference section */ @@ -3816,6 +4167,22 @@ version = 4.10.1; }; }; + 846FC1CC2CF0DC2A0087C9CD /* XCRemoteSwiftPackageReference "Splash" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/JohnSundell/Splash.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 0.16.0; + }; + }; + 846FC1CF2CF0DC4C0087C9CD /* XCRemoteSwiftPackageReference "swift-markdown-ui" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/gonzalezreal/swift-markdown-ui.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 2.4.1; + }; + }; 84E95A75284A486600699FD3 /* XCRemoteSwiftPackageReference "stream-chat-swift" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/GetStream/stream-chat-swift.git"; @@ -3870,6 +4237,16 @@ package = 84E95A75284A486600699FD3 /* XCRemoteSwiftPackageReference "stream-chat-swift" */; productName = StreamChatTestTools; }; + 846FC1CD2CF0DC2A0087C9CD /* Splash */ = { + isa = XCSwiftPackageProductDependency; + package = 846FC1CC2CF0DC2A0087C9CD /* XCRemoteSwiftPackageReference "Splash" */; + productName = Splash; + }; + 846FC1D02CF0DC4C0087C9CD /* MarkdownUI */ = { + isa = XCSwiftPackageProductDependency; + package = 846FC1CF2CF0DC4C0087C9CD /* XCRemoteSwiftPackageReference "swift-markdown-ui" */; + productName = MarkdownUI; + }; 84B87F222861C0C900959CBE /* StreamChat */ = { isa = XCSwiftPackageProductDependency; package = 84E95A75284A486600699FD3 /* XCRemoteSwiftPackageReference "stream-chat-swift" */; diff --git a/StreamChatSwiftUI.xcodeproj/xcuserdata/martinmitrevski.xcuserdatad/xcschemes/xcschememanagement.plist b/StreamChatSwiftUI.xcodeproj/xcuserdata/martinmitrevski.xcuserdatad/xcschemes/xcschememanagement.plist index 564e79e93..b70bdbadb 100644 --- a/StreamChatSwiftUI.xcodeproj/xcuserdata/martinmitrevski.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/StreamChatSwiftUI.xcodeproj/xcuserdata/martinmitrevski.xcuserdatad/xcschemes/xcschememanagement.plist @@ -48,6 +48,11 @@ isShown + orderHint + 3 + + StreamChatAISwiftUI.xcscheme_^#shared#^_ + orderHint 4 From 0c5ccf02cf7ab6635a60eeab709d2f1234167355 Mon Sep 17 00:00:00 2001 From: Stream Bot Date: Fri, 22 Nov 2024 17:16:50 +0100 Subject: [PATCH 2/5] Updated package.swift --- Package.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Package.swift b/Package.swift index 791f241f1..dc3ee8a15 100644 --- a/Package.swift +++ b/Package.swift @@ -16,7 +16,8 @@ let package = Package( ), .library( name: "StreamChatAISwiftUI", - targets: ["StreamChatAISwiftUI"] + targets: ["StreamChatAISwiftUI"], + condition: .when(platform: .iOS, version: .v15) ) ], dependencies: [ From 759cfa9ef417bd7b0f2a084aa18f523613cfa609 Mon Sep 17 00:00:00 2001 From: Stream Bot Date: Fri, 22 Nov 2024 17:22:45 +0100 Subject: [PATCH 3/5] Updated the package file --- Package.swift | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/Package.swift b/Package.swift index dc3ee8a15..12aeb27a7 100644 --- a/Package.swift +++ b/Package.swift @@ -1,13 +1,12 @@ // swift-tools-version:5.9 -import Foundation import PackageDescription let package = Package( name: "StreamChatSwiftUI", defaultLocalization: "en", platforms: [ - .iOS(.v14), .macOS(.v11) + .iOS(.v14), .macOS(.v11) // General platform settings ], products: [ .library( @@ -16,8 +15,7 @@ let package = Package( ), .library( name: "StreamChatAISwiftUI", - targets: ["StreamChatAISwiftUI"], - condition: .when(platform: .iOS, version: .v15) + targets: ["StreamChatAISwiftUI"] ) ], dependencies: [ @@ -28,15 +26,23 @@ let package = Package( targets: [ .target( name: "StreamChatSwiftUI", - dependencies: [.product(name: "StreamChat", package: "stream-chat-swift")], + dependencies: [ + .product(name: "StreamChat", package: "stream-chat-swift") + ], exclude: ["README.md", "Info.plist", "Generated/L10n_template.stencil"], resources: [.process("Resources")] ), .target( name: "StreamChatAISwiftUI", - dependencies: [.product(name: "Splash", package: "Splash"), .product(name: "MarkdownUI", package: "swift-markdown-ui")], + dependencies: [ + .product(name: "Splash", package: "Splash"), + .product(name: "MarkdownUI", package: "swift-markdown-ui") + ], exclude: [], - resources: [] + resources: [], + swiftSettings: [ + .define("PLATFORM_IOS15_OR_LATER") + ] ) ] ) @@ -45,4 +51,4 @@ let package = Package( package.dependencies.append( .package(url: "https://github.com/apple/swift-docc-plugin", from: "1.0.0") ) -#endif +#endif \ No newline at end of file From 2804179294d8236dbc51da9de4ebeea1a9a20641 Mon Sep 17 00:00:00 2001 From: Stream Bot Date: Mon, 25 Nov 2024 17:41:43 +0100 Subject: [PATCH 4/5] Embed dependencies --- Makefile | 12 ++++++ Scripts/updateDependency.sh | 4 ++ .../Nuke/Processing/ImageDecompression.swift | 8 +--- .../NukeExtensions/ImageViewExtensions.swift | 9 +---- .../StreamNuke/NukeUI/LazyImage.swift | 6 +++ StreamChatSwiftUI.xcodeproj/project.pbxproj | 40 ++----------------- 6 files changed, 29 insertions(+), 50 deletions(-) diff --git a/Makefile b/Makefile index 461beee44..3e84c2d95 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,10 @@ update_dependencies: make update_nuke version=11.3.1 echo "👉 Updating SwiftyGif" make update_swiftygif version=5.4.2 + echo "👉 Updating MarkdownUI" + make update_markdown_ui version=2.4.1 + echo "👉 Updating Splash" + make update_splash version=0.16.0 update_nuke: check_version_parameter ./Scripts/updateDependency.sh $(version) Dependencies/Nuke Sources/StreamChatSwiftUI/StreamNuke Sources @@ -14,6 +18,14 @@ update_swiftygif: check_version_parameter ./Scripts/updateDependency.sh $(version) Dependencies/SwiftyGif Sources/StreamChatSwiftUI/StreamSwiftyGif SwiftyGif ./Scripts/removePublicDeclarations.sh Sources/StreamChatSwiftUI/StreamSwiftyGif +update_markdown_ui: check_version_parameter + ./Scripts/updateDependency.sh $(version) Dependencies/MarkdownUI Sources/StreamChatAISwiftUI/MarkdownUI Sources + ./Scripts/removePublicDeclarations.sh Sources/StreamChatAISwiftUI/StreamMarkdownUI + +update_splash: check_version_parameter + ./Scripts/updateDependency.sh $(version) Dependencies/Splash Sources/StreamChatAISwiftUI/Splash Sources + ./Scripts/removePublicDeclarations.sh Sources/StreamChatAISwiftUI/StreamSplash + check_version_parameter: @if [ "$(version)" = "" ]; then\ echo "❌ Missing version parameter"; \ diff --git a/Scripts/updateDependency.sh b/Scripts/updateDependency.sh index e71419e42..82cddecb0 100755 --- a/Scripts/updateDependency.sh +++ b/Scripts/updateDependency.sh @@ -24,6 +24,10 @@ if [[ $dependency_directory == *"Nuke"* ]]; then dependency_url="git@github.com:kean/Nuke.git" elif [[ $dependency_directory == *"SwiftyGif"* ]]; then dependency_url="git@github.com:kirualex/SwiftyGif.git" +elif [[ $dependency_directory == *"Splash"* ]]; then + dependency_url="git@github.com:JohnSundell/Splash.git" +elif [[ $dependency_directory == *"MarkdownUI"* ]]; then + dependency_url="git@github.com:gonzalezreal/swift-markdown-ui.git" else echo "→ Unknown dependency at $dependency_directory" exit 1 diff --git a/Sources/StreamChatSwiftUI/StreamNuke/Nuke/Processing/ImageDecompression.swift b/Sources/StreamChatSwiftUI/StreamNuke/Nuke/Processing/ImageDecompression.swift index d9db20145..5b2870749 100644 --- a/Sources/StreamChatSwiftUI/StreamNuke/Nuke/Processing/ImageDecompression.swift +++ b/Sources/StreamChatSwiftUI/StreamNuke/Nuke/Processing/ImageDecompression.swift @@ -15,14 +15,10 @@ enum ImageDecompression { static var isDecompressionNeededAK = "ImageDecompressor.isDecompressionNeeded.AssociatedKey" static func setDecompressionNeeded(_ isDecompressionNeeded: Bool, for image: PlatformImage) { - withUnsafePointer(to: &isDecompressionNeededAK) { keyPointer in - objc_setAssociatedObject(image, keyPointer, isDecompressionNeeded, .OBJC_ASSOCIATION_RETAIN) - } + objc_setAssociatedObject(image, &isDecompressionNeededAK, isDecompressionNeeded, .OBJC_ASSOCIATION_RETAIN) } static func isDecompressionNeeded(for image: PlatformImage) -> Bool? { - return withUnsafePointer(to: &isDecompressionNeededAK) { keyPointer in - objc_getAssociatedObject(image, keyPointer) as? Bool - } + objc_getAssociatedObject(image, &isDecompressionNeededAK) as? Bool } } diff --git a/Sources/StreamChatSwiftUI/StreamNuke/NukeExtensions/ImageViewExtensions.swift b/Sources/StreamChatSwiftUI/StreamNuke/NukeExtensions/ImageViewExtensions.swift index 2e6aa4d88..bc2c08659 100644 --- a/Sources/StreamChatSwiftUI/StreamNuke/NukeExtensions/ImageViewExtensions.swift +++ b/Sources/StreamChatSwiftUI/StreamNuke/NukeExtensions/ImageViewExtensions.swift @@ -172,16 +172,11 @@ private final class ImageViewController { // Lazily create a controller for a given view and associate it with a view. static func controller(for view: ImageDisplayingView) -> ImageViewController { - if let controller = withUnsafePointer(to: &ImageViewController.controllerAK, { keyPointer in - objc_getAssociatedObject(view, keyPointer) as? ImageViewController - }) { + if let controller = objc_getAssociatedObject(view, &ImageViewController.controllerAK) as? ImageViewController { return controller } - let controller = ImageViewController(view: view) - withUnsafePointer(to: &ImageViewController.controllerAK) { keyPointer in - objc_setAssociatedObject(view, keyPointer, controller, .OBJC_ASSOCIATION_RETAIN) - } + objc_setAssociatedObject(view, &ImageViewController.controllerAK, controller, .OBJC_ASSOCIATION_RETAIN) return controller } diff --git a/Sources/StreamChatSwiftUI/StreamNuke/NukeUI/LazyImage.swift b/Sources/StreamChatSwiftUI/StreamNuke/NukeUI/LazyImage.swift index 37fb2c32e..ad8922477 100644 --- a/Sources/StreamChatSwiftUI/StreamNuke/NukeUI/LazyImage.swift +++ b/Sources/StreamChatSwiftUI/StreamNuke/NukeUI/LazyImage.swift @@ -3,9 +3,15 @@ // Copyright (c) 2015-2021 Alexander Grebenyuk (github.com/kean). import Foundation + import SwiftUI import Combine + + + + + private struct HashableRequest: Hashable { let request: ImageRequest diff --git a/StreamChatSwiftUI.xcodeproj/project.pbxproj b/StreamChatSwiftUI.xcodeproj/project.pbxproj index f3f3eb9c2..d191e0722 100644 --- a/StreamChatSwiftUI.xcodeproj/project.pbxproj +++ b/StreamChatSwiftUI.xcodeproj/project.pbxproj @@ -327,8 +327,6 @@ 846B8E2E2C5B8130006A6249 /* BlockedUsersViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 846B8E2D2C5B8130006A6249 /* BlockedUsersViewModel.swift */; }; 846D6564279FF0800094B36E /* ReactionUserView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 846D6563279FF0800094B36E /* ReactionUserView.swift */; }; 846FC1BC2CF0DBC30087C9CD /* StreamChatAISwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 846FC1B42CF0DBC30087C9CD /* StreamChatAISwiftUI.framework */; }; - 846FC1CE2CF0DC2A0087C9CD /* Splash in Frameworks */ = {isa = PBXBuildFile; productRef = 846FC1CD2CF0DC2A0087C9CD /* Splash */; }; - 846FC1D12CF0DC4C0087C9CD /* MarkdownUI in Frameworks */ = {isa = PBXBuildFile; productRef = 846FC1D02CF0DC4C0087C9CD /* MarkdownUI */; }; 847110B628611033004A46D6 /* MessageActions_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 840008BA27E8D64A00282D88 /* MessageActions_Tests.swift */; }; 847305BB28241D8D004AC770 /* ChatChannelHeader_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 847305BA28241D8D004AC770 /* ChatChannelHeader_Tests.swift */; }; 847305BD28243D25004AC770 /* WebView_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 847305BC28243D25004AC770 /* WebView_Tests.swift */; }; @@ -1197,8 +1195,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 846FC1CE2CF0DC2A0087C9CD /* Splash in Frameworks */, - 846FC1D12CF0DC4C0087C9CD /* MarkdownUI in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2476,8 +2472,6 @@ ); name = StreamChatAISwiftUI; packageProductDependencies = ( - 846FC1CD2CF0DC2A0087C9CD /* Splash */, - 846FC1D02CF0DC4C0087C9CD /* MarkdownUI */, ); productName = StreamChatAISwiftUI; productReference = 846FC1B42CF0DBC30087C9CD /* StreamChatAISwiftUI.framework */; @@ -2556,8 +2550,6 @@ 8400A346282C06F90067D3A0 /* XCRemoteSwiftPackageReference "OHHTTPStubs" */, 84E95A75284A486600699FD3 /* XCRemoteSwiftPackageReference "stream-chat-swift" */, 82543C7B2AD41B0400D5F6CD /* XCRemoteSwiftPackageReference "stream-chat-swift-test-helpers" */, - 846FC1CC2CF0DC2A0087C9CD /* XCRemoteSwiftPackageReference "Splash" */, - 846FC1CF2CF0DC4C0087C9CD /* XCRemoteSwiftPackageReference "swift-markdown-ui" */, ); productRefGroup = 8465FBB62746873A00AF091E /* Products */; projectDirPath = ""; @@ -3891,7 +3883,7 @@ GENERATE_INFOPLIST_FILE = YES; INFOPLIST_KEY_NSHumanReadableCopyright = ""; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -3931,7 +3923,7 @@ GENERATE_INFOPLIST_FILE = YES; INFOPLIST_KEY_NSHumanReadableCopyright = ""; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -3970,7 +3962,7 @@ GENERATE_INFOPLIST_FILE = YES; INFOPLIST_KEY_NSHumanReadableCopyright = ""; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -4167,22 +4159,6 @@ version = 4.10.1; }; }; - 846FC1CC2CF0DC2A0087C9CD /* XCRemoteSwiftPackageReference "Splash" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/JohnSundell/Splash.git"; - requirement = { - kind = upToNextMajorVersion; - minimumVersion = 0.16.0; - }; - }; - 846FC1CF2CF0DC4C0087C9CD /* XCRemoteSwiftPackageReference "swift-markdown-ui" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/gonzalezreal/swift-markdown-ui.git"; - requirement = { - kind = upToNextMajorVersion; - minimumVersion = 2.4.1; - }; - }; 84E95A75284A486600699FD3 /* XCRemoteSwiftPackageReference "stream-chat-swift" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/GetStream/stream-chat-swift.git"; @@ -4237,16 +4213,6 @@ package = 84E95A75284A486600699FD3 /* XCRemoteSwiftPackageReference "stream-chat-swift" */; productName = StreamChatTestTools; }; - 846FC1CD2CF0DC2A0087C9CD /* Splash */ = { - isa = XCSwiftPackageProductDependency; - package = 846FC1CC2CF0DC2A0087C9CD /* XCRemoteSwiftPackageReference "Splash" */; - productName = Splash; - }; - 846FC1D02CF0DC4C0087C9CD /* MarkdownUI */ = { - isa = XCSwiftPackageProductDependency; - package = 846FC1CF2CF0DC4C0087C9CD /* XCRemoteSwiftPackageReference "swift-markdown-ui" */; - productName = MarkdownUI; - }; 84B87F222861C0C900959CBE /* StreamChat */ = { isa = XCSwiftPackageProductDependency; package = 84E95A75284A486600699FD3 /* XCRemoteSwiftPackageReference "stream-chat-swift" */; From 2c5b3489f5e5997dbc9ddc8abbbd3ddd7d267b5a Mon Sep 17 00:00:00 2001 From: Alexey Alter-Pesotskiy Date: Mon, 25 Nov 2024 16:49:46 +0000 Subject: [PATCH 5/5] Update Makefile --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 3e84c2d95..03e9610b8 100644 --- a/Makefile +++ b/Makefile @@ -19,11 +19,11 @@ update_swiftygif: check_version_parameter ./Scripts/removePublicDeclarations.sh Sources/StreamChatSwiftUI/StreamSwiftyGif update_markdown_ui: check_version_parameter - ./Scripts/updateDependency.sh $(version) Dependencies/MarkdownUI Sources/StreamChatAISwiftUI/MarkdownUI Sources + ./Scripts/updateDependency.sh $(version) Dependencies/MarkdownUI Sources/StreamChatAISwiftUI/StreamMarkdownUI Sources ./Scripts/removePublicDeclarations.sh Sources/StreamChatAISwiftUI/StreamMarkdownUI update_splash: check_version_parameter - ./Scripts/updateDependency.sh $(version) Dependencies/Splash Sources/StreamChatAISwiftUI/Splash Sources + ./Scripts/updateDependency.sh $(version) Dependencies/Splash Sources/StreamChatAISwiftUI/StreamSplash Sources ./Scripts/removePublicDeclarations.sh Sources/StreamChatAISwiftUI/StreamSplash check_version_parameter: