Skip to content

Commit 3b96c28

Browse files
committed
Updates for Swift 6 compatibility
- Support for Swift 6.0 and strict concurrency mode - Removed many legacy forced-unwrapping of Optionals - Changed PhysicsMotion's DispatchSourceTimer to regular Timer to solve concurrency crash
1 parent 46250ac commit 3b96c28

34 files changed

+1220
-955
lines changed

CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
### 2.1.0
2+
- Support for Swift 6.0 and strict concurrency mode
3+
- Removed many legacy forced unwrappings of Optionals
4+
- Changed PhysicsMotion's DispatchSourceTimer to regular Timer to solve concurrency crash
5+
16
### 2.0.1
27
- Fixed some retain cycles that were holding on to target objects
38
- Updated examples project

Examples/MotionExamples.xcodeproj/project.pbxproj

+31-10
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
archiveVersion = 1;
44
classes = {
55
};
6-
objectVersion = 46;
6+
objectVersion = 54;
77
objects = {
88

99
/* Begin PBXBuildFile section */
@@ -228,14 +228,14 @@
228228
8BB379CC1CFFA17D00A35AFD /* Project object */ = {
229229
isa = PBXProject;
230230
attributes = {
231+
BuildIndependentTargetsInParallel = YES;
231232
LastSwiftUpdateCheck = 0730;
232-
LastUpgradeCheck = 1240;
233+
LastUpgradeCheck = 1610;
233234
ORGANIZATIONNAME = "Poet & Mountain, LLC";
234235
TargetAttributes = {
235236
8BB379D31CFFA17D00A35AFD = {
236237
CreatedOnToolsVersion = 7.3.1;
237238
LastSwiftMigration = 0900;
238-
ProvisioningStyle = Manual;
239239
};
240240
};
241241
};
@@ -365,6 +365,7 @@
365365
DEBUG_INFORMATION_FORMAT = dwarf;
366366
ENABLE_STRICT_OBJC_MSGSEND = YES;
367367
ENABLE_TESTABILITY = YES;
368+
ENABLE_USER_SCRIPT_SANDBOXING = YES;
368369
GCC_C_LANGUAGE_STANDARD = gnu99;
369370
GCC_DYNAMIC_NO_PIC = NO;
370371
GCC_NO_COMMON_BLOCKS = YES;
@@ -385,7 +386,7 @@
385386
SDKROOT = iphoneos;
386387
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
387388
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
388-
SWIFT_VERSION = 4.2;
389+
SWIFT_VERSION = "";
389390
};
390391
name = Debug;
391392
};
@@ -424,6 +425,7 @@
424425
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
425426
ENABLE_NS_ASSERTIONS = NO;
426427
ENABLE_STRICT_OBJC_MSGSEND = YES;
428+
ENABLE_USER_SCRIPT_SANDBOXING = YES;
427429
GCC_C_LANGUAGE_STANDARD = gnu99;
428430
GCC_NO_COMMON_BLOCKS = YES;
429431
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
@@ -435,9 +437,10 @@
435437
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
436438
MTL_ENABLE_DEBUG_INFO = NO;
437439
SDKROOT = iphoneos;
438-
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
440+
SWIFT_COMPILATION_MODE = wholemodule;
441+
SWIFT_OPTIMIZATION_LEVEL = "-O";
439442
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
440-
SWIFT_VERSION = 4.2;
443+
SWIFT_VERSION = "";
441444
VALIDATE_PRODUCT = YES;
442445
};
443446
name = Release;
@@ -446,25 +449,43 @@
446449
isa = XCBuildConfiguration;
447450
buildSettings = {
448451
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
452+
CODE_SIGN_IDENTITY = "Apple Development";
453+
CODE_SIGN_STYLE = Automatic;
454+
DEVELOPMENT_TEAM = HJVTQESL5X;
449455
INFOPLIST_FILE = MotionExamples/Info.plist;
450-
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
456+
IPHONEOS_DEPLOYMENT_TARGET = 15.4;
457+
LD_RUNPATH_SEARCH_PATHS = (
458+
"$(inherited)",
459+
"@executable_path/Frameworks",
460+
);
451461
PRODUCT_BUNDLE_IDENTIFIER = com.poetmountain.MotionExamples;
452462
PRODUCT_NAME = "$(TARGET_NAME)";
463+
PROVISIONING_PROFILE_SPECIFIER = "";
464+
SWIFT_STRICT_CONCURRENCY = complete;
453465
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
454-
SWIFT_VERSION = 4.2;
466+
SWIFT_VERSION = 5.0;
455467
};
456468
name = Debug;
457469
};
458470
8BB379EA1CFFA17E00A35AFD /* Release */ = {
459471
isa = XCBuildConfiguration;
460472
buildSettings = {
461473
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
474+
CODE_SIGN_IDENTITY = "Apple Development";
475+
CODE_SIGN_STYLE = Automatic;
476+
DEVELOPMENT_TEAM = HJVTQESL5X;
462477
INFOPLIST_FILE = MotionExamples/Info.plist;
463-
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
478+
IPHONEOS_DEPLOYMENT_TARGET = 15.4;
479+
LD_RUNPATH_SEARCH_PATHS = (
480+
"$(inherited)",
481+
"@executable_path/Frameworks",
482+
);
464483
PRODUCT_BUNDLE_IDENTIFIER = com.poetmountain.MotionExamples;
465484
PRODUCT_NAME = "$(TARGET_NAME)";
485+
PROVISIONING_PROFILE_SPECIFIER = "";
486+
SWIFT_STRICT_CONCURRENCY = complete;
466487
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
467-
SWIFT_VERSION = 4.2;
488+
SWIFT_VERSION = 5.0;
468489
};
469490
name = Release;
470491
};

Examples/MotionExamples/AppDelegate.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
import UIKit
1010

11-
@UIApplicationMain
11+
@main
1212
class AppDelegate: UIResponder, UIApplicationDelegate {
1313

1414
var window: UIWindow?

Examples/MotionExamples/ButtonsView.swift

+13-9
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
import UIKit
1010

11-
protocol ButtonsViewDelegate: class {
11+
@MainActor protocol ButtonsViewDelegate: AnyObject {
1212
func didStart()
1313
func didStop()
1414
func didPause()
@@ -17,10 +17,18 @@ protocol ButtonsViewDelegate: class {
1717

1818
public class ButtonsView: UIView {
1919

20-
public var startButton: UIButton!
21-
public var stopButton: UIButton!
22-
public var pauseButton: UIButton!
23-
public var resumeButton: UIButton!
20+
public var startButton: UIButton = {
21+
return UIButton.init(type: .system)
22+
}()
23+
public var stopButton: UIButton = {
24+
return UIButton.init(type: .system)
25+
}()
26+
public var pauseButton: UIButton = {
27+
return UIButton.init(type: .system)
28+
}()
29+
public var resumeButton: UIButton = {
30+
return UIButton.init(type: .system)
31+
}()
2432

2533
var uiCreated: Bool = false
2634

@@ -44,22 +52,18 @@ public class ButtonsView: UIView {
4452

4553
private func setupUI() {
4654

47-
startButton = UIButton.init(type: .system)
4855
startButton.setTitle("Start", for: UIControl.State())
4956
startButton.addTarget(self, action: #selector(start), for: .touchUpInside)
5057
self.addSubview(startButton)
5158

52-
stopButton = UIButton.init(type: .system)
5359
stopButton.setTitle("Stop", for: UIControl.State())
5460
stopButton.addTarget(self, action: #selector(stop), for: .touchUpInside)
5561
self.addSubview(stopButton)
5662

57-
pauseButton = UIButton.init(type: .system)
5863
pauseButton.setTitle("Pause", for: UIControl.State())
5964
pauseButton.addTarget(self, action: #selector(pause), for: .touchUpInside)
6065
self.addSubview(pauseButton)
6166

62-
resumeButton = UIButton.init(type: .system)
6367
resumeButton.setTitle("Resume", for: UIControl.State())
6468
resumeButton.addTarget(self, action: #selector(resume), for: .touchUpInside)
6569
self.addSubview(resumeButton)

Examples/MotionExamples/Classes/DynamicViewController.swift

+2-9
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,11 @@ public class DynamicViewController: UIViewController, ButtonsViewDelegate {
5656
motion.stop()
5757
}
5858
motions.removeAll()
59-
}
60-
61-
deinit {
59+
6260
view.removeGestureRecognizer(tapRecognizer)
6361
}
6462

65-
66-
63+
6764

6865
// MARK: - Private methods
6966

@@ -170,10 +167,6 @@ public class DynamicViewController: UIViewController, ButtonsViewDelegate {
170167
motion_y.additive = true
171168

172169
let group = MotionGroup(motions: [motion_x, motion_y])
173-
group.updated { [weak self] (group) in
174-
guard let strong_self = self else { return }
175-
//print("constraints \(strong_self.constraints)")
176-
}
177170
group.completed { [weak self] (group) in
178171
guard let strong_self = self else { return }
179172

Package@swift-6.0.swift

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// swift-tools-version: 6.0
2+
3+
// Package.swift
4+
// MotionMachine
5+
//
6+
// Created by Brett Walker on 11/12/24.
7+
// Copyright © 2024 Poet & Mountain, LLC. All rights reserved.
8+
//
9+
// Permission is hereby granted, free of charge, to any person obtaining a copy
10+
// of this software and associated documentation files (the "Software"), to deal
11+
// in the Software without restriction, including without limitation the rights
12+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+
// copies of the Software, and to permit persons to whom the Software is
14+
// furnished to do so, subject to the following conditions:
15+
//
16+
// The above copyright notice and this permission notice shall be included in
17+
// all copies or substantial portions of the Software.
18+
//
19+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+
// THE SOFTWARE.
26+
//
27+
28+
import PackageDescription
29+
30+
let package = Package(
31+
name: "MotionMachine",
32+
platforms: [
33+
.iOS(.v13), .tvOS(.v13)
34+
],
35+
products: [
36+
.library(name: "MotionMachine", targets: ["MotionMachine"])
37+
],
38+
targets: [
39+
.target(name: "MotionMachine", path: "Sources/"),
40+
.testTarget(
41+
name: "MotionMachineTests",
42+
dependencies: ["MotionMachine"],
43+
path: "Tests/Tests/"
44+
)
45+
],
46+
swiftLanguageModes: [.v6]
47+
)

Sources/CATempo.swift

+3-3
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import UIKit
2929
/**
3030
* CATempo uses a `CADisplayLink` object to send out tempo updates that are synchronized with the refresh rate of the display on iOS.
3131
*/
32-
public class CATempo : Tempo {
32+
@MainActor public class CATempo : Tempo {
3333

3434
/**
3535
* This `CADisplayLink` object is used to provide tempo updates.
@@ -51,10 +51,10 @@ public class CATempo : Tempo {
5151
displayLink?.add(to: RunLoop.main, forMode: .common)
5252
}
5353

54-
deinit {
54+
public override func cleanupResources() {
5555
displayLink?.invalidate()
56+
5657
}
57-
5858

5959
@objc func update() -> Void {
6060
let time_stamp: CFTimeInterval = self.displayLink?.timestamp ?? 0.0

0 commit comments

Comments
 (0)