Skip to content

Commit 474ac9f

Browse files
authored
Merge pull request #94 from AvdLee/feature/swift-6
Migrate to Swift 6, Strict Concurrency, and @observable
2 parents a24e5ee + 5f4810a commit 474ac9f

File tree

14 files changed

+58
-48
lines changed

14 files changed

+58
-48
lines changed

Example/RoadmapExample/RoadmapExample.xcodeproj/project.pbxproj

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@
113113
attributes = {
114114
BuildIndependentTargetsInParallel = 1;
115115
LastSwiftUpdateCheck = 1420;
116-
LastUpgradeCheck = 1420;
116+
LastUpgradeCheck = 2600;
117117
TargetAttributes = {
118118
841912F629A2AA2300D1A0F6 = {
119119
CreatedOnToolsVersion = 14.2;
@@ -197,9 +197,12 @@
197197
CLANG_WARN_UNREACHABLE_CODE = YES;
198198
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
199199
COPY_PHASE_STRIP = NO;
200+
DEAD_CODE_STRIPPING = YES;
200201
DEBUG_INFORMATION_FORMAT = dwarf;
202+
DEVELOPMENT_TEAM = 8Q7TMPA46J;
201203
ENABLE_STRICT_OBJC_MSGSEND = YES;
202204
ENABLE_TESTABILITY = YES;
205+
ENABLE_USER_SCRIPT_SANDBOXING = YES;
203206
GCC_C_LANGUAGE_STANDARD = gnu11;
204207
GCC_DYNAMIC_NO_PIC = NO;
205208
GCC_NO_COMMON_BLOCKS = YES;
@@ -217,6 +220,7 @@
217220
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
218221
MTL_FAST_MATH = YES;
219222
ONLY_ACTIVE_ARCH = YES;
223+
STRING_CATALOG_GENERATE_SYMBOLS = YES;
220224
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
221225
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
222226
};
@@ -255,9 +259,12 @@
255259
CLANG_WARN_UNREACHABLE_CODE = YES;
256260
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
257261
COPY_PHASE_STRIP = NO;
262+
DEAD_CODE_STRIPPING = YES;
258263
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
264+
DEVELOPMENT_TEAM = 8Q7TMPA46J;
259265
ENABLE_NS_ASSERTIONS = NO;
260266
ENABLE_STRICT_OBJC_MSGSEND = YES;
267+
ENABLE_USER_SCRIPT_SANDBOXING = YES;
261268
GCC_C_LANGUAGE_STANDARD = gnu11;
262269
GCC_NO_COMMON_BLOCKS = YES;
263270
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
@@ -268,6 +275,7 @@
268275
GCC_WARN_UNUSED_VARIABLE = YES;
269276
MTL_ENABLE_DEBUG_INFO = NO;
270277
MTL_FAST_MATH = YES;
278+
STRING_CATALOG_GENERATE_SYMBOLS = YES;
271279
SWIFT_COMPILATION_MODE = wholemodule;
272280
SWIFT_OPTIMIZATION_LEVEL = "-O";
273281
};
@@ -279,12 +287,17 @@
279287
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
280288
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
281289
CODE_SIGN_ENTITLEMENTS = RoadmapExample/RoadmapExample.entitlements;
290+
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "-";
282291
CODE_SIGN_STYLE = Automatic;
283292
CURRENT_PROJECT_VERSION = 1;
293+
DEAD_CODE_STRIPPING = YES;
284294
DEVELOPMENT_ASSET_PATHS = "\"RoadmapExample/Preview Content\"";
285-
DEVELOPMENT_TEAM = 8Q7TMPA46J;
295+
ENABLE_APP_SANDBOX = YES;
286296
ENABLE_HARDENED_RUNTIME = YES;
297+
ENABLE_INCOMING_NETWORK_CONNECTIONS = YES;
298+
ENABLE_OUTGOING_NETWORK_CONNECTIONS = YES;
287299
ENABLE_PREVIEWS = YES;
300+
ENABLE_USER_SELECTED_FILES = readonly;
288301
GENERATE_INFOPLIST_FILE = YES;
289302
INFOPLIST_KEY_CFBundleDisplayName = "Roadmap Example";
290303
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
@@ -297,18 +310,18 @@
297310
"INFOPLIST_KEY_UIStatusBarStyle[sdk=iphonesimulator*]" = UIStatusBarStyleDefault;
298311
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
299312
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
300-
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
313+
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
301314
LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
302315
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
303-
MACOSX_DEPLOYMENT_TARGET = 12.4;
316+
MACOSX_DEPLOYMENT_TARGET = 14.0;
304317
MARKETING_VERSION = 1.0;
305318
PRODUCT_BUNDLE_IDENTIFIER = com.swiftlee.RoadmapExample;
306319
PRODUCT_NAME = "$(TARGET_NAME)";
307320
SDKROOT = auto;
308321
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx xros xrsimulator";
309322
SUPPORTS_MACCATALYST = NO;
310323
SWIFT_EMIT_LOC_STRINGS = YES;
311-
SWIFT_VERSION = 5.0;
324+
SWIFT_VERSION = 6.0;
312325
TARGETED_DEVICE_FAMILY = "1,2,7";
313326
};
314327
name = Debug;
@@ -319,12 +332,17 @@
319332
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
320333
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
321334
CODE_SIGN_ENTITLEMENTS = RoadmapExample/RoadmapExample.entitlements;
335+
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "-";
322336
CODE_SIGN_STYLE = Automatic;
323337
CURRENT_PROJECT_VERSION = 1;
338+
DEAD_CODE_STRIPPING = YES;
324339
DEVELOPMENT_ASSET_PATHS = "\"RoadmapExample/Preview Content\"";
325-
DEVELOPMENT_TEAM = 8Q7TMPA46J;
340+
ENABLE_APP_SANDBOX = YES;
326341
ENABLE_HARDENED_RUNTIME = YES;
342+
ENABLE_INCOMING_NETWORK_CONNECTIONS = YES;
343+
ENABLE_OUTGOING_NETWORK_CONNECTIONS = YES;
327344
ENABLE_PREVIEWS = YES;
345+
ENABLE_USER_SELECTED_FILES = readonly;
328346
GENERATE_INFOPLIST_FILE = YES;
329347
INFOPLIST_KEY_CFBundleDisplayName = "Roadmap Example";
330348
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
@@ -337,18 +355,18 @@
337355
"INFOPLIST_KEY_UIStatusBarStyle[sdk=iphonesimulator*]" = UIStatusBarStyleDefault;
338356
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
339357
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
340-
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
358+
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
341359
LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
342360
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
343-
MACOSX_DEPLOYMENT_TARGET = 12.4;
361+
MACOSX_DEPLOYMENT_TARGET = 14.0;
344362
MARKETING_VERSION = 1.0;
345363
PRODUCT_BUNDLE_IDENTIFIER = com.swiftlee.RoadmapExample;
346364
PRODUCT_NAME = "$(TARGET_NAME)";
347365
SDKROOT = auto;
348366
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx xros xrsimulator";
349367
SUPPORTS_MACCATALYST = NO;
350368
SWIFT_EMIT_LOC_STRINGS = YES;
351-
SWIFT_VERSION = 5.0;
369+
SWIFT_VERSION = 6.0;
352370
TARGETED_DEVICE_FAMILY = "1,2,7";
353371
};
354372
name = Release;
Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,5 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
33
<plist version="1.0">
4-
<dict>
5-
<key>com.apple.security.app-sandbox</key>
6-
<true/>
7-
<key>com.apple.security.files.user-selected.read-only</key>
8-
<true/>
9-
<key>com.apple.security.network.client</key>
10-
<true/>
11-
<key>com.apple.security.network.server</key>
12-
<true/>
13-
</dict>
4+
<dict/>
145
</plist>

Package.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
// swift-tools-version: 5.9
1+
// swift-tools-version: 6.0
22
// The swift-tools-version declares the minimum version of Swift required to build this package.
33

44
import PackageDescription
55

66
let package = Package(
77
name: "Roadmap",
88
platforms: [
9-
.iOS(.v15),
10-
.macOS(.v12),
9+
.iOS(.v17),
10+
.macOS(.v14),
1111
.visionOS(.v1)
1212
],
1313
products: [

Sources/Roadmap/DataProviders/FeatureVoter.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
import Foundation
99

10-
public protocol FeatureVoter {
10+
public protocol FeatureVoter: Sendable {
1111
/// Fetches the current count for the given feature.
1212
func fetch(for feature: RoadmapFeature) async -> Int
1313

Sources/Roadmap/DataProviders/JSONDataFetcher.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ struct JSONDataFetcher {
1212
case invalidURL
1313
}
1414

15-
private static var urlSession: URLSession = {
15+
private static let urlSession: URLSession = {
1616
URLSession(configuration: .ephemeral)
1717
}()
1818

Sources/Roadmap/Extensions/Logger.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import OSLog
1010

1111
extension Logger {
1212
/// Using your bundle identifier is a great way to ensure a unique identifier.
13-
private static var subsystem = Bundle.main.bundleIdentifier!
13+
private static let subsystem = Bundle.main.bundleIdentifier!
1414

1515
/// Logs the view cycles like a view that appeared.
1616
static let roadmap = Logger(subsystem: subsystem, category: "Roadmap")

Sources/Roadmap/Models/RoadmapFeature.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
import Foundation
99

10-
public struct RoadmapFeature: Codable, Identifiable {
10+
public struct RoadmapFeature: Codable, Identifiable, Sendable {
1111
public let id: String
1212
public let title: String?
1313
public var status: String? = nil

Sources/Roadmap/RoadmapConfiguration.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import Foundation
99
import SwiftUI
1010

11-
public struct RoadmapConfiguration {
11+
public struct RoadmapConfiguration: Sendable {
1212
/// Instead of a simple URL a Request is also possible for a more advanced way to the JSON
1313
public let roadmapRequest: URLRequest
1414

@@ -31,7 +31,7 @@ public struct RoadmapConfiguration {
3131
public let allowsFilterByStatus: Bool
3232

3333
/// If set, will be used for sorting features.
34-
public let sorting: ((RoadmapFeature, RoadmapFeature) -> Bool)?
34+
public let sorting: (@Sendable (RoadmapFeature, RoadmapFeature) -> Bool)?
3535

3636
/// Creates a new Roadmap configuration instance.
3737
/// - Parameters:
@@ -52,7 +52,7 @@ public struct RoadmapConfiguration {
5252
namespace: String? = nil,
5353
style: RoadmapStyle = RoadmapTemplate.standard.style,
5454
shuffledOrder: Bool = false,
55-
sorting: ((RoadmapFeature, RoadmapFeature) -> Bool)? = nil,
55+
sorting: (@Sendable (RoadmapFeature, RoadmapFeature) -> Bool)? = nil,
5656
allowVotes: Bool = true,
5757
allowSearching: Bool = false,
5858
allowsFilterByStatus: Bool = false) {

Sources/Roadmap/RoadmapFeatureView.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import SwiftUI
99

1010
struct RoadmapFeatureView: View {
1111
@Environment(\.dynamicTypeSize) var typeSize
12-
@StateObject var viewModel: RoadmapFeatureViewModel
12+
@State var viewModel: RoadmapFeatureViewModel
1313

1414
var body: some View {
1515
ZStack{

Sources/Roadmap/RoadmapFeatureViewModel.swift

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@
88
import Foundation
99
import SwiftUI
1010

11-
final class RoadmapFeatureViewModel: ObservableObject {
11+
@MainActor
12+
@Observable
13+
final class RoadmapFeatureViewModel {
1214
let feature: RoadmapFeature
1315
let configuration: RoadmapConfiguration
1416
let canVote: Bool
1517

16-
@Published var voteCount = 0
18+
var voteCount = 0
1719

1820
init(feature: RoadmapFeature, configuration: RoadmapConfiguration) {
1921
self.feature = feature
@@ -22,7 +24,6 @@ final class RoadmapFeatureViewModel: ObservableObject {
2224
self.canVote = configuration.allowVotes
2325
}
2426

25-
@MainActor
2627
func getCurrentVotes(firstLoad: Bool = false) async {
2728
if let votes = feature.votes, firstLoad {
2829
voteCount = votes
@@ -31,14 +32,12 @@ final class RoadmapFeatureViewModel: ObservableObject {
3132
}
3233
}
3334

34-
@MainActor
3535
func vote() async {
3636
let newCount = await configuration.voter.vote(for: feature)
3737
voteCount = newCount ?? (voteCount + 1)
3838
feature.hasVoted = true
3939
}
4040

41-
@MainActor
4241
func unvote() async {
4342
let newCount = await configuration.voter.unvote(for: feature)
4443
voteCount = newCount ?? (voteCount - 1)

0 commit comments

Comments
 (0)