Skip to content

Commit

Permalink
Updates for Swift 6 compatibility
Browse files Browse the repository at this point in the history
- 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
  • Loading branch information
poetmountain committed Nov 13, 2024
1 parent 46250ac commit 3b96c28
Show file tree
Hide file tree
Showing 34 changed files with 1,220 additions and 955 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
### 2.1.0
- Support for Swift 6.0 and strict concurrency mode
- Removed many legacy forced unwrappings of Optionals
- Changed PhysicsMotion's DispatchSourceTimer to regular Timer to solve concurrency crash

### 2.0.1
- Fixed some retain cycles that were holding on to target objects
- Updated examples project
Expand Down
41 changes: 31 additions & 10 deletions Examples/MotionExamples.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objectVersion = 54;
objects = {

/* Begin PBXBuildFile section */
Expand Down Expand Up @@ -228,14 +228,14 @@
8BB379CC1CFFA17D00A35AFD /* Project object */ = {
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = YES;
LastSwiftUpdateCheck = 0730;
LastUpgradeCheck = 1240;
LastUpgradeCheck = 1610;
ORGANIZATIONNAME = "Poet & Mountain, LLC";
TargetAttributes = {
8BB379D31CFFA17D00A35AFD = {
CreatedOnToolsVersion = 7.3.1;
LastSwiftMigration = 0900;
ProvisioningStyle = Manual;
};
};
};
Expand Down Expand Up @@ -365,6 +365,7 @@
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
Expand All @@ -385,7 +386,7 @@
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 4.2;
SWIFT_VERSION = "";
};
name = Debug;
};
Expand Down Expand Up @@ -424,6 +425,7 @@
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
Expand All @@ -435,9 +437,10 @@
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 4.2;
SWIFT_VERSION = "";
VALIDATE_PRODUCT = YES;
};
name = Release;
Expand All @@ -446,25 +449,43 @@
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = HJVTQESL5X;
INFOPLIST_FILE = MotionExamples/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 15.4;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.poetmountain.MotionExamples;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_STRICT_CONCURRENCY = complete;
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 4.2;
SWIFT_VERSION = 5.0;
};
name = Debug;
};
8BB379EA1CFFA17E00A35AFD /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = HJVTQESL5X;
INFOPLIST_FILE = MotionExamples/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 15.4;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.poetmountain.MotionExamples;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_STRICT_CONCURRENCY = complete;
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 4.2;
SWIFT_VERSION = 5.0;
};
name = Release;
};
Expand Down
2 changes: 1 addition & 1 deletion Examples/MotionExamples/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import UIKit

@UIApplicationMain
@main
class AppDelegate: UIResponder, UIApplicationDelegate {

var window: UIWindow?
Expand Down
22 changes: 13 additions & 9 deletions Examples/MotionExamples/ButtonsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import UIKit

protocol ButtonsViewDelegate: class {
@MainActor protocol ButtonsViewDelegate: AnyObject {
func didStart()
func didStop()
func didPause()
Expand All @@ -17,10 +17,18 @@ protocol ButtonsViewDelegate: class {

public class ButtonsView: UIView {

public var startButton: UIButton!
public var stopButton: UIButton!
public var pauseButton: UIButton!
public var resumeButton: UIButton!
public var startButton: UIButton = {
return UIButton.init(type: .system)
}()
public var stopButton: UIButton = {
return UIButton.init(type: .system)
}()
public var pauseButton: UIButton = {
return UIButton.init(type: .system)
}()
public var resumeButton: UIButton = {
return UIButton.init(type: .system)
}()

var uiCreated: Bool = false

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

private func setupUI() {

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

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

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

resumeButton = UIButton.init(type: .system)
resumeButton.setTitle("Resume", for: UIControl.State())
resumeButton.addTarget(self, action: #selector(resume), for: .touchUpInside)
self.addSubview(resumeButton)
Expand Down
11 changes: 2 additions & 9 deletions Examples/MotionExamples/Classes/DynamicViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,11 @@ public class DynamicViewController: UIViewController, ButtonsViewDelegate {
motion.stop()
}
motions.removeAll()
}

deinit {

view.removeGestureRecognizer(tapRecognizer)
}





// MARK: - Private methods

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

let group = MotionGroup(motions: [motion_x, motion_y])
group.updated { [weak self] (group) in
guard let strong_self = self else { return }
//print("constraints \(strong_self.constraints)")
}
group.completed { [weak self] (group) in
guard let strong_self = self else { return }

Expand Down
47 changes: 47 additions & 0 deletions [email protected]
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// swift-tools-version: 6.0

// Package.swift
// MotionMachine
//
// Created by Brett Walker on 11/12/24.
// Copyright © 2024 Poet & Mountain, LLC. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

import PackageDescription

let package = Package(
name: "MotionMachine",
platforms: [
.iOS(.v13), .tvOS(.v13)
],
products: [
.library(name: "MotionMachine", targets: ["MotionMachine"])
],
targets: [
.target(name: "MotionMachine", path: "Sources/"),
.testTarget(
name: "MotionMachineTests",
dependencies: ["MotionMachine"],
path: "Tests/Tests/"
)
],
swiftLanguageModes: [.v6]
)
6 changes: 3 additions & 3 deletions Sources/CATempo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import UIKit
/**
* CATempo uses a `CADisplayLink` object to send out tempo updates that are synchronized with the refresh rate of the display on iOS.
*/
public class CATempo : Tempo {
@MainActor public class CATempo : Tempo {

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

deinit {
public override func cleanupResources() {
displayLink?.invalidate()

}


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

0 comments on commit 3b96c28

Please sign in to comment.