Skip to content
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

Resolve many concurrency warnings #349

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
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
2 changes: 1 addition & 1 deletion Examples/Demo/Demo/DemoView.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import MarkdownUI
import SwiftUI

struct ThemeOption: Hashable {
struct ThemeOption: Hashable, Sendable {
let name: String
let theme: Theme

Expand Down
5 changes: 4 additions & 1 deletion Package.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// swift-tools-version:5.6
// swift-tools-version: 5.10

import PackageDescription

Expand Down Expand Up @@ -28,6 +28,9 @@ let package = Package(
dependencies: [
"cmark-gfm",
.product(name: "NetworkImage", package: "NetworkImage"),
],
swiftSettings: [
.enableExperimentalFeature("StrictConcurrency"),
]
),
.testTarget(
Expand Down
2 changes: 1 addition & 1 deletion Sources/MarkdownUI/DSL/Blocks/ListItem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import Foundation
/// ```
///
/// ![](ListItem)
public struct ListItem: Hashable {
public struct ListItem: Hashable, Sendable {
let children: [BlockNode]

init(children: [BlockNode]) {
Expand Down
2 changes: 1 addition & 1 deletion Sources/MarkdownUI/DSL/Blocks/MarkdownContent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public protocol MarkdownContentProtocol {
/// }
/// }
/// ```
public struct MarkdownContent: Equatable, MarkdownContentProtocol {
public struct MarkdownContent: Equatable, MarkdownContentProtocol, Sendable {
/// Returns a Markdown content value with the sum of the contents of all the container blocks
/// present in this content.
///
Expand Down
2 changes: 1 addition & 1 deletion Sources/MarkdownUI/DSL/Blocks/TaskListItem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import Foundation
/// }
/// }
/// ```
public struct TaskListItem: Hashable {
public struct TaskListItem: Hashable, Sendable {
let isCompleted: Bool
let children: [BlockNode]

Expand Down
4 changes: 2 additions & 2 deletions Sources/MarkdownUI/DSL/Inlines/SoftBreak.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Foundation
/// A soft break in a Markdown content block.
///
/// A ``Markdown`` view will display a soft break as a space.
public struct SoftBreak: InlineContentProtocol {
public struct SoftBreak: InlineContentProtocol, Sendable {
/// Creates a soft break inline element.
public init() {}

Expand All @@ -13,7 +13,7 @@ public struct SoftBreak: InlineContentProtocol {
}

extension SoftBreak {
public enum Mode {
public enum Mode: Sendable {
/// Treat a soft break as a space
case space

Expand Down
8 changes: 4 additions & 4 deletions Sources/MarkdownUI/Extensibility/AssetImageProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,24 @@ import SwiftUI
/// }
/// .markdownImageProvider(.asset)
/// ```
public struct AssetImageProvider: ImageProvider {
private let name: (URL) -> String
public struct AssetImageProvider: ImageProvider, Sendable {
private let name: @Sendable (URL) -> String
private let bundle: Bundle?

/// Creates an asset image provider.
/// - Parameters:
/// - name: A closure that extracts the image resource name from the URL in the Markdown content.
/// - bundle: The bundle where the image resources are located. Specify `nil` to search the app’s main bundle.
public init(
name: @escaping (URL) -> String = \.lastPathComponent,
name: @Sendable @escaping (URL) -> String = \.lastPathComponent,
bundle: Bundle? = nil
) {
self.name = name
self.bundle = bundle
}

public func makeImage(url: URL?) -> some View {
if let url = url, let image = self.image(url: url) {
if let url, let image = self.image(url: url) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is unrelated to the concurrency.

ResizeToFit(idealSize: image.size) {
Image(platformImage: image)
.resizable()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ import SwiftUI

/// An inline image provider that loads images from resources located in an app or a module.
public struct AssetInlineImageProvider: InlineImageProvider {
private let name: (URL) -> String
private let name: @Sendable (URL) -> String
private let bundle: Bundle?

/// Creates an asset inline image provider.
/// - Parameters:
/// - name: A closure that extracts the image resource name from the URL in the Markdown content.
/// - bundle: The bundle where the image resources are located. Specify `nil` to search the app’s main bundle.
public init(
name: @escaping (URL) -> String = \.lastPathComponent,
name: @Sendable @escaping (URL) -> String = \.lastPathComponent,
bundle: Bundle? = nil
) {
self.name = name
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import SwiftUI
///
/// To configure the current code syntax highlighter for a view hierarchy, use the
/// `markdownCodeSyntaxHighlighter(_:)` modifier.
public protocol CodeSyntaxHighlighter {
public protocol CodeSyntaxHighlighter: Sendable {
/// Returns a text view configured with the syntax highlighted code.
/// - Parameters:
/// - code: The code block.
Expand Down
6 changes: 3 additions & 3 deletions Sources/MarkdownUI/Extensibility/ImageProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import SwiftUI
/// }
/// .markdownImageProvider(.asset)
/// ```
public protocol ImageProvider {
public protocol ImageProvider: Sendable {
/// A view that loads and displays an image.
associatedtype Body: View

Expand All @@ -26,8 +26,8 @@ public protocol ImageProvider {
@ViewBuilder func makeImage(url: URL?) -> Body
}

struct AnyImageProvider: ImageProvider {
private let _makeImage: (URL?) -> AnyView
struct AnyImageProvider: ImageProvider, Sendable {
private let _makeImage: @Sendable (URL?) -> AnyView

init<I: ImageProvider>(_ imageProvider: I) {
self._makeImage = {
Expand Down
2 changes: 1 addition & 1 deletion Sources/MarkdownUI/Extensibility/InlineImageProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import SwiftUI
///
/// To configure the current inline image provider for a view hierarchy,
/// use the `markdownInlineImageProvider(_:)` modifier.
public protocol InlineImageProvider {
public protocol InlineImageProvider: Sendable {
/// Returns an image for the given URL.
///
/// ``Markdown`` views call this method to load images within a line of text.
Expand Down
12 changes: 6 additions & 6 deletions Sources/MarkdownUI/Parser/BlockNode.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Foundation

enum BlockNode: Hashable {
enum BlockNode: Hashable, Sendable {
case blockquote(children: [BlockNode])
case bulletedList(isTight: Bool, items: [RawListItem])
case numberedList(isTight: Bool, start: Int, items: [RawListItem])
Expand Down Expand Up @@ -35,26 +35,26 @@ extension BlockNode {
}
}

struct RawListItem: Hashable {
struct RawListItem: Hashable, Sendable {
let children: [BlockNode]
}

struct RawTaskListItem: Hashable {
struct RawTaskListItem: Hashable, Sendable {
let isCompleted: Bool
let children: [BlockNode]
}

enum RawTableColumnAlignment: Character {
enum RawTableColumnAlignment: Character, Sendable {
case none = "\0"
case left = "l"
case center = "c"
case right = "r"
}

struct RawTableRow: Hashable {
struct RawTableRow: Hashable, Sendable {
let cells: [RawTableCell]
}

struct RawTableCell: Hashable {
struct RawTableCell: Hashable, Sendable {
let content: [InlineNode]
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import SwiftUI
/// Most theme ``BlockStyle`` instances receive a `BlockConfiguration` input in their
/// `body` closure. The configuration ``BlockConfiguration/label-swift.property``
/// property reflects the block's content.
@MainActor
public struct BlockConfiguration {
/// A type-erased view of a Markdown block.
public struct Label: View {
Expand Down
7 changes: 4 additions & 3 deletions Sources/MarkdownUI/Theme/BlockStyle/BlockStyle.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,13 @@ import SwiftUI
/// ```
///
/// ![](CustomBlockquote)
@MainActor
public struct BlockStyle<Configuration> {
private let body: (Configuration) -> AnyView
private let body: @MainActor (Configuration) -> AnyView

/// Creates a block style that customizes a block by applying the given body.
/// - Parameter body: A view builder that returns the customized block.
public init<Body: View>(@ViewBuilder body: @escaping (_ configuration: Configuration) -> Body) {
public init<Body: View>(@ViewBuilder body: @MainActor @escaping (_ configuration: Configuration) -> Body) {
self.body = { AnyView(body($0)) }
}

Expand All @@ -54,7 +55,7 @@ public struct BlockStyle<Configuration> {
extension BlockStyle where Configuration == Void {
/// Creates a block style for a block with no content, like a thematic break.
/// - Parameter body: A view builder that returns the customized block.
public init<Body: View>(@ViewBuilder body: @escaping () -> Body) {
public init<Body: View>(@ViewBuilder body: @MainActor @escaping () -> Body) {
self.init { _ in
body()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import SwiftUI
///
/// The theme ``Theme/bulletedListMarker`` and ``Theme/numberedListMarker``
/// block styles receive a `ListMarkerConfiguration` input in their `body` closure.
public struct ListMarkerConfiguration {
public struct ListMarkerConfiguration: Sendable {
/// The list level (one-based) of the item to which the marker applies.
public let listLevel: Int

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ import SwiftUI
/// ```
///
/// ![](CustomTableBackground)
public struct TableBackgroundStyle {
let background: (_ row: Int, _ column: Int) -> AnyShapeStyle
public struct TableBackgroundStyle: Sendable {
let background: @Sendable (_ row: Int, _ column: Int) -> AnyShapeStyle

/// Creates a table background style that customizes table backgrounds by applying a given closure
/// to the background of each cell.
/// - Parameter background: A closure that returns a shape style for a given table cell location.
public init<S: ShapeStyle>(background: @escaping (_ row: Int, _ column: Int) -> S) {
public init<S: ShapeStyle>(background: @Sendable @escaping (_ row: Int, _ column: Int) -> S) {
self.background = { row, column in
AnyShapeStyle(background(row, column))
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/MarkdownUI/Theme/BlockStyle/TableBorderStyle.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import SwiftUI
/// ```
///
/// ![](CustomTableBorders)
public struct TableBorderStyle {
public struct TableBorderStyle: Sendable {
/// The visible table borders.
public var visibleBorders: TableBorderSelector

Expand Down
14 changes: 7 additions & 7 deletions Sources/MarkdownUI/Theme/TextStyle/Styles/FontProperties.swift
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import SwiftUI

/// The characteristics of a font.
public struct FontProperties: Hashable {
public struct FontProperties: Hashable, Sendable {
/// The font family.
public enum Family: Hashable {
public enum Family: Hashable, Sendable {
/// The system font family.
case system(Font.Design = .default)

Expand All @@ -12,7 +12,7 @@ public struct FontProperties: Hashable {
}

/// The font family variant.
public enum FamilyVariant: Hashable {
public enum FamilyVariant: Hashable, Sendable {
/// No variant. Use the current font family.
case normal

Expand All @@ -21,7 +21,7 @@ public struct FontProperties: Hashable {
}

/// The font caps variant.
public enum CapsVariant: Hashable {
public enum CapsVariant: Hashable, Sendable {
/// Don't use a font caps variant.
case normal

Expand All @@ -36,7 +36,7 @@ public struct FontProperties: Hashable {
}

/// The font digit variant.
public enum DigitVariant: Hashable {
public enum DigitVariant: Hashable, Sendable {
/// Don't use a font digit variant.
case normal

Expand All @@ -45,7 +45,7 @@ public struct FontProperties: Hashable {
}

/// The font style.
public enum Style {
public enum Style: Sendable {
/// Don't use a font style.
case normal

Expand Down Expand Up @@ -102,7 +102,7 @@ public struct FontProperties: Hashable {
set { self.widthStorage = newValue }
}

private var widthStorage: AnyHashable?
nonisolated(unsafe) private var widthStorage: AnyHashable? // Marking this as `nonisolated(unsafe)`, because it should really be `Font.Width?`, but this is only available from iOS 16. Change to type `Font.Width?` and remove `nonisolated(unsafe)` after raising minimum target to iOS 16
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may be able to define an adapter for this instead of raising the minimum platform version.


/// The font size.
public var size: CGFloat = Self.defaultSize
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Foundation

enum FontPropertiesAttribute: AttributedStringKey {
enum FontPropertiesAttribute: AttributedStringKey, Sendable {
typealias Value = FontProperties
static let name = "fontProperties"
}
Expand Down
4 changes: 2 additions & 2 deletions Sources/MarkdownUI/Theme/TextStyle/Styles/FontSize.swift
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import Foundation

/// A text style that sets the font size.
public struct FontSize: TextStyle {
private enum Size {
public struct FontSize: TextStyle, Sendable {
private enum Size: Sendable {
case points(CGFloat)
case relative(RelativeSize)
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/MarkdownUI/Theme/TextStyle/TextStyle.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,6 @@ import SwiftUI
/// ```
///
/// ![](CustomBlockquote)
public protocol TextStyle {
public protocol TextStyle: Sendable {
func _collectAttributes(in attributes: inout AttributeContainer)
}
3 changes: 2 additions & 1 deletion Sources/MarkdownUI/Theme/Theme.swift
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ import SwiftUI
/// }
/// // More block styles...
/// ```
public struct Theme {
@MainActor
public struct Theme: Sendable {
/// The default text style.
public var text: TextStyle = EmptyTextStyle()

Expand Down
8 changes: 4 additions & 4 deletions Sources/MarkdownUI/Utility/Deprecations.swift
Original file line number Diff line number Diff line change
Expand Up @@ -369,8 +369,8 @@ extension View {
"BlockStyle" types.
"""
)
public struct MarkdownStyle: Hashable {
public struct Font: Hashable {
public struct MarkdownStyle: Hashable, Sendable {
public struct Font: Hashable, Sendable {
public static var largeTitle: Self { fatalError("Unimplemented") }
public static var title: Self { fatalError("Unimplemented") }
public static var title2: Self { fatalError("Unimplemented") }
Expand Down Expand Up @@ -423,7 +423,7 @@ public struct MarkdownStyle: Hashable {
}
}

public struct HeadingScales: Hashable {
public struct HeadingScales: Hashable, Sendable {
public init(
h1: CGFloat,
h2: CGFloat,
Expand All @@ -444,7 +444,7 @@ public struct MarkdownStyle: Hashable {
}
}

public struct Measurements: Hashable {
public struct Measurements: Hashable, Sendable {
public var codeFontScale: CGFloat
public var headIndentStep: CGFloat
public var tailIndentStep: CGFloat
Expand Down
2 changes: 1 addition & 1 deletion Sources/MarkdownUI/Utility/InlineNode+RawImageData.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Foundation

struct RawImageData: Hashable {
struct RawImageData: Hashable, Sendable {
var source: String
var alt: String
var destination: String?
Expand Down
Loading