diff --git a/.circleci/config.yml b/.circleci/config.yml index 525d1c0..92258c6 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -9,7 +9,7 @@ anchors: - &test_output_folder test_output - &default_executor macos: - xcode: "13.2.1" + xcode: "14.0.0" env: global: @@ -124,13 +124,13 @@ jobs: - store_test_results: path: swiftlint.html - test-xcode12-ios14: + test-xcode13-ios15: macos: - xcode: "12.5.0" + xcode: "13.0.0" steps: - test_main_project - test-xcode13-ios15: + test-xcode14-ios16: <<: *default_executor steps: - test_main_project @@ -152,9 +152,9 @@ workflows: build-and-test: jobs: - swiftlint: - version: 0.39.2 - - test-xcode12-ios14 + version: 0.49.1 - test-xcode13-ios15 + - test-xcode14-ios16 - test-example-messages - test-example-demo diff --git a/.swiftlint.yml b/.swiftlint.yml index 5fa0cdc..809a5eb 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -18,6 +18,8 @@ disabled_rules: - shorthand_operator - unused_closure_parameter + - inclusive_language + opt_in_rules: - first_where - last_where diff --git a/Examples/Messages/Example.xcodeproj/project.pbxproj b/Examples/Messages/Example.xcodeproj/project.pbxproj index bd090c1..8cf234d 100644 --- a/Examples/Messages/Example.xcodeproj/project.pbxproj +++ b/Examples/Messages/Example.xcodeproj/project.pbxproj @@ -9,6 +9,8 @@ /* Begin PBXBuildFile section */ 2A8568E12344F73200B9D157 /* ExampleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A8568E02344F73200B9D157 /* ExampleTests.swift */; }; 75593950283BA41200EA10E9 /* Presentation in Frameworks */ = {isa = PBXBuildFile; productRef = 7559394F283BA41200EA10E9 /* Presentation */; }; + C8D31DC528E5B8AD00CB59C2 /* Flow in Frameworks */ = {isa = PBXBuildFile; productRef = C8D31DC428E5B8AD00CB59C2 /* Flow */; }; + C8D31DC828E5B91A00CB59C2 /* Form in Frameworks */ = {isa = PBXBuildFile; productRef = C8D31DC728E5B91A00CB59C2 /* Form */; }; F61928ED2088DE200008F713 /* Messages.swift in Sources */ = {isa = PBXBuildFile; fileRef = F61928EC2088DE200008F713 /* Messages.swift */; }; F61928EF2088DE7E0008F713 /* ComposeMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = F61928EE2088DE7E0008F713 /* ComposeMessage.swift */; }; F61928F12088DEBD0008F713 /* MessageDetails.swift in Sources */ = {isa = PBXBuildFile; fileRef = F61928F02088DEBD0008F713 /* MessageDetails.swift */; }; @@ -64,6 +66,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + C8D31DC828E5B91A00CB59C2 /* Form in Frameworks */, + C8D31DC528E5B8AD00CB59C2 /* Flow in Frameworks */, 75593950283BA41200EA10E9 /* Presentation in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -148,6 +152,8 @@ name = Example; packageProductDependencies = ( 7559394F283BA41200EA10E9 /* Presentation */, + C8D31DC428E5B8AD00CB59C2 /* Flow */, + C8D31DC728E5B91A00CB59C2 /* Form */, ); productName = Messages; productReference = F6B3E0552086210E00F55C53 /* Example.app */; @@ -183,6 +189,8 @@ mainGroup = F6B3E04C2086210E00F55C53; packageReferences = ( 7559394E283BA41200EA10E9 /* XCRemoteSwiftPackageReference "Presentation" */, + C8D31DC328E5B8AD00CB59C2 /* XCRemoteSwiftPackageReference "Flow" */, + C8D31DC628E5B91A00CB59C2 /* XCRemoteSwiftPackageReference "Form" */, ); productRefGroup = F6B3E0562086210E00F55C53 /* Products */; projectDirPath = ""; @@ -348,7 +356,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.3; + IPHONEOS_DEPLOYMENT_TARGET = 12.1; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -402,7 +410,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.3; + IPHONEOS_DEPLOYMENT_TARGET = 12.1; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SWIFT_COMPILATION_MODE = wholemodule; @@ -417,6 +425,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_STYLE = Automatic; INFOPLIST_FILE = Example/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.1; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -434,6 +443,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_STYLE = Automatic; INFOPLIST_FILE = Example/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.1; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -486,6 +496,22 @@ minimumVersion = 1.15.2; }; }; + C8D31DC328E5B8AD00CB59C2 /* XCRemoteSwiftPackageReference "Flow" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/iZettle/Flow.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 1.0.0; + }; + }; + C8D31DC628E5B91A00CB59C2 /* XCRemoteSwiftPackageReference "Form" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/iZettle/Form.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 4.0.0; + }; + }; /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ @@ -494,6 +520,16 @@ package = 7559394E283BA41200EA10E9 /* XCRemoteSwiftPackageReference "Presentation" */; productName = Presentation; }; + C8D31DC428E5B8AD00CB59C2 /* Flow */ = { + isa = XCSwiftPackageProductDependency; + package = C8D31DC328E5B8AD00CB59C2 /* XCRemoteSwiftPackageReference "Flow" */; + productName = Flow; + }; + C8D31DC728E5B91A00CB59C2 /* Form */ = { + isa = XCSwiftPackageProductDependency; + package = C8D31DC628E5B91A00CB59C2 /* XCRemoteSwiftPackageReference "Form" */; + productName = Form; + }; /* End XCSwiftPackageProductDependency section */ }; rootObject = F6B3E04D2086210E00F55C53 /* Project object */; diff --git a/Examples/Messages/Example.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Examples/Messages/Example.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 07d2704..109baae 100644 --- a/Examples/Messages/Example.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Examples/Messages/Example.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,25 +1,32 @@ { - "object": { - "pins": [ - { - "package": "Flow", - "repositoryURL": "https://github.com/izettle/Flow.git", - "state": { - "branch": null, - "revision": "ad38c734f16a404de8895236424bc4acc5355a3d", - "version": "1.10.1" - } - }, - { - "package": "Presentation", - "repositoryURL": "https://github.com/iZettle/Presentation.git", - "state": { - "branch": null, - "revision": "491735c045a0e61e4e2536a2da41b347c533d7e6", - "version": "1.15.2" - } + "pins" : [ + { + "identity" : "flow", + "kind" : "remoteSourceControl", + "location" : "https://github.com/izettle/Flow.git", + "state" : { + "revision" : "ad38c734f16a404de8895236424bc4acc5355a3d", + "version" : "1.10.1" } - ] - }, - "version": 1 + }, + { + "identity" : "form", + "kind" : "remoteSourceControl", + "location" : "https://github.com/iZettle/Form.git", + "state" : { + "revision" : "6eee6b0b49c5f178e15339760fdb05cbbfdf5e07", + "version" : "4.0.0" + } + }, + { + "identity" : "presentation", + "kind" : "remoteSourceControl", + "location" : "https://github.com/iZettle/Presentation.git", + "state" : { + "revision" : "491735c045a0e61e4e2536a2da41b347c533d7e6", + "version" : "1.15.2" + } + } + ], + "version" : 2 } diff --git a/Form.xcodeproj/project.pbxproj b/Form.xcodeproj/project.pbxproj index a4941e8..9fc9fed 100644 --- a/Form.xcodeproj/project.pbxproj +++ b/Form.xcodeproj/project.pbxproj @@ -710,6 +710,7 @@ CLANG_ANALYZER_NONNULL = YES; FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/Carthage/Build/iOS"; INFOPLIST_FILE = FormTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.1; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -727,6 +728,7 @@ CLANG_ANALYZER_NONNULL = YES; FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/Carthage/Build/iOS"; INFOPLIST_FILE = FormTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 12.1; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -780,7 +782,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.1; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -833,7 +835,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.1; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SWIFT_COMPILATION_MODE = wholemodule; @@ -858,6 +860,7 @@ HEADER_SEARCH_PATHS = "$(SRCROOT)/**"; INFOPLIST_FILE = Form/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.1; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -883,6 +886,7 @@ HEADER_SEARCH_PATHS = "$(SRCROOT)/**"; INFOPLIST_FILE = Form/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.1; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", diff --git a/Form/FormStyle.swift b/Form/FormStyle.swift index 847f86e..5e97857 100644 --- a/Form/FormStyle.swift +++ b/Form/FormStyle.swift @@ -18,7 +18,7 @@ public struct FormStyle: Style { public struct DynamicFormStyle: DynamicStyle { public var styleGenerator: (UITraitCollection) -> FormStyle - public init(generateStyle : @escaping (UITraitCollection) -> FormStyle) { + public init(generateStyle: @escaping (UITraitCollection) -> FormStyle) { self.styleGenerator = generateStyle } } diff --git a/Form/FormView.swift b/Form/FormView.swift index fcad16c..dab52e1 100644 --- a/Form/FormView.swift +++ b/Form/FormView.swift @@ -47,7 +47,7 @@ public extension FormView { return visibleViews } - //swiftlint:disable:next unused_setter_value + // swiftlint:disable superfluous_disable_command unused_setter_value set { /* Always computed */ } } diff --git a/Form/HeaderFooterStyle.swift b/Form/HeaderFooterStyle.swift index 7ab9214..b917cf7 100644 --- a/Form/HeaderFooterStyle.swift +++ b/Form/HeaderFooterStyle.swift @@ -28,7 +28,7 @@ public struct HeaderFooterStyle: Style { public struct DynamicHeaderFooterStyle: DynamicStyle { public var styleGenerator: (UITraitCollection) -> HeaderFooterStyle - public init(generateStyle : @escaping (UITraitCollection) -> HeaderFooterStyle) { + public init(generateStyle: @escaping (UITraitCollection) -> HeaderFooterStyle) { self.styleGenerator = generateStyle } } diff --git a/Form/ParentChildRelational.swift b/Form/ParentChildRelational.swift index c9c2db6..9975f5a 100644 --- a/Form/ParentChildRelational.swift +++ b/Form/ParentChildRelational.swift @@ -88,7 +88,7 @@ public extension ParentChildRelational { } } - ///Returns the first ancestor of type `type` if any. + /// Returns the first ancestor of type `type` if any. func firstAncestor(ofType type: T.Type) -> T? { guard let parent = parent else { return nil } if let matching = parent as? T { diff --git a/Form/SectionStyle.swift b/Form/SectionStyle.swift index fb5b830..67715dc 100644 --- a/Form/SectionStyle.swift +++ b/Form/SectionStyle.swift @@ -54,7 +54,7 @@ public extension SectionStyle { public struct DynamicSectionStyle: DynamicStyle { public var styleGenerator: (UITraitCollection) -> SectionStyle - public init(generateStyle : @escaping (UITraitCollection) -> SectionStyle) { + public init(generateStyle: @escaping (UITraitCollection) -> SectionStyle) { self.styleGenerator = generateStyle } } diff --git a/Form/SectionView.swift b/Form/SectionView.swift index b951b73..f8042fc 100644 --- a/Form/SectionView.swift +++ b/Form/SectionView.swift @@ -105,7 +105,7 @@ public extension SectionView { return elements } - //swiftlint:disable:next unused_setter_value + // swiftlint:disable superfluous_disable_command unused_setter_value set { /* Always computed */ } } diff --git a/Form/UIScrollView+Keyboard.swift b/Form/UIScrollView+Keyboard.swift index e49dab7..3d815a7 100644 --- a/Form/UIScrollView+Keyboard.swift +++ b/Form/UIScrollView+Keyboard.swift @@ -51,7 +51,7 @@ public extension UIScrollView { } public extension UIScrollView { - /// Will dynamically adjust the content offset of `self` to reveal first responders. + /// Will dynamically adjust the content offset of `self` to reveal first responders. /// Parameter adjustInsets: Function to adjust the frame of the first responder view used to calculate the content offset. Defaults to `alignToRow`. /// - Returns: A disposable that will stop adjustments when being disposed. func scrollToRevealFirstResponder(_ adjustInsets: @escaping (UIView) -> UIEdgeInsets = alignToRow) -> Disposable { diff --git a/Form/UIScrollView+Pinning.swift b/Form/UIScrollView+Pinning.swift index b3b4ebb..34e78f4 100644 --- a/Form/UIScrollView+Pinning.swift +++ b/Form/UIScrollView+Pinning.swift @@ -189,7 +189,7 @@ private extension UIScrollView { switch edge { case .bottom: // FIXME: enable for iOS 11 if we can remove the re-pin hack - //precondition(self[insets: insetKey].bottom == 0, "Only one view can be pinned to bottom") + // precondition(self[insets: insetKey].bottom == 0, "Only one view can be pinned to bottom") bag += viewHeight.atOnce().onValue { height in self[insets: insetKey].bottom = height } @@ -223,7 +223,7 @@ private extension UIScrollView { case .top: // FIXME: enable for iOS 11 if we can remove the re-pin hack - //precondition(self[insets: insetKey].bottom == 0, "Only one view can be pinned to top") + // precondition(self[insets: insetKey].bottom == 0, "Only one view can be pinned to top") bag += viewHeight.atOnce().onValue { height in self[insets: insetKey].top = height } diff --git a/Form/UIScrollView+Spacing.swift b/Form/UIScrollView+Spacing.swift index 8e49ba6..f20170b 100644 --- a/Form/UIScrollView+Spacing.swift +++ b/Form/UIScrollView+Spacing.swift @@ -57,6 +57,7 @@ public extension UIScrollView { disembedBag += { deactivate(constraints) } // .equalSpacing gives ambigious layout on iOS < 11, help out by calculating spacing manually. + // swiftlint:disable:next unavailable_condition if #available(iOS 11, *) {} else if !orderedViews.isEmpty { let contentHeight = signal(for: \.contentSize)[\.height].toVoid().atValue { for view in orderedViews { view.layoutIfNeeded() } diff --git a/Form/UITableViewCell+Utilities.swift b/Form/UITableViewCell+Utilities.swift index a73b5c3..858c815 100644 --- a/Form/UITableViewCell+Utilities.swift +++ b/Form/UITableViewCell+Utilities.swift @@ -151,10 +151,8 @@ public extension UITableViewCell { extension UITableViewCell { var reorderControlView: UIView? { - for view in subviews as [UIView] { - if type(of: view).description() == "UITableViewCellReorderControl" { - return view - } + for view in subviews as [UIView] where type(of: view).description() == "UITableViewCellReorderControl" { + return view } return nil } @@ -208,8 +206,8 @@ private extension UITableViewCell { // Passing through touches if the touch doesn't hit a subview private class TapThroughView: UIView { fileprivate override func point(inside point: CGPoint, with event: UIEvent?) -> Bool { - for subview in subviews { - if subview.point(inside: convert(point, to: subview), with: event) { return true } + for subview in subviews where subview.point(inside: convert(point, to: subview), with: event) { + return true } return false } diff --git a/Form/ValueField.swift b/Form/ValueField.swift index 0d72372..d54d28f 100644 --- a/Form/ValueField.swift +++ b/Form/ValueField.swift @@ -172,7 +172,7 @@ public final class ValueField: UIControl, UIKeyInput { get { editor.accessibilityValue } - //swiftlint:disable:next unused_setter_value + // swiftlint:disable superfluous_disable_command unused_setter_value set { /* accessibilityValue is always read from the editor. */ } } @@ -191,7 +191,7 @@ public final class ValueField: UIControl, UIKeyInput { /// Always use `.no` autocorrection as the system keyboard will be confused if it is used. public dynamic var autocorrectionType: UITextAutocorrectionType { get { return .no } - //swiftlint:disable:next unused_setter_value + // swiftlint:disable:next unused_setter_value set { /* ignore */ } } diff --git a/FormTests/CollectionDiffTests.swift b/FormTests/CollectionDiffTests.swift index 12aa33c..73a95ce 100644 --- a/FormTests/CollectionDiffTests.swift +++ b/FormTests/CollectionDiffTests.swift @@ -15,6 +15,7 @@ func changes(from old: [T], to new: [T]) -> [ChangeStep] { } func randomizedArray(length: Int) -> [Int] { + // swiftlint:disable:next legacy_random return (1...length).map { _ in Int(arc4random_uniform(UInt32(length))) } }