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

IOS-10545 Migrating to Swift 6.0 with strict concurrency #405

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/record-screenshots.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,15 @@ jobs:

- name: Enable screenshots recording
run: |
find . -type f -name "*.swift" -exec sed -i '' 's/isRecording = false/isRecording = true/' {} +
find . -type f -name "*.swift" -exec sed -i '' 's/record: .never/record: .failed/' {} +

- name: Launch tests and record screenshots
run: make test
continue-on-error: true

- name: Disable screenshots recording
run: |
find . -type f -name "*.swift" -exec sed -i '' 's/isRecording = true/isRecording = false/' {} +
find . -type f -name "*.swift" -exec sed -i '' 's/record: .failed/record: .never/' {} +

- name: Commit Changes
uses: stefanzweifel/git-auto-commit-action@v5
Expand Down
8 changes: 4 additions & 4 deletions MisticaCatalog/Source/MisticaCatalogApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -106,15 +106,15 @@ struct MisticaCatalogApp: App {

func configureFontStyle(for brandStyle: BrandStyle) {
if let mapping = brandStyle.fontMapping {
FontStyle.fontNameForWeight = { weight in
FontManager.shared.fontNameForWeight = { weight in
mapping.fontName(for: weight)
}
FontStyle.uiFontNameForWeight = { weight in
FontManager.shared.uiFontNameForWeight = { weight in
mapping.UIfontName(for: weight)
}
} else {
FontStyle.fontNameForWeight = nil
FontStyle.uiFontNameForWeight = nil
FontManager.shared.fontNameForWeight = nil
FontManager.shared.uiFontNameForWeight = nil
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// swift-tools-version:5.9
// swift-tools-version:6.0

import PackageDescription

Expand All @@ -15,7 +15,7 @@ let package = Package(
],
dependencies: [
.package(url: "https://github.com/airbnb/lottie-spm.git", exact: "4.5.0"),
.package(url: "https://github.com/pointfreeco/swift-snapshot-testing.git", exact: "1.8.2"),
.package(url: "https://github.com/pointfreeco/swift-snapshot-testing.git", exact: "1.17.6"),
.package(url: "https://github.com/SDWebImage/SDWebImage.git", exact: "5.19.1"),
.package(url: "https://github.com/SDWebImage/SDWebImageSVGCoder.git", exact: "1.7.0")
],
Expand Down
1 change: 1 addition & 0 deletions Sources/Mistica/Components/Badge/NovumBarButtonItem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import UIKit
/// Creates a UITabBarItem with the Badge style of Novum
/// - Parameters:
/// - badgeValue: The number to show in the badge or 0 for do not display it.
@MainActor
public func createNovumTabBarItem(badgeValue: UInt = 0) -> UITabBarItem {
let item = UITabBarItem()
item.badgeColor = .badge
Expand Down
6 changes: 3 additions & 3 deletions Sources/Mistica/Components/Button/ButtonStyle+Toolkit.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ public extension Button.Style {
private static var smallFont: UIFont { .textPreset2(weight: .button) }
private static var linkFont: UIFont { .textPreset2(weight: .button) }

private static var regularMinimumWidth: CGFloat = 156
private static var smallMinimumWidth: CGFloat = 104
private static var linkMinimumWidth: CGFloat = 0
private static let regularMinimumWidth: CGFloat = 156
private static let smallMinimumWidth: CGFloat = 104
private static let linkMinimumWidth: CGFloat = 0

private enum ImageHeight {
static let regular: CGFloat = 24
Expand Down
2 changes: 1 addition & 1 deletion Sources/Mistica/Components/Callout/Callout.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public class Callout: UIView {
if let contentConfiguration = contentConfiguration {
configure(withConfiguration: contentConfiguration)
} else {
configure(withConfiguration: .emptyConfiguration)
configure(withConfiguration: .emptyConfiguration())
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ import Foundation
import UIKit

public struct CalloutConfiguration {
static let emptyConfiguration = CalloutConfiguration(asset: .none, title: nil, description: "Empty configuration", actions: nil, canClose: true)
public static func emptyConfiguration() -> CalloutConfiguration {
CalloutConfiguration(asset: .none, title: nil, description: "Empty configuration", actions: nil, canClose: true)
}

public enum CalloutActions {
case primary(CalloutButton)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,10 @@ extension CalloutContentBase {

var descriptionTitle: String {
get {
calloutBaseView.messagesView.description
calloutBaseView.messagesView.calloutDescription
}
set {
calloutBaseView.messagesView.description = newValue
calloutBaseView.messagesView.calloutDescription = newValue
}
}

Expand Down Expand Up @@ -107,7 +107,7 @@ extension CalloutContentBase {
}

calloutBaseView.title = configuration.title
calloutBaseView.description = configuration.description
calloutBaseView.calloutTitleDescription = configuration.description

switch configuration.actions {
case let .primary(primaryButton):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ extension CalloutMessagesContent {
}
}

override var description: String {
var calloutDescription: String {
get {
descriptionLabel.text!
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ extension CalloutTitleActions {
}
}

override var description: String {
var calloutTitleDescription: String {
get {
messagesView.description
messagesView.calloutDescription
}
set {
messagesView.description = newValue
messagesView.calloutDescription = newValue
}
}

Expand Down
12 changes: 6 additions & 6 deletions Sources/Mistica/Components/Callout/Model/CalloutButton.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,31 @@

import Foundation

public struct CalloutButton {
public struct CalloutButton: Sendable {
public let title: String
public let loadingTitle: String?
public let accessibilityIdentifier: String?
public let tapHandler: (() -> Void)?
public let tapHandler: (@Sendable() -> Void)?

public init(title: String,
loadingTitle: String?,
accessibilityIdentifier: String? = nil,
tapHandler: (() -> Void)?) {
tapHandler: (@Sendable() -> Void)?) {
self.title = title
self.loadingTitle = loadingTitle
self.accessibilityIdentifier = accessibilityIdentifier
self.tapHandler = tapHandler
}
}

public struct CalloutLinkButton {
public struct CalloutLinkButton: Sendable {
public let title: String
public let accessibilityIdentifier: String?
public let tapHandler: (() -> Void)?
public let tapHandler: (@Sendable() -> Void)?

public init(title: String,
accessibilityIdentifier: String? = nil,
tapHandler: (() -> Void)?) {
tapHandler: (@Sendable() -> Void)?) {
self.title = title
self.accessibilityIdentifier = accessibilityIdentifier
self.tapHandler = tapHandler
Expand Down
16 changes: 9 additions & 7 deletions Sources/Mistica/Components/Cards/DataCard.swift
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public class DataCard: UIView {
if let contentConfiguration = contentConfiguration {
configure(with: contentConfiguration)
} else {
configure(with: .emptyConfiguration)
configure(with: .emptyConfiguration())
}
}
}
Expand Down Expand Up @@ -294,11 +294,13 @@ private extension DataCard {
}

private extension DataCardConfiguration {
static let emptyConfiguration = DataCardConfiguration(
title: "",
descriptionTitle: "",
buttons: .link(
CardLinkButton(title: "", accessibilityIdentifier: nil, tapHandler: nil)
static func emptyConfiguration() -> DataCardConfiguration {
DataCardConfiguration(
title: "",
descriptionTitle: "",
buttons: .link(
CardLinkButton(title: "", accessibilityIdentifier: nil, tapHandler: nil)
)
)
)
}
}
7 changes: 5 additions & 2 deletions Sources/Mistica/Components/Cards/MediaCard.swift
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public class MediaCard: UIView {
if let contentConfiguration = contentConfiguration {
configure(with: contentConfiguration)
} else {
configure(with: .emptyConfiguration)
configure(with: .emptyConfiguration())
}
}
}
Expand Down Expand Up @@ -201,5 +201,8 @@ private extension MediaCard {
}

private extension MediaCardConfiguration {
static let emptyConfiguration = MediaCardConfiguration(richMedia: UIView(), descriptionTitle: "")
@MainActor
static func emptyConfiguration() -> MediaCardConfiguration {
MediaCardConfiguration(richMedia: UIView(), descriptionTitle: "")
}
}
12 changes: 6 additions & 6 deletions Sources/Mistica/Components/Cards/Model/CardButton.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,31 @@

import Foundation

public struct CardButton {
public struct CardButton: Sendable {
public let title: String
public let accessibilityIdentifier: String?
public let loadingTitle: String?
public let tapHandler: (() -> Void)?
public let tapHandler: (@Sendable() -> Void)?

public init(title: String,
loadingTitle: String?,
accessibilityIdentifier: String? = nil,
tapHandler: (() -> Void)?) {
tapHandler: (@Sendable() -> Void)?) {
self.title = title
self.loadingTitle = loadingTitle
self.accessibilityIdentifier = accessibilityIdentifier
self.tapHandler = tapHandler
}
}

public struct CardLinkButton {
public struct CardLinkButton: Sendable {
public let title: String
public let accessibilityIdentifier: String?
public let tapHandler: (() -> Void)?
public let tapHandler: (@Sendable() -> Void)?

public init(title: String,
accessibilityIdentifier: String? = nil,
tapHandler: (() -> Void)?) {
tapHandler: (@Sendable() -> Void)?) {
self.title = title
self.accessibilityIdentifier = accessibilityIdentifier
self.tapHandler = tapHandler
Expand Down
2 changes: 1 addition & 1 deletion Sources/Mistica/Components/Checkbox/Checkbox.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class Checkbox: UIControl {
private enum Constants {
static let viewWidth = CGFloat(18)
static let animationDuration = Double(0.4)
static let timingFunction = CAMediaTimingFunction(controlPoints: 0.77, 0, 0.175, 1)
nonisolated(unsafe) static let timingFunction = CAMediaTimingFunction(controlPoints: 0.77, 0, 0.175, 1)
}

private let imageView = UIImageView(image: .checkmarkIcon)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@

import UIKit

@MainActor
public class CroutonController: NSObject {
public enum RootViewController {
public typealias Closure = () -> UIViewController?
public static let `default`: Closure = { UIApplication.shared.windows.filter(\.isKeyWindow).first?.rootViewController }
@MainActor public static let `default`: Closure = { UIApplication.shared.windows.filter(\.isKeyWindow).first?.rootViewController
}
}

public typealias Token = UUID
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import UIKit

extension CroutonController {
@MainActor
struct OngoingCrouton {
let token: Token
let croutonView: CroutonView
Expand Down
2 changes: 1 addition & 1 deletion Sources/Mistica/Components/EmptyState/EmptyState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public class EmptyState: UIView {
if let contentConfiguration = contentConfiguration {
configure(withConfiguration: contentConfiguration)
} else {
configure(withConfiguration: .empty)
configure(withConfiguration: .emptyConfiguration())
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,14 @@ import Foundation
import UIKit

public struct EmptyStateConfiguration {
static let empty = EmptyStateConfiguration(type: .default(.icon(UIImage())), title: "Basic configuration", description: "This is a basic configuration for the empty state", actions: nil)
static func emptyConfiguration() -> EmptyStateConfiguration {
EmptyStateConfiguration(
type: .default(.icon(UIImage())),
title: "Basic configuration",
description: "This is a basic configuration for the empty state",
actions: nil
)
}

public enum EmptyStateActions {
case primary(EmptyStateButton)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,26 @@

import Foundation

public struct EmptyStateButton {
public struct EmptyStateButton: Sendable {
public let title: String
public let loadingTitle: String?
public let tapHandler: (() -> Void)?
public let tapHandler: (@Sendable() -> Void)?

public init(title: String,
loadingTitle: String?,
tapHandler: (() -> Void)?) {
tapHandler: (@Sendable() -> Void)?) {
self.title = title
self.loadingTitle = loadingTitle
self.tapHandler = tapHandler
}
}

public struct EmptyStateLinkButton {
public struct EmptyStateLinkButton: Sendable {
public let title: String
public let tapHandler: (() -> Void)?
public let tapHandler: (@Sendable() -> Void)?

public init(title: String,
tapHandler: (() -> Void)?) {
tapHandler: (@Sendable() -> Void)?) {
self.title = title
self.tapHandler = tapHandler
}
Expand Down
14 changes: 9 additions & 5 deletions Sources/Mistica/Components/Feedback/FeedbackView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -208,8 +208,10 @@ public class FeedbackView: UIView {
private lazy var buttonsView: UIView = {
let buttonsView = UIStackView(arrangedSubviews: [])

[primaryButton, secondaryButton].compactMap { $0 }
.forEach(buttonsView.addArrangedSubview(_:))
Task { @MainActor in
try [primaryButton, secondaryButton].compactMap { $0 }
.forEach(buttonsView.addArrangedSubview(_:))
Copy link
Contributor Author

@alejandroruizponce alejandroruizponce Oct 25, 2024

Choose a reason for hiding this comment

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

Now addArrangedSubview is isolated:
@MainActor open class UIStackView : UIView { .. }

}

buttonsView.alignment = .fill
buttonsView.axis = .vertical
Expand Down Expand Up @@ -365,7 +367,7 @@ private extension FeedbackView {
}

// Prepare
views.forEach(prepare(view:))
try? views.forEach(prepare(view:))
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Now forEach method has a rethrow to be handled:
@inlinable public func forEach(_ body: (Element) throws -> Void) rethrows

// Generate animators
animators = views.map(animation).map { animation in
let animator = animator
Expand Down Expand Up @@ -410,8 +412,10 @@ private extension FeedbackView {
let hapticFeedbackDelay = style.hapticFeedbackDelay else { return }
Timer.scheduledTimer(withTimeInterval: hapticFeedbackDelay, repeats: false) { [weak self] _ in
guard let self = self else { return }
self.feedbackGenerator?.notificationOccurred(hapticFeedbackStyle)
self.feedbackGenerator = nil
Task { @MainActor in
self.feedbackGenerator?.notificationOccurred(hapticFeedbackStyle)
self.feedbackGenerator = nil
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Now UINotificationFeedbackGenerator is isolated:
@MainActor open class UINotificationFeedbackGenerator : UIFeedbackGenerator

}
}

Expand Down
Loading