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

[Update] Bump version to Xcode 16 #508

Merged
merged 25 commits into from
Sep 26, 2024
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
f2e1cd5
Validated settings for Xcode 16.
yo1995 Sep 20, 2024
b257c76
Bump Xcode requirement in README.
yo1995 Sep 20, 2024
e3e8793
Upgrade Xcode project version.
yo1995 Sep 20, 2024
4b52704
Make ID conformance nonisolated.
yo1995 Sep 23, 2024
56f860c
Add `@retroactive` to silence protocol related warnings.
yo1995 Sep 23, 2024
28683f3
Bump Swift Version to 6.0.
yo1995 Sep 23, 2024
5186c7c
Merge branch 'v.next' into Ting/BumpXcode16
yo1995 Sep 23, 2024
5705754
any Sendable.
yo1995 Sep 23, 2024
2db484f
Change deinit cleanup method to nonisolated Task.
yo1995 Sep 23, 2024
2cf826b
Do FileDocument on main actor to ensure single access.
yo1995 Sep 23, 2024
0784edc
Use sendable closure for taskgroups.
yo1995 Sep 23, 2024
858fbd3
Swift 6 concurrency upgrade.
yo1995 Sep 23, 2024
bed2c63
Blindly unchecked Sendable.
yo1995 Sep 23, 2024
3cf2a63
Apply suggestions from code review.
yo1995 Sep 24, 2024
2f49637
Move deinit stopping logics to onDisappear.
yo1995 Sep 24, 2024
d4e7483
Refactor `KMZFile` to make it Sendable.
yo1995 Sep 25, 2024
c4ed988
Inline openURL method.
yo1995 Sep 25, 2024
f54c9db
Move the sentence reader to run on main actor.
yo1995 Sep 25, 2024
7935e77
Refactor animation logic to not use Timer block.
yo1995 Sep 25, 2024
bf91bf6
Apply suggestions from code review.
yo1995 Sep 25, 2024
2336429
Get rid of redundant Sendable conformance
yo1995 Sep 25, 2024
1d207ee
Make app storage not array but string.
yo1995 Sep 25, 2024
c660138
Apply suggestions from code review.
yo1995 Sep 25, 2024
73725b6
Rename extension file in project.
yo1995 Sep 25, 2024
25058a0
Merge branch 'v.next' into Ting/BumpXcode16
yo1995 Sep 25, 2024
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 README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ This repository contains Swift sample code demonstrating the capabilities of the

## Requirements

* [ArcGIS Maps SDK for Swift](https://developers.arcgis.com/swift/) 200.5 (or newer)
* [ArcGIS Maps SDK for Swift](https://developers.arcgis.com/swift/) 200.5.1 (or newer)
* [ArcGIS Maps SDK for Swift Toolkit](https://github.com/Esri/arcgis-maps-sdk-swift-toolkit) 200.5 (or newer)
* Xcode 15.0 (or newer)
* Xcode 16.0 (or newer)

The *ArcGIS Maps SDK for Swift Samples app* has a *Target SDK* version of *16.0*, meaning that it can run on devices with *iOS 16.0* or newer.

Expand Down
10 changes: 5 additions & 5 deletions Samples.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 60;
objectVersion = 77;
objects = {

/* Begin PBXBuildFile section */
Expand Down Expand Up @@ -2951,7 +2951,7 @@
StyleSymbolsFromMobileStyleFile,
);
LastSwiftUpdateCheck = 1330;
LastUpgradeCheck = 1500;
LastUpgradeCheck = 1600;
ORGANIZATIONNAME = Esri;
TargetAttributes = {
00E5401227F3CCA200CF66D5 = {
Expand All @@ -2960,7 +2960,6 @@
};
};
buildConfigurationList = 00E5400A27F3CCA100CF66D5 /* Build configuration list for PBXProject "Samples" */;
compatibilityVersion = "Xcode 15.0";
philium marked this conversation as resolved.
Show resolved Hide resolved
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
Expand All @@ -2971,6 +2970,7 @@
packageReferences = (
00C43AEB2947DC350099AE34 /* XCRemoteSwiftPackageReference "arcgis-maps-sdk-swift-toolkit" */,
);
preferredProjectObjectVersion = 77;
productRefGroup = 00E5401427F3CCA200CF66D5 /* Products */;
projectDirPath = "";
projectRoot = "";
Expand Down Expand Up @@ -3490,7 +3490,7 @@
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_STRICT_CONCURRENCY = targeted;
SWIFT_VERSION = 5.0;
SWIFT_VERSION = 6.0;
TARGETED_DEVICE_FAMILY = "1,2,6";
};
name = Debug;
Expand Down Expand Up @@ -3522,7 +3522,7 @@
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_STRICT_CONCURRENCY = targeted;
SWIFT_VERSION = 5.0;
SWIFT_VERSION = 6.0;
TARGETED_DEVICE_FAMILY = "1,2,6";
VALIDATE_PRODUCT = YES;
};
Expand Down
2 changes: 1 addition & 1 deletion Samples.xcodeproj/xcshareddata/xcschemes/Samples.xcscheme
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1500"
LastUpgradeVersion = "1600"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ struct AnalyzeNetworkWithSubnetworkTraceView: View {
@State private var selectedComparison: UtilityNetworkAttributeComparison.Operator?

/// The value selected by the user.
@State private var selectedValue: Any?
@State private var selectedValue: (any Sendable)?

/// A Boolean value indicating if the add condition menu is presented.
@State private var isConditionMenuPresented = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,10 +136,6 @@ extension Animate3DGraphicView {
animation.setup(displayLink: displayLink)
}

deinit {
Task { await animation.displayLink?.invalidate() }
}

// MARK: Methods

/// Monitors the camera controller's properties to update the associated text when they change.
Expand Down
4 changes: 4 additions & 0 deletions Shared/Samples/Animate 3D graphic/Animate3DGraphicView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ struct Animate3DGraphicView: View {
} label: {
Image(systemName: model.animation.isPlaying ? "pause.fill" : "play.fill")
}
.onDisappear {
model.animation.displayLink?.invalidate()
}

Spacer()

SettingsView(label: "Camera") {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ struct AugmentRealityToNavigateRouteView: View {
.onSingleTapGesture { _, mapPoint in
tapLocation = mapPoint
}
.onDisappear {
Task {
await model.locationDisplay.dataSource.stop()
}
}
.task(id: tapLocation) {
guard let tapLocation else { return }

Expand Down Expand Up @@ -161,13 +166,6 @@ private extension AugmentRealityToNavigateRouteView {
/// The status text displayed to the user.
@Published var statusText = "Tap to place a start point."

deinit {
Task {
/// Stop the location data source.
await locationDisplay.dataSource.stop()
}
}

/// Performs important tasks including setting up the location display, creating route parameters,
/// and loading the scene elevation source.
func setUp() async throws {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ struct CreateAndSaveKMLView: View {

extension CreateAndSaveKMLView {
/// A KMZ file that can be used with the native file exporter.
final class KMZFile: FileDocument {
@MainActor
final class KMZFile: @preconcurrency FileDocument, Sendable {
yo1995 marked this conversation as resolved.
Show resolved Hide resolved
/// The KML document that is used to create the KMZ file.
private let document: KMLDocument

Expand Down Expand Up @@ -106,7 +107,6 @@ extension CreateAndSaveKMLView {
}

/// Saves the KML document as a KMZ file to a temporary location.
@MainActor
func saveFile() async throws {
temporaryDirectory = FileManager.createTemporaryDirectory()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,8 @@ extension CreateMobileGeodatabaseView {
// MARK: GeodatabaseFile

/// A geodatabase file that can be used with the native file exporter.
final class GeodatabaseFile {
@MainActor
final class GeodatabaseFile: Sendable {
yo1995 marked this conversation as resolved.
Show resolved Hide resolved
/// The mobile geodatabase used to create the geodatabase file.
private(set) var geodatabase: Geodatabase?

Expand Down Expand Up @@ -166,7 +167,7 @@ extension CreateMobileGeodatabaseView {
}
}

extension CreateMobileGeodatabaseView.GeodatabaseFile: FileDocument {
extension CreateMobileGeodatabaseView.GeodatabaseFile: @preconcurrency FileDocument {
/// The file and data types that the document reads from.
static var readableContentTypes: [UTType] { [.geodatabase] }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ extension DownloadPreplannedMapAreaView {
await withTaskGroup(of: Void.self) { group in
for model in allOfflineMapModels {
if model.isDownloading {
group.addTask { @MainActor in
group.addTask { @MainActor @Sendable in
await model.cancelDownloading()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,15 +100,15 @@ struct NavigateRouteWithReroutingView: View {
guard model.isNavigating, let routeTracker = model.routeTracker else { return }

await withTaskGroup(of: Void.self) { group in
group.addTask { @MainActor in
group.addTask { @MainActor @Sendable in
// Handle new tracking statuses from the route tracker.
for await trackingStatus in routeTracker.$trackingStatus {
guard let trackingStatus else { continue }
await model.updateProgress(using: trackingStatus)
}
}

group.addTask { @MainActor in
group.addTask { @MainActor @Sendable in
// Speak new voice guidances from the route tracker.
for await voiceGuidance in routeTracker.voiceGuidances {
model.speakVoiceGuidance(voiceGuidance)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ struct SetUpLocationDrivenGeotriggersView: View {
private func startGeotriggerMonitors(_ geotriggerMonitors: [GeotriggerMonitor]) async throws {
await withThrowingTaskGroup(of: Void.self) { group in
for monitor in geotriggerMonitors {
group.addTask { @MainActor in
group.addTask { @MainActor @Sendable in
try await monitor.start()
for await newNotification in monitor.notifications where newNotification is FenceGeotriggerNotificationInfo {
model.handleGeotriggerNotification(newNotification as! FenceGeotriggerNotificationInfo)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import Foundation

extension ShowDeviceLocationWithNMEADataSourcesView {
/// A data source simulating a hardware that emits NMEA data.
class FileNMEASentenceReader {
class FileNMEASentenceReader: @unchecked Sendable {
/// The playback time interval.
private let interval: TimeInterval

Expand Down Expand Up @@ -79,7 +79,7 @@ extension ShowDeviceLocationWithNMEADataSourcesView {
withTimeInterval: interval,
repeats: true
) { [weak self] _ in
guard let self = self else { return }
guard let self else { return }
let data = self.nmeaDataIterator.next()!
continuation.yield(data)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ struct ShowViewshedFromGeoelementInSceneView: View {

private extension ShowViewshedFromGeoelementInSceneView {
/// The view model for the sample.
class Model: ObservableObject {
class Model: ObservableObject, @unchecked Sendable {
yo1995 marked this conversation as resolved.
Show resolved Hide resolved
/// A scene with an imagery basemap.
let scene: ArcGIS.Scene = {
let scene = Scene(basemapStyle: .arcGISImagery)
Expand Down
yo1995 marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import Foundation

/// An extension allowing an array to be used with the app storage property wrapper.
extension Array: RawRepresentable where Element == String {
extension Array: @retroactive RawRepresentable where Element == String {
yo1995 marked this conversation as resolved.
Show resolved Hide resolved
/// Creates a new array from a given raw value.
/// - Parameter rawValue: The raw value of the array to create.
public init(rawValue: String) {
Expand Down
2 changes: 1 addition & 1 deletion Shared/Supporting Files/Models/OnDemandResource.swift
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,4 @@ final class OnDemandResource: ObservableObject {
}
}

extension NSBundleResourceRequest: @unchecked Sendable {}
extension NSBundleResourceRequest: @unchecked @retroactive Sendable {}
2 changes: 1 addition & 1 deletion Shared/Supporting Files/Views/SampleDetailView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -104,5 +104,5 @@ struct SampleDetailView: View {
}

extension SampleDetailView: Identifiable {
var id: String { sample.nameInUpperCamelCase }
nonisolated var id: String { sample.nameInUpperCamelCase }
}
3 changes: 1 addition & 2 deletions Shared/Supporting Files/Views/WebView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,14 @@ struct WebView: UIViewRepresentable {
switch navigationAction.navigationType {
case .linkActivated:
if let url = navigationAction.request.url {
await Self.openURL(url)
Self.openURL(url)
yo1995 marked this conversation as resolved.
Show resolved Hide resolved
}
return .cancel
default:
return .allow
}
}

@MainActor
yo1995 marked this conversation as resolved.
Show resolved Hide resolved
static func openURL(_ url: URL) {
guard UIApplication.shared.canOpenURL(url) else { return }
UIApplication.shared.open(url)
Expand Down
Loading