From ed0a9789da5ff139c2988bb37f768229a446672f Mon Sep 17 00:00:00 2001 From: Felix Herrmann Date: Mon, 9 Sep 2024 01:44:14 +0200 Subject: [PATCH] Fix Concurrency errors --- README.md | 2 +- Sources/UIImageColors/NSImage+Colors.swift | 23 +++++++++++++++---- Sources/UIImageColors/ScaleQuality.swift | 2 +- Sources/UIImageColors/UIImage+Colors.swift | 4 ++-- .../UIImageColorsObjc/NSImageColorsObjc.swift | 2 +- .../UIImageColorsObjc/UIImageColorsObjc.swift | 2 +- .../UIImageColorsTests.swift | 1 + 7 files changed, 26 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index af33bb2..02010d1 100644 --- a/README.md +++ b/README.md @@ -150,7 +150,7 @@ Higher qualities will give better results at the cost of performance. | ------------------- | ----------- | | low | 50 pixel | | medium | 100 pixel | -| high | 250 pixel | +| high | 250 pixel | | full | no scaling | | custom (Swift only) | given value | diff --git a/Sources/UIImageColors/NSImage+Colors.swift b/Sources/UIImageColors/NSImage+Colors.swift index 6635e63..d06c2e0 100644 --- a/Sources/UIImageColors/NSImage+Colors.swift +++ b/Sources/UIImageColors/NSImage+Colors.swift @@ -15,7 +15,7 @@ import AppKit extension NSImage { /// Represents the most common colors inside an image. - public struct Colors { + public struct Colors: Sendable { /// The most common, non-black/white color. public let background: NSColor @@ -59,11 +59,26 @@ extension NSImage { /// - Parameters: /// - quality: The scale quality. Default is `ScaleQuality.high`. /// - completion: The completion block with the ``Colors``. - public func getColors(quality: ScaleQuality = .high, _ completion: @escaping (Colors?) -> Void) { + public func getColors(quality: ScaleQuality = .high, _ completion: @MainActor @Sendable @escaping (Colors?) -> Void) { + let scaledSize = quality._scaleSize(size) + guard let resizedCGImage = _resizedCGImage(size: scaledSize) else { + DispatchQueue.main.async { + completion(nil) + } + return + } + DispatchQueue.global().async { - let result = self.getColors(quality: quality) + let colors: Colors? + if let counter = _ColorCounter(cgImage: resizedCGImage) { + let analyzer = _ColorAnalyzer(counter: counter) + colors = analyzer?.colors + } else { + colors = nil + } + DispatchQueue.main.async { - completion(result) + completion(colors) } } } diff --git a/Sources/UIImageColors/ScaleQuality.swift b/Sources/UIImageColors/ScaleQuality.swift index d10d4cd..e41dfb0 100644 --- a/Sources/UIImageColors/ScaleQuality.swift +++ b/Sources/UIImageColors/ScaleQuality.swift @@ -11,7 +11,7 @@ import CoreGraphics // MARK: - ScaleQuality /// The quality the original image should be scaled to. -public enum ScaleQuality { +public enum ScaleQuality: Sendable { /// Scales the image to 50 pixel. case low diff --git a/Sources/UIImageColors/UIImage+Colors.swift b/Sources/UIImageColors/UIImage+Colors.swift index d4f7a03..5c1a3f3 100644 --- a/Sources/UIImageColors/UIImage+Colors.swift +++ b/Sources/UIImageColors/UIImage+Colors.swift @@ -15,7 +15,7 @@ import UIKit extension UIImage { /// Represents the most common colors inside an image. - public struct Colors { + public struct Colors: Sendable { /// The most common, non-black/white color. public let background: UIColor @@ -59,7 +59,7 @@ extension UIImage { /// - Parameters: /// - quality: The scale quality. Default is `ScaleQuality.high`. /// - completion: The completion block with the ``Colors``. - public func getColors(quality: ScaleQuality = .high, _ completion: @escaping (Colors?) -> Void) { + public func getColors(quality: ScaleQuality = .high, _ completion: @MainActor @Sendable @escaping (Colors?) -> Void) { DispatchQueue.global().async { let result = self.getColors(quality: quality) DispatchQueue.main.async { diff --git a/Sources/UIImageColorsObjc/NSImageColorsObjc.swift b/Sources/UIImageColorsObjc/NSImageColorsObjc.swift index cf5fd12..6f126ba 100644 --- a/Sources/UIImageColorsObjc/NSImageColorsObjc.swift +++ b/Sources/UIImageColorsObjc/NSImageColorsObjc.swift @@ -66,7 +66,7 @@ extension NSImage { /// - quality: The scale quality. /// - completion: The completion block with the ``NSImageColorsObjc``. @objc(getColorsWithQuality:completion:) - public func getColorsObjc(quality: UIImageColorsScaleQuality, completion: @escaping (NSImageColorsObjc?) -> Void) { + public func getColorsObjc(quality: UIImageColorsScaleQuality, completion: @Sendable @escaping (NSImageColorsObjc?) -> Void) { getColors(quality: quality._scaleQuality) { colors in if let colors = colors { completion(NSImageColorsObjc(background: colors.background, primary: colors.primary, secondary: colors.secondary, detail: colors.detail)) diff --git a/Sources/UIImageColorsObjc/UIImageColorsObjc.swift b/Sources/UIImageColorsObjc/UIImageColorsObjc.swift index 979d794..9724c3c 100644 --- a/Sources/UIImageColorsObjc/UIImageColorsObjc.swift +++ b/Sources/UIImageColorsObjc/UIImageColorsObjc.swift @@ -66,7 +66,7 @@ extension UIImage { /// - quality: The scale quality. /// - completion: The completion block with the ``UIImageColorsObjc``. @objc(getColorsWithQuality:completion:) - public func getColorsObjc(quality: UIImageColorsScaleQuality, completion: @escaping (UIImageColorsObjc?) -> Void) { + public func getColorsObjc(quality: UIImageColorsScaleQuality, completion: @Sendable @escaping (UIImageColorsObjc?) -> Void) { getColors(quality: quality._scaleQuality) { colors in if let colors = colors { completion(UIImageColorsObjc(background: colors.background, primary: colors.primary, secondary: colors.secondary, detail: colors.detail)) diff --git a/Tests/UIImageColorsTests/UIImageColorsTests.swift b/Tests/UIImageColorsTests/UIImageColorsTests.swift index d09ebfb..5693736 100644 --- a/Tests/UIImageColorsTests/UIImageColorsTests.swift +++ b/Tests/UIImageColorsTests/UIImageColorsTests.swift @@ -127,6 +127,7 @@ final class UIImageColorsTests: XCTestCase { #endif } + @MainActor func testInternalScaling() throws { #if canImport(UIKit) let cgImage = try XCTUnwrap(image.cgImage)