From 1d9a8b82cf8904fd2362224928155867d2c46ae3 Mon Sep 17 00:00:00 2001 From: Gio Lodi Date: Tue, 24 Mar 2026 11:34:16 +1100 Subject: [PATCH 1/5] Enable SwiftLint rule: empty_count Prefer checking `isEmpty` over comparing `count` to zero. Part of the Orchard SwiftLint rollout campaign. --- Generated with the help of Claude Code, https://code.claude.com Co-Authored-By: Claude Code Opus 4.6 (1M context) --- .swiftlint.yml | 3 +++ .../Sources/JetpackStats/Charts/BarChartView.swift | 2 +- .../JetpackStats/Charts/LineChartView.swift | 2 +- .../JetpackStats/Charts/SimpleBarChartView.swift | 2 +- .../JetpackStats/Screens/TopListScreenView.swift | 2 +- .../Services/Mocks/StatsDataAggregator.swift | 2 +- .../TopList/Rows/TopListExternalLinkRowView.swift | 2 +- .../UITestsFoundation/Screens/CommentsScreen.swift | 2 +- .../Utilities/ContentExtractor.swift | 2 +- .../Sources/WordPressKit/JetpackScanThreat.swift | 2 +- .../WordPressKit/JetpackThreatFixStatus.swift | 4 ++-- .../WordPressKit/SiteDesignServiceRemote.swift | 2 +- .../Sources/WordPressKit/WordPressComRestApi.swift | 2 +- .../WordPressKit/WordPressOrgXMLRPCValidator.swift | 2 +- .../Utility/RichContentFormatter.swift | 14 +++++++------- .../JetpackStatsTests/MockStatsServiceTests.swift | 4 ++-- .../WeeklyTrendsViewModelTests.swift | 4 ++-- .../WordPressSharedTests/LanguagesTests.swift | 8 ++++---- .../FancyAlertViewController+LoginError.swift | 2 +- .../Features/SignIn/LoginViewController.swift | 2 +- .../ViewRelated/2FA/TwoFAViewController.swift | 2 +- .../Views/SearchTableViewCell.swift | 4 ++-- Sources/WordPressData/Swift/Blog+Lookup.swift | 4 ++-- Sources/WordPressData/Swift/Post.swift | 6 +++--- .../Swift/ReaderCard+CoreDataClass.swift | 4 ++-- .../Swift/WordPressOrgRestApi+WordPress.swift | 2 +- .../Media/StockPhotos/MockStockPhotosService.swift | 2 +- .../Features/Media/Tenor/MockTenorService.swift | 2 +- .../Tests/Services/DomainsServiceTests.swift | 2 +- .../Tests/Utility/PagesListTests.swift | 4 ++-- .../Tests/Utility/RouteMatcherTests.swift | 4 ++-- Tests/WordPressDataTests/CoreDataHelperTests.swift | 2 +- .../PostMetadataContainerTests.swift | 4 ++-- .../Tests/ActivityServiceRemoteTests.swift | 2 +- .../Tests/DomainsServiceRemoteRESTTests.swift | 2 +- .../Tests/PeopleServiceRemoteTests.swift | 4 ++-- .../Classes/Extensions/WKWebView+UserAgent.swift | 2 +- .../Navigation/MigrationFlowCoordinator.swift | 2 +- .../Done/MigrationDoneViewController.swift | 2 +- WordPress/Classes/Stores/PluginStore.swift | 2 +- .../System/WordPressAppDelegate+openURL.swift | 2 +- .../WeeklyRoundupBackgroundTask.swift | 6 +++--- .../BloggingRemindersScheduleFormatter.swift | 4 ++-- .../BloggingRemindersScheduler.swift | 4 ++-- .../Utility/ImmuTable/ImmuTable+Optional.swift | 2 +- .../Sharing/ShareExtensionSessionManager.swift | 2 +- .../Migration/WPAdminConvertibleRouter.swift | 2 +- .../Universal Links/UniversalLinkRouter.swift | 2 +- WordPress/Classes/Utility/Version.swift | 4 ++-- WordPress/Classes/Utility/ZendeskUtils.swift | 8 ++++---- .../ViewControllers/AztecPostViewController.swift | 2 +- .../Cards/DashboardJetpackSocialCardCell.swift | 6 +++--- .../Blog Details/BlogDetailsTableViewModel.swift | 2 +- ...oggingRemindersFlowSettingsViewController.swift | 4 ++-- .../Blog/Sharing/PublicizeServicesState.swift | 2 +- .../Sharing/SharingAccountViewController.swift | 6 +++--- .../Sharing/SharingButtonsViewController.swift | 2 +- .../RegisterDomainDetailsViewController.swift | 4 ++-- .../Domains/DomainSelectionViewController.swift | 4 ++-- .../Domains/View Models/SiteDomainsViewModel.swift | 4 ++-- .../Gutenberg/GutenbergMediaPickerHelper.swift | 2 +- .../FilterableCategoriesViewController.swift | 4 ++-- .../Utils/GutenbergFilesAppMediaSource.swift | 2 +- .../Jetpack Scan/JetpackScanCoordinator.swift | 2 +- .../View Models/JetpackScanStatusViewModel.swift | 2 +- .../View Models/AllDomainsListViewModel.swift | 2 +- .../SiteMediaAddMediaMenuController.swift | 2 +- .../Media/SiteMedia/SiteMediaViewController.swift | 4 ++-- .../Media/StockPhotos/StockPhotosDataSource.swift | 2 +- .../ViewRelated/Media/Tenor/TenorDataSource.swift | 2 +- .../SignupUsernameTableViewController.swift | 4 ++-- .../Controllers/NotificationContentRouter.swift | 2 +- .../NotificationSettingDetailsViewController.swift | 2 +- .../NotificationSettingsViewController.swift | 2 +- .../NotificationsViewController.swift | 2 +- .../Controllers/InvitePersonViewController.swift | 10 +++++----- .../People/Controllers/PeopleViewController.swift | 2 +- .../People/Controllers/PersonViewController.swift | 2 +- .../Plugins/ViewModels/PluginListViewModel.swift | 2 +- .../Post/Categories/PostCategoryCreateView.swift | 2 +- .../AbstractPostListViewController.swift | 8 ++++---- .../Views/PrepublishingAutoSharingView.swift | 2 +- .../ReaderSiteSearchViewController.swift | 4 ++-- .../Controllers/ReaderStreamViewController.swift | 8 ++++---- .../ReaderSelectInterestsViewController.swift | 4 ++-- .../Reader/Views/ReaderInterestsCoordinator.swift | 2 +- .../ViewRelated/Stats/Charts/DonutChartView.swift | 2 +- .../ViewRelated/Stats/Charts/SparklineView.swift | 2 +- .../InsightsManagementViewController.swift | 10 +++++----- .../Stats/Insights/TabbedTotalsCell.swift | 4 ++-- .../Period Stats/SiteStatsPeriodViewModel.swift | 2 +- .../Post Stats/PostStatsViewModel.swift | 2 +- .../Stats Detail/SiteStatsDetailsViewModel.swift | 2 +- .../SiteStatsInsightsDetailsViewModel.swift | 2 +- .../StatsReferrersChartViewModel.swift | 2 +- .../Stats/Shared Views/TopTotalsCell.swift | 2 +- .../Suggestions/SuggestionsListViewModel.swift | 4 ++-- .../Classes/ViewRelated/Tags/SiteTagsView.swift | 2 +- .../Tools/SettingsListEditorViewController.swift | 2 +- .../Sources/Services/AppExtensionsService.swift | 2 +- .../Sources/Services/ShareExtractor.swift | 6 +++--- .../Sources/UI/ShareModularViewController.swift | 4 ++-- 102 files changed, 165 insertions(+), 162 deletions(-) diff --git a/.swiftlint.yml b/.swiftlint.yml index 8d9ef1eb50c7..7dc00fbf8012 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -26,6 +26,9 @@ only_rules: - duplicate_imports + # Prefer checking `isEmpty` over comparing `count` to zero. + - empty_count + # Arguments can be omitted when matching enums with associated types if they # are not used. - empty_enum_arguments diff --git a/Modules/Sources/JetpackStats/Charts/BarChartView.swift b/Modules/Sources/JetpackStats/Charts/BarChartView.swift index 90a04b22d6c5..5b12fc9723ec 100644 --- a/Modules/Sources/JetpackStats/Charts/BarChartView.swift +++ b/Modules/Sources/JetpackStats/Charts/BarChartView.swift @@ -158,7 +158,7 @@ struct BarChartView: View { @ChartContentBuilder private var significantPointAnnotations: some ChartContent { - if tappedDataPoint == nil, let maxPoint = data.significantPoints.currentMax, data.currentData.count > 0 { + if tappedDataPoint == nil, let maxPoint = data.significantPoints.currentMax, !data.currentData.isEmpty { PointMark( x: .value("Date", maxPoint.date, unit: data.granularity.component, calendar: context.calendar), y: .value("Value", maxPoint.value) diff --git a/Modules/Sources/JetpackStats/Charts/LineChartView.swift b/Modules/Sources/JetpackStats/Charts/LineChartView.swift index 8ffea6a906ef..3a3553e2bf87 100644 --- a/Modules/Sources/JetpackStats/Charts/LineChartView.swift +++ b/Modules/Sources/JetpackStats/Charts/LineChartView.swift @@ -165,7 +165,7 @@ struct LineChartView: View { @ChartContentBuilder private var significantPointAnnotations: some ChartContent { - if let maxPoint = data.significantPoints.currentMax, data.currentData.count > 0 { + if let maxPoint = data.significantPoints.currentMax, !data.currentData.isEmpty { PointMark( x: .value("Date", maxPoint.date, unit: data.granularity.component, calendar: context.calendar), y: .value("Value", maxPoint.value) diff --git a/Modules/Sources/JetpackStats/Charts/SimpleBarChartView.swift b/Modules/Sources/JetpackStats/Charts/SimpleBarChartView.swift index 6e9e4ba7c16f..2ee041b36762 100644 --- a/Modules/Sources/JetpackStats/Charts/SimpleBarChartView.swift +++ b/Modules/Sources/JetpackStats/Charts/SimpleBarChartView.swift @@ -102,7 +102,7 @@ struct SimpleBarChartView: View { @ChartContentBuilder private var peakAnnotation: some ChartContent { - if let maxPoint = data.currentData.max(by: { $0.value < $1.value }), data.currentData.count > 0 { + if let maxPoint = data.currentData.max(by: { $0.value < $1.value }), !data.currentData.isEmpty { PointMark( x: .value("Date", maxPoint.date, unit: data.granularity.component), y: .value("Value", maxPoint.value) diff --git a/Modules/Sources/JetpackStats/Screens/TopListScreenView.swift b/Modules/Sources/JetpackStats/Screens/TopListScreenView.swift index cc23f9484903..f4bdfd66e702 100644 --- a/Modules/Sources/JetpackStats/Screens/TopListScreenView.swift +++ b/Modules/Sources/JetpackStats/Screens/TopListScreenView.swift @@ -181,7 +181,7 @@ struct TopListScreenView: View { @ViewBuilder private func listContent(data: TopListData) -> some View { - if data.items.count > 0 { + if !data.items.isEmpty { listSection(.top10, data: data) } if data.items.count > 10 { diff --git a/Modules/Sources/JetpackStats/Services/Mocks/StatsDataAggregator.swift b/Modules/Sources/JetpackStats/Services/Mocks/StatsDataAggregator.swift index fedca5365bf5..e934cfd22043 100644 --- a/Modules/Sources/JetpackStats/Services/Mocks/StatsDataAggregator.swift +++ b/Modules/Sources/JetpackStats/Services/Mocks/StatsDataAggregator.swift @@ -61,7 +61,7 @@ struct StatsDataAggregator { case .sum: normalizedData[date] = dataPoint.sum case .average: - if dataPoint.count > 0 { + if !dataPoint.isEmpty { normalizedData[date] = dataPoint.sum / dataPoint.count } } diff --git a/Modules/Sources/JetpackStats/Views/TopList/Rows/TopListExternalLinkRowView.swift b/Modules/Sources/JetpackStats/Views/TopList/Rows/TopListExternalLinkRowView.swift index 9479c5ece7a0..86c18881c031 100644 --- a/Modules/Sources/JetpackStats/Views/TopList/Rows/TopListExternalLinkRowView.swift +++ b/Modules/Sources/JetpackStats/Views/TopList/Rows/TopListExternalLinkRowView.swift @@ -10,7 +10,7 @@ struct TopListExternalLinkRowView: View { .foregroundColor(.primary) .lineLimit(1) - if item.children.count > 0 { + if !item.children.isEmpty { Text(Strings.ArchiveSections.itemCount(item.children.count)) .font(.caption) .foregroundColor(.secondary) diff --git a/Modules/Sources/UITestsFoundation/Screens/CommentsScreen.swift b/Modules/Sources/UITestsFoundation/Screens/CommentsScreen.swift index e8c115914ab8..632d264cad2e 100644 --- a/Modules/Sources/UITestsFoundation/Screens/CommentsScreen.swift +++ b/Modules/Sources/UITestsFoundation/Screens/CommentsScreen.swift @@ -68,7 +68,7 @@ public class CommentsScreen: ScreenObject { public func verifyCommentsListEmpty() -> CommentsScreen { XCTAssertTrue(emptyImage.waitForExistence(timeout: 3)) XCTAssertTrue(app.staticTexts["Be the first to leave a comment."].isHittable) - XCTAssertTrue(app.cells.containing(.button, identifier: "reply-comment-button").count == 0) + XCTAssertTrue(app.cells.containing(.button, identifier: "reply-comment-button").isEmpty) return self } diff --git a/Modules/Sources/WordPressIntelligence/Utilities/ContentExtractor.swift b/Modules/Sources/WordPressIntelligence/Utilities/ContentExtractor.swift index e6c0c1bf522b..f7fb69436ce8 100644 --- a/Modules/Sources/WordPressIntelligence/Utilities/ContentExtractor.swift +++ b/Modules/Sources/WordPressIntelligence/Utilities/ContentExtractor.swift @@ -26,7 +26,7 @@ public enum ContentExtractor { public static func extractRelevantText(from content: String) throws -> String { let doc = try SwiftSoup.parse(content) - guard let body = doc.body(), body.children().count > 0 else { + guard let body = doc.body(), !body.children().isEmpty else { return content // Return as is } diff --git a/Modules/Sources/WordPressKit/JetpackScanThreat.swift b/Modules/Sources/WordPressKit/JetpackScanThreat.swift index d5242b0cb127..fdf5076154d8 100644 --- a/Modules/Sources/WordPressKit/JetpackScanThreat.swift +++ b/Modules/Sources/WordPressKit/JetpackScanThreat.swift @@ -237,7 +237,7 @@ public struct JetpackThreatContext { } } - return (highlights.count > 0) ? highlights : nil + return (!highlights.isEmpty) ? highlights : nil } /// Generates an NSRange from an array diff --git a/Modules/Sources/WordPressKit/JetpackThreatFixStatus.swift b/Modules/Sources/WordPressKit/JetpackThreatFixStatus.swift index e3d3877283d9..f12126dd6f82 100644 --- a/Modules/Sources/WordPressKit/JetpackThreatFixStatus.swift +++ b/Modules/Sources/WordPressKit/JetpackThreatFixStatus.swift @@ -23,13 +23,13 @@ public struct JetpackThreatFixResponse: Decodable { statusArray.append(fixStatus) } - isFixingThreats = statusArray.filter { $0.status == .inProgress }.count > 0 + isFixingThreats = !statusArray.filter { $0.status == .inProgress }.isEmpty threats = statusArray } /// Returns true the fixing status is complete, and all threats are no longer in progress public var finished: Bool { - return inProgress.count <= 0 + return inProgress.isEmpty } /// Returns all the fixed threats diff --git a/Modules/Sources/WordPressKit/SiteDesignServiceRemote.swift b/Modules/Sources/WordPressKit/SiteDesignServiceRemote.swift index 2a0f31b71a9e..74ed24b76e06 100644 --- a/Modules/Sources/WordPressKit/SiteDesignServiceRemote.swift +++ b/Modules/Sources/WordPressKit/SiteDesignServiceRemote.swift @@ -16,7 +16,7 @@ public struct SiteDesignRequest { "preview_height": "\(thumbnailSize.height)" as AnyObject, "scale": UIScreen.main.nativeScale as AnyObject ] - if 0 < groups.count { + if !groups.isEmpty { let groups = groups.map { $0.rawValue } parameters["group"] = groups.joined(separator: ",") as AnyObject } diff --git a/Modules/Sources/WordPressKit/WordPressComRestApi.swift b/Modules/Sources/WordPressKit/WordPressComRestApi.swift index b9e5a891a7cd..d2683e54727f 100644 --- a/Modules/Sources/WordPressKit/WordPressComRestApi.swift +++ b/Modules/Sources/WordPressKit/WordPressComRestApi.swift @@ -521,7 +521,7 @@ extension WordPressComRestApi { } var errorDictionary: AnyObject? = responseDictionary as AnyObject? - if let errorArray = responseDictionary["errors"] as? [AnyObject], errorArray.count > 0 { + if let errorArray = responseDictionary["errors"] as? [AnyObject], !errorArray.isEmpty { errorDictionary = errorArray.first } guard let errorEntry = errorDictionary as? [String: AnyObject], diff --git a/Modules/Sources/WordPressKit/WordPressOrgXMLRPCValidator.swift b/Modules/Sources/WordPressKit/WordPressOrgXMLRPCValidator.swift index 84e9b65dd5e6..51d82b5701aa 100644 --- a/Modules/Sources/WordPressKit/WordPressOrgXMLRPCValidator.swift +++ b/Modules/Sources/WordPressKit/WordPressOrgXMLRPCValidator.swift @@ -318,7 +318,7 @@ open class WordPressOrgXMLRPCValidator: NSObject { let matches = rsdURLRegExp.matches(in: html, options: NSRegularExpression.MatchingOptions(), range: NSRange(location: 0, length: html.count)) - if matches.count <= 0 { + if matches.isEmpty { return nil } diff --git a/Modules/Sources/WordPressShared/Utility/RichContentFormatter.swift b/Modules/Sources/WordPressShared/Utility/RichContentFormatter.swift index f23cf53b4ca1..4ba21d550ab7 100644 --- a/Modules/Sources/WordPressShared/Utility/RichContentFormatter.swift +++ b/Modules/Sources/WordPressShared/Utility/RichContentFormatter.swift @@ -47,7 +47,7 @@ import WordPressSharedObjC /// - Returns: The formatted string. /// @objc public class func formatContentString(_ string: String, isPrivateSite isPrivate: Bool) -> String { - guard string.count > 0 else { + guard !string.isEmpty else { return string } @@ -70,7 +70,7 @@ import WordPressSharedObjC /// - Returns: The formatted string. /// @objc public class func removeForbiddenTags(_ string: String) -> String { - guard string.count > 0 else { + guard !string.isEmpty else { return string } var content = string @@ -101,7 +101,7 @@ import WordPressSharedObjC /// - Returns: The formatted string. /// @objc public class func normalizeParagraphs(_ string: String) -> String { - guard string.count > 0 else { + guard !string.isEmpty else { return string } var content = string @@ -142,7 +142,7 @@ import WordPressSharedObjC // We don't want to remove new lines from preformatted tag blocks, // so get the ranges of such blocks. let matches = RegEx.preTags.matches(in: content, options: .reportCompletion, range: NSRange(location: 0, length: content.count)) - if matches.count == 0 { + if matches.isEmpty { // No blocks found, so we'll parse the whole string. ranges.append(NSRange(location: 0, length: content.count)) @@ -184,7 +184,7 @@ import WordPressSharedObjC /// - Returns: The formatted string. /// @objc public class func removeInlineStyles(_ string: String) -> String { - guard string.count > 0 else { + guard !string.isEmpty else { return string } var content = string @@ -206,7 +206,7 @@ import WordPressSharedObjC /// - Returns: The formatted string. /// @objc public class func resizeGalleryImageURL(_ string: String, isPrivateSite isPrivate: Bool) -> String { - guard string.count > 0 else { + guard !string.isEmpty else { return string } @@ -282,7 +282,7 @@ import WordPressSharedObjC /// - Returns: The formatted string. /// @objc public class func removeTrailingBreakTags(_ string: String) -> String { - guard string.count > 0 else { + guard !string.isEmpty else { return string } diff --git a/Modules/Tests/JetpackStatsTests/MockStatsServiceTests.swift b/Modules/Tests/JetpackStatsTests/MockStatsServiceTests.swift index 4fa319eba2c5..6e0947961c2a 100644 --- a/Modules/Tests/JetpackStatsTests/MockStatsServiceTests.swift +++ b/Modules/Tests/JetpackStatsTests/MockStatsServiceTests.swift @@ -25,7 +25,7 @@ struct MockStatsServiceTests { print("elapsed: \((CFAbsoluteTimeGetCurrent() - startTime) * 1000) ms") // THEN - #expect(response.items.count > 0) + #expect(!response.items.isEmpty) #expect(response.items.count <= 40, "Should return maximum 40 items") // THEN all items are posts @@ -56,6 +56,6 @@ struct MockStatsServiceTests { print("elapsed: \((CFAbsoluteTimeGetCurrent() - startTime) * 1000) ms") // THEN - Basic validations - #expect(response.metrics.count > 0, "Should return at least one data point") + #expect(!response.metrics.isEmpty, "Should return at least one data point") } } diff --git a/Modules/Tests/JetpackStatsTests/WeeklyTrendsViewModelTests.swift b/Modules/Tests/JetpackStatsTests/WeeklyTrendsViewModelTests.swift index 0b560159e68e..1f885a152878 100644 --- a/Modules/Tests/JetpackStatsTests/WeeklyTrendsViewModelTests.swift +++ b/Modules/Tests/JetpackStatsTests/WeeklyTrendsViewModelTests.swift @@ -47,7 +47,7 @@ struct WeeklyTrendsViewModelTests { ) // Then - #expect(viewModel.weeks.count == 0) + #expect(viewModel.weeks.isEmpty) #expect(viewModel.maxValue == 1) } @@ -376,6 +376,6 @@ struct WeeklyTrendsViewModelTests { ) // Then - #expect(viewModel.weeks.count == 0) + #expect(viewModel.weeks.isEmpty) } } diff --git a/Modules/Tests/WordPressSharedTests/LanguagesTests.swift b/Modules/Tests/WordPressSharedTests/LanguagesTests.swift index 2af2c91101a4..066086ff2ac0 100644 --- a/Modules/Tests/WordPressSharedTests/LanguagesTests.swift +++ b/Modules/Tests/WordPressSharedTests/LanguagesTests.swift @@ -12,8 +12,8 @@ class LanguagesTests { @Test func testLanguagesEffectivelyLoadJsonFile() { let languages = WordPressComLanguageDatabase.shared - XCTAssert(languages.all.count != 0) - XCTAssert(languages.popular.count != 0) + XCTAssert(!languages.all.isEmpty) + XCTAssert(!languages.popular.isEmpty) } @Test func testAllLanguagesHaveValidFields() { @@ -21,8 +21,8 @@ class LanguagesTests { let sum = languages.all + languages.popular for language in sum { - XCTAssert(language.slug.count > 0) - XCTAssert(language.name.count > 0) + XCTAssert(!language.slug.isEmpty) + XCTAssert(!language.name.isEmpty) } } diff --git a/Sources/WordPressAuthenticator/Extensions/FancyAlertViewController+LoginError.swift b/Sources/WordPressAuthenticator/Extensions/FancyAlertViewController+LoginError.swift index 5cd46bd7fdae..2189cf311564 100644 --- a/Sources/WordPressAuthenticator/Extensions/FancyAlertViewController+LoginError.swift +++ b/Sources/WordPressAuthenticator/Extensions/FancyAlertViewController+LoginError.swift @@ -57,7 +57,7 @@ extension FancyAlertViewController { message = NSLocalizedString("Incorrect username or password. Please try entering your login details again.", comment: "An error message shown when a user signed in with incorrect credentials.") } - if message.trim().count == 0 { + if message.trim().isEmpty { message = NSLocalizedString("Log in failed. Please try again.", comment: "A generic error message for a failed log in.") } diff --git a/Sources/WordPressAuthenticator/Features/SignIn/LoginViewController.swift b/Sources/WordPressAuthenticator/Features/SignIn/LoginViewController.swift index 56128b793216..6f5b0965e944 100644 --- a/Sources/WordPressAuthenticator/Features/SignIn/LoginViewController.swift +++ b/Sources/WordPressAuthenticator/Features/SignIn/LoginViewController.swift @@ -101,7 +101,7 @@ open class LoginViewController: NUXViewController, LoginFacadeDelegate { /// You will want to set this to `true` if the error was caused after pressing a button /// (e.g. Next button). func displayError(message: String, moveVoiceOverFocus: Bool = false) { - guard message.count > 0 else { + guard !message.isEmpty else { errorLabel?.isHidden = true return } diff --git a/Sources/WordPressAuthenticator/Helpers/UnifiedAuth/ViewRelated/2FA/TwoFAViewController.swift b/Sources/WordPressAuthenticator/Helpers/UnifiedAuth/ViewRelated/2FA/TwoFAViewController.swift index d28708fa6a7d..9216bb8d0690 100644 --- a/Sources/WordPressAuthenticator/Helpers/UnifiedAuth/ViewRelated/2FA/TwoFAViewController.swift +++ b/Sources/WordPressAuthenticator/Helpers/UnifiedAuth/ViewRelated/2FA/TwoFAViewController.swift @@ -316,7 +316,7 @@ extension TwoFAViewController: ASAuthorizationControllerDelegate, ASAuthorizatio // Some password managers(like 1P) don't deliver `rawClientDataJSON`. In those cases we need to assemble it manually. func extractClientData(from credential: ASAuthorizationPlatformPublicKeyCredentialAssertion, challengeInfo: WebauthnChallengeInfo) -> Data? { - if credential.rawClientDataJSON.count > 0 { + if !credential.rawClientDataJSON.isEmpty { return credential.rawClientDataJSON } diff --git a/Sources/WordPressAuthenticator/Views/SearchTableViewCell.swift b/Sources/WordPressAuthenticator/Views/SearchTableViewCell.swift index d04da78748df..28f080b6298d 100644 --- a/Sources/WordPressAuthenticator/Views/SearchTableViewCell.swift +++ b/Sources/WordPressAuthenticator/Views/SearchTableViewCell.swift @@ -98,7 +98,7 @@ extension SearchTableViewCell: UITextFieldDelegate { sanitizedString = string.trimmingCharacters(in: .whitespacesAndNewlines) } - let hasValidEdits = sanitizedString.count > 0 || range.length > 0 + let hasValidEdits = !sanitizedString.isEmpty || range.length > 0 if hasValidEdits { guard let start = textField.position(from: textField.beginningOfDocument, offset: range.location), @@ -129,7 +129,7 @@ extension SearchTableViewCell: UITextFieldDelegate { return } - if text.count == 0 { + if text.isEmpty { delegate.startSearch(for: "") } else { delegate.startSearch(for: text) diff --git a/Sources/WordPressData/Swift/Blog+Lookup.swift b/Sources/WordPressData/Swift/Blog+Lookup.swift index c2c99fd27410..4d52a614dfe2 100644 --- a/Sources/WordPressData/Swift/Blog+Lookup.swift +++ b/Sources/WordPressData/Swift/Blog+Lookup.swift @@ -113,9 +113,9 @@ public extension Blog { return true } - return Blog.selfHosted(in: context) + return !Blog.selfHosted(in: context) .filter { $0.jetpack?.isConnected == true } - .count > 0 + .isEmpty } @objc(selfHostedInContext:) diff --git a/Sources/WordPressData/Swift/Post.swift b/Sources/WordPressData/Swift/Post.swift index 46a0621b1e5b..fdbdbfca6789 100644 --- a/Sources/WordPressData/Swift/Post.swift +++ b/Sources/WordPressData/Swift/Post.swift @@ -83,7 +83,7 @@ public class Post: AbstractPost { let matchingCategories = blogCategories.filter({ return $0.categoryName == categoryName }) - if matchingCategories.count > 0 { + if !matchingCategories.isEmpty { newCategories = newCategories.union(matchingCategories) } } @@ -215,7 +215,7 @@ public class Post: AbstractPost { // MARK: - BasePost override public func contentPreviewForDisplay() -> String { - if let excerpt = mt_excerpt, excerpt.count > 0 { + if let excerpt = mt_excerpt, !excerpt.isEmpty { if let preview = PostPreviewCache.shared.excerpt[excerpt] { return preview } @@ -240,7 +240,7 @@ public class Post: AbstractPost { .stringByDecodingXMLCharacters() .strippingHTML() - if title.count == 0 && !hasRemote() && contentPreviewForDisplay().count == 0 { + if title.isEmpty && !hasRemote() && contentPreviewForDisplay().isEmpty { title = NSLocalizedString("(no title)", comment: "Lets a user know that a local draft does not have a title.") } diff --git a/Sources/WordPressData/Swift/ReaderCard+CoreDataClass.swift b/Sources/WordPressData/Swift/ReaderCard+CoreDataClass.swift index 9ea1a8f5d647..b023ff82dae3 100644 --- a/Sources/WordPressData/Swift/ReaderCard+CoreDataClass.swift +++ b/Sources/WordPressData/Swift/ReaderCard+CoreDataClass.swift @@ -16,11 +16,11 @@ public class ReaderCard: NSManagedObject { return .post } - if topicsArray.count > 0 { + if !topicsArray.isEmpty { return .topics } - if sitesArray.count > 0 { + if !sitesArray.isEmpty { return .sites } diff --git a/Sources/WordPressData/Swift/WordPressOrgRestApi+WordPress.swift b/Sources/WordPressData/Swift/WordPressOrgRestApi+WordPress.swift index 726a8334c13c..8d685e197d71 100644 --- a/Sources/WordPressData/Swift/WordPressOrgRestApi+WordPress.swift +++ b/Sources/WordPressData/Swift/WordPressOrgRestApi+WordPress.swift @@ -32,7 +32,7 @@ extension WordPressOrgRestApi { ) { if let dotComID = blog.dotComID?.uint64Value, let token = blog.account?.authToken, - token.count > 0 { + !token.isEmpty { self.init( dotComSiteID: dotComID, bearerToken: token, diff --git a/Tests/KeystoneTests/Tests/Features/Media/StockPhotos/MockStockPhotosService.swift b/Tests/KeystoneTests/Tests/Features/Media/StockPhotos/MockStockPhotosService.swift index cfdaba58012e..93b5e68510dc 100644 --- a/Tests/KeystoneTests/Tests/Features/Media/StockPhotos/MockStockPhotosService.swift +++ b/Tests/KeystoneTests/Tests/Features/Media/StockPhotos/MockStockPhotosService.swift @@ -10,7 +10,7 @@ final class MockStockPhotosService: StockPhotosService { func search(params: StockPhotosSearchParams, completion: @escaping (StockPhotosResultsPage) -> Void) { let text = params.text - guard text.count > 0 else { + guard !text.isEmpty else { completion(StockPhotosResultsPage.empty()) return } diff --git a/Tests/KeystoneTests/Tests/Features/Media/Tenor/MockTenorService.swift b/Tests/KeystoneTests/Tests/Features/Media/Tenor/MockTenorService.swift index f0f690eee523..68d8508f7e9c 100644 --- a/Tests/KeystoneTests/Tests/Features/Media/Tenor/MockTenorService.swift +++ b/Tests/KeystoneTests/Tests/Features/Media/Tenor/MockTenorService.swift @@ -10,7 +10,7 @@ final class MockTenorService: TenorService { override func search(params: TenorSearchParams, completion: @escaping (TenorResultsPage) -> Void) { let text = params.text - guard text.count > 0 else { + guard !text.isEmpty else { completion(TenorResultsPage.empty()) return } diff --git a/Tests/KeystoneTests/Tests/Services/DomainsServiceTests.swift b/Tests/KeystoneTests/Tests/Services/DomainsServiceTests.swift index d8c13af5c9d5..a447db6e1e7a 100644 --- a/Tests/KeystoneTests/Tests/Services/DomainsServiceTests.swift +++ b/Tests/KeystoneTests/Tests/Services/DomainsServiceTests.swift @@ -76,7 +76,7 @@ class DomainsServiceTests: CoreDataTestCase { func testDomainServiceHandlesTwoNewDomains() { let domains = findAllDomains() - XCTAssert(domains.count == 0, "Expecting no domains initially") + XCTAssert(domains.isEmpty, "Expecting no domains initially") stubDomainsResponseWithFile("domain-service-valid-domains.json") fetchDomains() diff --git a/Tests/KeystoneTests/Tests/Utility/PagesListTests.swift b/Tests/KeystoneTests/Tests/Utility/PagesListTests.swift index 5301a31991a5..b59d0fed13eb 100644 --- a/Tests/KeystoneTests/Tests/Utility/PagesListTests.swift +++ b/Tests/KeystoneTests/Tests/Utility/PagesListTests.swift @@ -212,10 +212,10 @@ class PagesListTests: CoreDataTestCase { NSLog("Array.sort took \(String(format: "%.3f", (CFAbsoluteTimeGetCurrent() - start) * 1000)) millisecond to process \(pages.count) pages") let orderDiff = originalIDs.difference(from: newIDs).inferringMoves() - XCTAssertTrue(orderDiff.count == 0, "Unexpected order difference: \(orderDiff)", file: file, line: line) + XCTAssertTrue(orderDiff.isEmpty, "Unexpected order difference: \(orderDiff)", file: file, line: line) let levelDiff = originalLevels.difference(from: newLevels).inferringMoves() - XCTAssertTrue(levelDiff.count == 0, "Unexpected level difference: \(levelDiff)", file: file, line: line) + XCTAssertTrue(levelDiff.isEmpty, "Unexpected level difference: \(levelDiff)", file: file, line: line) } } diff --git a/Tests/KeystoneTests/Tests/Utility/RouteMatcherTests.swift b/Tests/KeystoneTests/Tests/Utility/RouteMatcherTests.swift index 014aa7bfcd12..8c16f2427ad6 100644 --- a/Tests/KeystoneTests/Tests/Utility/RouteMatcherTests.swift +++ b/Tests/KeystoneTests/Tests/Utility/RouteMatcherTests.swift @@ -24,7 +24,7 @@ class RouteMatcherTests: XCTestCase { matcher = RouteMatcher(routes: routes) let matches = matcher.routesMatching(URL(string: "/hello")!) - XCTAssert(matches.count == 0) + XCTAssert(matches.isEmpty) } func testMatchingRouteWithSingleComponent() { @@ -89,7 +89,7 @@ class RouteMatcherTests: XCTestCase { matcher = RouteMatcher(routes: routes) let matches = matcher.routesMatching(URL(string: "/me/bobsmith")!) - XCTAssert(matches.count == 0) + XCTAssert(matches.isEmpty) } func testMatchedRouteWithManyPlaceholders() { diff --git a/Tests/WordPressDataTests/CoreDataHelperTests.swift b/Tests/WordPressDataTests/CoreDataHelperTests.swift index 0495943f5e2c..1d1214b8581e 100644 --- a/Tests/WordPressDataTests/CoreDataHelperTests.swift +++ b/Tests/WordPressDataTests/CoreDataHelperTests.swift @@ -80,7 +80,7 @@ import CoreData context.deleteAllObjects(ofType: DummyEntity.self) #expect(context.countObjects(ofType: DummyEntity.self) == 0) - #expect(context.allObjects(ofType: DummyEntity.self).count == 0) + #expect(context.allObjects(ofType: DummyEntity.self).isEmpty) } @Test func firstObjectMatchingPredicateReturnsTheExpectedObject() { diff --git a/Tests/WordPressDataTests/PostMetadataContainerTests.swift b/Tests/WordPressDataTests/PostMetadataContainerTests.swift index 3c38b856505a..def4e276861e 100644 --- a/Tests/WordPressDataTests/PostMetadataContainerTests.swift +++ b/Tests/WordPressDataTests/PostMetadataContainerTests.swift @@ -36,7 +36,7 @@ struct PostMetadataContainerTests { let metadata = PostMetadataContainer() #expect(metadata.values.isEmpty) - #expect(metadata.values.count == 0) + #expect(metadata.values.isEmpty) } // MARK: - CRUD @@ -117,7 +117,7 @@ struct PostMetadataContainerTests { metadata.clear() #expect(metadata.values.isEmpty) - #expect(metadata.values.count == 0) + #expect(metadata.values.isEmpty) } // MARK: - Encoding Tests diff --git a/Tests/WordPressKitTests/WordPressKitTests/Tests/ActivityServiceRemoteTests.swift b/Tests/WordPressKitTests/WordPressKitTests/Tests/ActivityServiceRemoteTests.swift index 7661bc5f42ba..5bf4fc1db966 100644 --- a/Tests/WordPressKitTests/WordPressKitTests/Tests/ActivityServiceRemoteTests.swift +++ b/Tests/WordPressKitTests/WordPressKitTests/Tests/ActivityServiceRemoteTests.swift @@ -376,7 +376,7 @@ class ActivityServiceRemoteTests: RemoteTestCase, RESTTestable { XCTAssertEqual(rewindStatus.restore!.status, .fail) XCTAssertEqual(rewindStatus.restore!.progress, 0) XCTAssertNotNil(rewindStatus.restore!.failureReason) - XCTAssert(rewindStatus.restore!.failureReason!.count > 0) + XCTAssert(!rewindStatus.restore!.failureReason!.isEmpty) expect.fulfill() }, failure: { _ in expect.fulfill() diff --git a/Tests/WordPressKitTests/WordPressKitTests/Tests/DomainsServiceRemoteRESTTests.swift b/Tests/WordPressKitTests/WordPressKitTests/Tests/DomainsServiceRemoteRESTTests.swift index 4cbb75ef8cde..4b5a84fb478b 100644 --- a/Tests/WordPressKitTests/WordPressKitTests/Tests/DomainsServiceRemoteRESTTests.swift +++ b/Tests/WordPressKitTests/WordPressKitTests/Tests/DomainsServiceRemoteRESTTests.swift @@ -160,7 +160,7 @@ class DomainsServiceRemoteRESTTests: RemoteTestCase, RESTTestable { remote.getStates(for: countryCode, success: { (stateList) in - XCTAssert(stateList.count == 0) + XCTAssert(stateList.isEmpty) expect.fulfill() }) { (_) in XCTFail("This callback shouldn't get called") diff --git a/Tests/WordPressKitTests/WordPressKitTests/Tests/PeopleServiceRemoteTests.swift b/Tests/WordPressKitTests/WordPressKitTests/Tests/PeopleServiceRemoteTests.swift index b0f09cfc8b2f..3bf312869c24 100644 --- a/Tests/WordPressKitTests/WordPressKitTests/Tests/PeopleServiceRemoteTests.swift +++ b/Tests/WordPressKitTests/WordPressKitTests/Tests/PeopleServiceRemoteTests.swift @@ -286,7 +286,7 @@ class PeopleServiceRemoteTests: RemoteTestCase, RESTTestable { // When remote.getEmailFollowers(siteID, page: 1, max: 1, success: { followers, hasMore in // Then - XCTAssertTrue(followers.count > 0) + XCTAssertTrue(!followers.isEmpty) XCTAssertFalse(hasMore) expect.fulfill() }, failure: { _ in @@ -305,7 +305,7 @@ class PeopleServiceRemoteTests: RemoteTestCase, RESTTestable { // When remote.getEmailFollowers(siteID, page: 1, max: 1, success: { followers, hasMore in // Then - XCTAssertTrue(followers.count > 0) + XCTAssertTrue(!followers.isEmpty) XCTAssertTrue(hasMore) expect.fulfill() }, failure: { _ in diff --git a/WordPress/Classes/Extensions/WKWebView+UserAgent.swift b/WordPress/Classes/Extensions/WKWebView+UserAgent.swift index bad71b2780a0..8705adc84743 100644 --- a/WordPress/Classes/Extensions/WKWebView+UserAgent.swift +++ b/WordPress/Classes/Extensions/WKWebView+UserAgent.swift @@ -13,7 +13,7 @@ extension WKWebView { @objc func userAgent() -> String { guard let userAgent = value(forKey: WKWebView.userAgentKey) as? String, - userAgent.count > 0 else { + !userAgent.isEmpty else { WordPressAppDelegate.crashLogging?.logMessage( "This method for retrieveing the user agent seems to be no longer working. We need to figure out an alternative.", properties: [:], diff --git a/WordPress/Classes/Jetpack/JetpackMigration/Common/Navigation/MigrationFlowCoordinator.swift b/WordPress/Classes/Jetpack/JetpackMigration/Common/Navigation/MigrationFlowCoordinator.swift index 5e834bc6757e..42c0c4e4d384 100644 --- a/WordPress/Classes/Jetpack/JetpackMigration/Common/Navigation/MigrationFlowCoordinator.swift +++ b/WordPress/Classes/Jetpack/JetpackMigration/Common/Navigation/MigrationFlowCoordinator.swift @@ -28,7 +28,7 @@ final class MigrationFlowCoordinator: ObservableObject { // Skip the migration if the user just created an account and haven't // created any site yet. - if (try? BlogQuery().blogs(in: ContextManager.shared.mainContext))?.count == 0 { + if (try? BlogQuery().blogs(in: ContextManager.shared.mainContext))?.isEmpty == true { self.currentStep = MigrationStep.done self.userPersistentRepository.jetpackContentMigrationState = .completed } diff --git a/WordPress/Classes/Jetpack/JetpackMigration/Done/MigrationDoneViewController.swift b/WordPress/Classes/Jetpack/JetpackMigration/Done/MigrationDoneViewController.swift index bd091ce840d5..2241040b6a3f 100644 --- a/WordPress/Classes/Jetpack/JetpackMigration/Done/MigrationDoneViewController.swift +++ b/WordPress/Classes/Jetpack/JetpackMigration/Done/MigrationDoneViewController.swift @@ -38,7 +38,7 @@ class MigrationDoneViewController: UIViewController { super.viewDidAppear(animated) var properties: [String: String] = [:] - if (try? BlogQuery().blogs(in: ContextManager.shared.mainContext))?.count == 0 { + if (try? BlogQuery().blogs(in: ContextManager.shared.mainContext))?.isEmpty == true { properties["no_sites"] = "true" } tracker.track(.thanksScreenShown, properties: properties) diff --git a/WordPress/Classes/Stores/PluginStore.swift b/WordPress/Classes/Stores/PluginStore.swift index 14d9246e5146..fed439310b37 100644 --- a/WordPress/Classes/Stores/PluginStore.swift +++ b/WordPress/Classes/Stores/PluginStore.swift @@ -392,7 +392,7 @@ extension PluginStore { func shouldFetchDirectory(feed: PluginDirectoryFeedType) -> Bool { let isFetching = state.fetchingDirectoryFeed[feed.slug, default: false] - if case .search(let term) = feed, term.count > 0 { + if case .search(let term) = feed, !term.isEmpty { return !isFetching } diff --git a/WordPress/Classes/System/WordPressAppDelegate+openURL.swift b/WordPress/Classes/System/WordPressAppDelegate+openURL.swift index 2130d7b47905..60bf0fdd8121 100644 --- a/WordPress/Classes/System/WordPressAppDelegate+openURL.swift +++ b/WordPress/Classes/System/WordPressAppDelegate+openURL.swift @@ -231,7 +231,7 @@ private extension URL { var queryItems: [URLQueryItem]? { guard let components = URLComponents(url: self, resolvingAgainstBaseURL: false), let queryItems = components.queryItems, - queryItems.count > 0 else { + !queryItems.isEmpty else { return nil } return queryItems diff --git a/WordPress/Classes/Utility/BackgroundTasks/WeeklyRoundupBackgroundTask.swift b/WordPress/Classes/Utility/BackgroundTasks/WeeklyRoundupBackgroundTask.swift index e89151a23685..469a12aad7de 100644 --- a/WordPress/Classes/Utility/BackgroundTasks/WeeklyRoundupBackgroundTask.swift +++ b/WordPress/Classes/Utility/BackgroundTasks/WeeklyRoundupBackgroundTask.swift @@ -52,7 +52,7 @@ private class WeeklyRoundupDataProvider { self.getSites { [weak self] sitesResult in switch sitesResult { case .success(let sites): - guard let self, sites.count > 0 else { + guard let self, !sites.isEmpty else { completion(.success(nil)) return } @@ -179,7 +179,7 @@ private class WeeklyRoundupDataProvider { site.isAdmin && !site.isAutomatticP2 } - guard administeredSites.count > 0 else { + guard !administeredSites.isEmpty else { result(.success([])) return } @@ -729,7 +729,7 @@ class WeeklyRoundupNotificationScheduler { userNotificationCenter.getPendingNotificationRequests { requests in let notifications = requests.filter({ $0.content.threadIdentifier == Self.threadIdentifier }) - guard notifications.count > 0 else { + guard !notifications.isEmpty else { return } diff --git a/WordPress/Classes/Utility/Blogging Reminders/BloggingRemindersScheduleFormatter.swift b/WordPress/Classes/Utility/Blogging Reminders/BloggingRemindersScheduleFormatter.swift index 5de223f97fcd..8630ea45bfc0 100644 --- a/WordPress/Classes/Utility/Blogging Reminders/BloggingRemindersScheduleFormatter.swift +++ b/WordPress/Classes/Utility/Blogging Reminders/BloggingRemindersScheduleFormatter.swift @@ -18,7 +18,7 @@ struct BloggingRemindersScheduleFormatter { case .none: return Self.stringToAttributedString(TextContent.shortNoRemindersDescription) case .weekdays(let days): - guard days.count > 0 else { + guard !days.isEmpty else { return shortScheduleDescription(for: .none, time: time) } @@ -33,7 +33,7 @@ struct BloggingRemindersScheduleFormatter { case .none: return NSAttributedString(string: TextContent.longNoRemindersDescription) case .weekdays(let days): - guard days.count > 0 else { + guard !days.isEmpty else { return longScheduleDescription(for: .none, time: time) } diff --git a/WordPress/Classes/Utility/Blogging Reminders/BloggingRemindersScheduler.swift b/WordPress/Classes/Utility/Blogging Reminders/BloggingRemindersScheduler.swift index a3f711672adb..f5c798df9503 100644 --- a/WordPress/Classes/Utility/Blogging Reminders/BloggingRemindersScheduler.swift +++ b/WordPress/Classes/Utility/Blogging Reminders/BloggingRemindersScheduler.swift @@ -188,7 +188,7 @@ class BloggingRemindersScheduler { configuration[url] = schedule } - if configuration.count > 0 { + if !configuration.isEmpty { try? PropertyListEncoder().encode(configuration).write(to: sharedFileUrl) } } @@ -204,7 +204,7 @@ class BloggingRemindersScheduler { } // Only copy if the existing local store contains no schedules - if localStore.configuration.count == 0 { + if localStore.configuration.isEmpty { ContextManager.shared.performAndSave { context in for (blogUrl, schedule) in sharedConfig { guard let blog = try? BlogQuery().hostname(matching: blogUrl).blog(in: context) else { diff --git a/WordPress/Classes/Utility/ImmuTable/ImmuTable+Optional.swift b/WordPress/Classes/Utility/ImmuTable/ImmuTable+Optional.swift index 8b10c3e986e9..b946eaf24270 100644 --- a/WordPress/Classes/Utility/ImmuTable/ImmuTable+Optional.swift +++ b/WordPress/Classes/Utility/ImmuTable/ImmuTable+Optional.swift @@ -8,7 +8,7 @@ extension ImmuTableSection { /// init?(headerText: String? = nil, optionalRows: [ImmuTableRow?], footerText: String? = nil) { let rows = optionalRows.compactMap({ $0 }) - guard rows.count > 0 else { + guard !rows.isEmpty else { return nil } self.init(headerText: headerText, rows: rows, footerText: footerText) diff --git a/WordPress/Classes/Utility/Sharing/ShareExtensionSessionManager.swift b/WordPress/Classes/Utility/Sharing/ShareExtensionSessionManager.swift index 4c1d6380e1ab..dea13d3806a0 100644 --- a/WordPress/Classes/Utility/Sharing/ShareExtensionSessionManager.swift +++ b/WordPress/Classes/Utility/Sharing/ShareExtensionSessionManager.swift @@ -146,7 +146,7 @@ import WordPressKit /// - uploadOpObjectIDs: Array of object IDs /// fileprivate func logError(_ errorString: String, uploadOpObjectIDs: [NSManagedObjectID]) { - guard uploadOpObjectIDs.count > 0 else { + guard !uploadOpObjectIDs.isEmpty else { return } DDLogError("\(errorString)") diff --git a/WordPress/Classes/Utility/Universal Links/Migration/WPAdminConvertibleRouter.swift b/WordPress/Classes/Utility/Universal Links/Migration/WPAdminConvertibleRouter.swift index b5fd72066b79..cb8f8e6d609f 100644 --- a/WordPress/Classes/Utility/Universal Links/Migration/WPAdminConvertibleRouter.swift +++ b/WordPress/Classes/Utility/Universal Links/Migration/WPAdminConvertibleRouter.swift @@ -21,7 +21,7 @@ struct WPAdminConvertibleRouter: LinkRouter { } func canHandle(url: URL) -> Bool { - return matcher.routesMatching(url).count > 0 + return !matcher.routesMatching(url).isEmpty } func handle(url: URL, shouldTrack track: Bool = false, source: DeepLinkSource? = nil) { diff --git a/WordPress/Classes/Utility/Universal Links/UniversalLinkRouter.swift b/WordPress/Classes/Utility/Universal Links/UniversalLinkRouter.swift index 4232f476fb2e..589a4afa2404 100644 --- a/WordPress/Classes/Utility/Universal Links/UniversalLinkRouter.swift +++ b/WordPress/Classes/Utility/Universal Links/UniversalLinkRouter.swift @@ -114,7 +114,7 @@ struct UniversalLinkRouter: LinkRouter { /// but does not perform any actions or tracking. /// func canHandle(url: URL) -> Bool { - let matcherCanHandle = matcher.routesMatching(url).count > 0 + let matcherCanHandle = !matcher.routesMatching(url).isEmpty guard let host = url.host, let scheme = url.scheme else { return matcherCanHandle diff --git a/WordPress/Classes/Utility/Version.swift b/WordPress/Classes/Utility/Version.swift index e8a348b8f580..1bbbde4fd5e5 100644 --- a/WordPress/Classes/Utility/Version.swift +++ b/WordPress/Classes/Utility/Version.swift @@ -114,11 +114,11 @@ extension Version: Comparable { return lhsComparators.lexicographicallyPrecedes(rhsComparators) } - guard lhs.prereleaseIdentifiers.count > 0 else { + guard !lhs.prereleaseIdentifiers.isEmpty else { return false // Non-prerelease lhs >= potentially prerelease rhs } - guard rhs.prereleaseIdentifiers.count > 0 else { + guard !rhs.prereleaseIdentifiers.isEmpty else { return true // Prerelease lhs < non-prerelease rhs } diff --git a/WordPress/Classes/Utility/ZendeskUtils.swift b/WordPress/Classes/Utility/ZendeskUtils.swift index f58be834aac5..a25f233fc270 100644 --- a/WordPress/Classes/Utility/ZendeskUtils.swift +++ b/WordPress/Classes/Utility/ZendeskUtils.swift @@ -659,7 +659,7 @@ private extension ZendeskUtils { ZendeskUtils.sharedInstance.userEmail = wpAccount.email ZendeskUtils.sharedInstance.userName = wpAccount.username - if accountSettings.firstName.count > 0 || accountSettings.lastName.count > 0 { + if !accountSettings.firstName.isEmpty || !accountSettings.lastName.isEmpty { ZendeskUtils.sharedInstance.userName = (accountSettings.firstName + " " + accountSettings.lastName).trim() } } @@ -765,7 +765,7 @@ private extension ZendeskUtils { static func getBlogInformation() -> String { let allBlogs = (try? BlogQuery().blogs(in: ContextManager.shared.mainContext)) ?? [] - guard allBlogs.count > 0 else { + guard !allBlogs.isEmpty else { return Constants.noValue } @@ -794,7 +794,7 @@ private extension ZendeskUtils { tags.append(Constants.platformTag) // If there are no sites, then the user has an empty WP account. - guard allBlogs.count > 0 else { + guard !allBlogs.isEmpty else { tags.append(Constants.wpComTag) return tags } @@ -880,7 +880,7 @@ private extension ZendeskUtils { // Submit Action let submitAction = alertController.addDefaultActionWithTitle(alertOptions.submit) { [weak alertController] (_) in - guard let email = alertController?.textFields?.first?.text, email.count > 0 else { + guard let email = alertController?.textFields?.first?.text, !email.isEmpty else { completion(false) return } diff --git a/WordPress/Classes/ViewRelated/Aztec/ViewControllers/AztecPostViewController.swift b/WordPress/Classes/ViewRelated/Aztec/ViewControllers/AztecPostViewController.swift index 592204d2c5d2..e2da01b2cb91 100644 --- a/WordPress/Classes/ViewRelated/Aztec/ViewControllers/AztecPostViewController.swift +++ b/WordPress/Classes/ViewRelated/Aztec/ViewControllers/AztecPostViewController.swift @@ -1161,7 +1161,7 @@ private extension AztecPostViewController { self.displayPreview() } - if (post.revisions ?? []).count > 0 { + if !(post.revisions ?? []).isEmpty { alert.addDefaultActionWithTitle(MoreSheetAlert.historyTitle) { [unowned self] _ in self.displayRevisionsList() } diff --git a/WordPress/Classes/ViewRelated/Blog/Blog Dashboard/Cards/DashboardJetpackSocialCardCell.swift b/WordPress/Classes/ViewRelated/Blog/Blog Dashboard/Cards/DashboardJetpackSocialCardCell.swift index afc5dd543505..310f5ba54aec 100644 --- a/WordPress/Classes/ViewRelated/Blog/Blog Dashboard/Cards/DashboardJetpackSocialCardCell.swift +++ b/WordPress/Classes/ViewRelated/Blog/Blog Dashboard/Cards/DashboardJetpackSocialCardCell.swift @@ -187,8 +187,8 @@ private extension DashboardJetpackSocialCardCell { let isNoConnectionViewHidden = hiddenSites[dotComID] ?? false return blog.supports(.publicize) - && services.count > 0 - && connections.count == 0 + && !services.isEmpty + && connections.isEmpty && !isNoConnectionViewHidden } @@ -278,7 +278,7 @@ private extension DashboardJetpackSocialCardCell { let isNoSharesViewHidden = hiddenSites[dotComID] ?? false return blog.supports(.publicize) - && connections.filter { !$0.requiresUserAction() }.count > 0 + && !connections.filter { !$0.requiresUserAction() }.isEmpty && !isNoSharesViewHidden && sharingLimit.remaining == 0 } diff --git a/WordPress/Classes/ViewRelated/Blog/Blog Details/BlogDetailsTableViewModel.swift b/WordPress/Classes/ViewRelated/Blog/Blog Details/BlogDetailsTableViewModel.swift index 748653efc582..420f442047e0 100644 --- a/WordPress/Classes/ViewRelated/Blog/Blog Details/BlogDetailsTableViewModel.swift +++ b/WordPress/Classes/ViewRelated/Blog/Blog Details/BlogDetailsTableViewModel.swift @@ -252,7 +252,7 @@ extension BlogDetailsTableViewModel: UITableViewDataSource { switch sections[section].category { case .jetpackInstallCard, .migrationSuccess, .jetpackBrandingCard, .extensiveLogging, .xmlrpcDisabled: // The "card" sections do not set the `rows` property. It's hard-coded to show specific types of cards. - wpAssert(sections[section].rows.count == 0) + wpAssert(sections[section].rows.isEmpty) return 1 default: return sections[section].rows.count diff --git a/WordPress/Classes/ViewRelated/Blog/BloggingReminders/BloggingRemindersFlowSettingsViewController.swift b/WordPress/Classes/ViewRelated/Blog/BloggingReminders/BloggingRemindersFlowSettingsViewController.swift index bd35496f3bfc..2ca8afdd3f4d 100644 --- a/WordPress/Classes/ViewRelated/Blog/BloggingReminders/BloggingRemindersFlowSettingsViewController.swift +++ b/WordPress/Classes/ViewRelated/Blog/BloggingReminders/BloggingRemindersFlowSettingsViewController.swift @@ -342,7 +342,7 @@ final class BloggingRemindersFlowSettingsViewController: UIViewController { private func scheduleReminders(showPushPrompt: Bool = true) { let schedule: BloggingRemindersScheduler.Schedule - if weekdays.count > 0 { + if !weekdays.isEmpty { schedule = .weekdays(weekdays) } else { schedule = .none @@ -509,7 +509,7 @@ private extension BloggingRemindersFlowSettingsViewController { /// Updates the label that contains the number of scheduled days as users change them func refreshFrequencyLabel() { - guard weekdays.count > 0 else { + guard !weekdays.isEmpty else { frequencyLabel.isHidden = true timeSelectionStackView.isHidden = true return diff --git a/WordPress/Classes/ViewRelated/Blog/Sharing/PublicizeServicesState.swift b/WordPress/Classes/ViewRelated/Blog/Sharing/PublicizeServicesState.swift index 8d3d4e9adada..888b4d027651 100644 --- a/WordPress/Classes/ViewRelated/Blog/Sharing/PublicizeServicesState.swift +++ b/WordPress/Classes/ViewRelated/Blog/Sharing/PublicizeServicesState.swift @@ -12,7 +12,7 @@ import WordPressData } func hasAddedNewConnectionTo(_ connections: [PublicizeConnection]) -> Bool { - guard connections.count > 0 else { + guard !connections.isEmpty else { return false } diff --git a/WordPress/Classes/ViewRelated/Blog/Sharing/SharingAccountViewController.swift b/WordPress/Classes/ViewRelated/Blog/Sharing/SharingAccountViewController.swift index c1f554b44241..387297d8c91e 100644 --- a/WordPress/Classes/ViewRelated/Blog/Sharing/SharingAccountViewController.swift +++ b/WordPress/Classes/ViewRelated/Blog/Sharing/SharingAccountViewController.swift @@ -88,7 +88,7 @@ import WordPressUI var connectedAccounts = [KeyringAccount]() var accounts = keyringAccountHelper.accountsFromKeyringConnections(keyringConnections, with: publicizeService) - if accounts.count == 0 { + if accounts.isEmpty { showNoResultsViewController() return ImmuTable(sections: []) } @@ -110,7 +110,7 @@ import WordPressUI // Build the section for connected accounts rows = rowsForConnectedKeyringAccounts(connectedAccounts) - if rows.count > 0 { + if !rows.isEmpty { let title = NSLocalizedString("Connected", comment: "Adjective. The title of a list of third-part sharing service account names.") let section = ImmuTableSection(headerText: title, rows: rows, footerText: nil) sections.append(section) @@ -126,7 +126,7 @@ import WordPressUI /// - Returns: An ImmuTableSection or `nil` if there were no rows. /// fileprivate func sectionForUnconnectedKeyringAccountRows(_ rows: [ImmuTableRow]) -> ImmuTableSection? { - if rows.count == 0 { + if rows.isEmpty { return nil } diff --git a/WordPress/Classes/ViewRelated/Blog/Sharing/SharingButtonsViewController.swift b/WordPress/Classes/ViewRelated/Blog/Sharing/SharingButtonsViewController.swift index 3dcc37482b83..246067ad18b7 100644 --- a/WordPress/Classes/ViewRelated/Blog/Sharing/SharingButtonsViewController.swift +++ b/WordPress/Classes/ViewRelated/Blog/Sharing/SharingButtonsViewController.swift @@ -295,7 +295,7 @@ class SharingButtonsViewController: UITableViewController { cell.textLabel?.text = self.twitterUsernameTitle var name = self.blog.settings!.sharingTwitterName - if name.count > 0 { + if !name.isEmpty { name = "@\(name)" } cell.detailTextLabel?.text = name diff --git a/WordPress/Classes/ViewRelated/Domains/Domain registration/RegisterDomainDetails/ViewController/RegisterDomainDetailsViewController.swift b/WordPress/Classes/ViewRelated/Domains/Domain registration/RegisterDomainDetails/ViewController/RegisterDomainDetailsViewController.swift index df50988e0106..9ce6b2ffa918 100644 --- a/WordPress/Classes/ViewRelated/Domains/Domain registration/RegisterDomainDetails/ViewController/RegisterDomainDetailsViewController.swift +++ b/WordPress/Classes/ViewRelated/Domains/Domain registration/RegisterDomainDetails/ViewController/RegisterDomainDetailsViewController.swift @@ -275,7 +275,7 @@ extension RegisterDomainDetailsViewController { } switch field { case .country: - if viewModel.countryNames.count > 0 { + if !viewModel.countryNames.isEmpty { showItemSelectionPage(onSelectionAt: indexPath, title: Localized.ContactInformation.country, items: viewModel.countryNames) @@ -289,7 +289,7 @@ extension RegisterDomainDetailsViewController { case .addNewAddressLine: viewModel.replaceAddNewAddressLine() case .state: - if viewModel.stateNames.count > 0 { + if !viewModel.stateNames.isEmpty { showItemSelectionPage(onSelectionAt: indexPath, title: Localized.Address.state, items: viewModel.stateNames) diff --git a/WordPress/Classes/ViewRelated/Domains/DomainSelectionViewController.swift b/WordPress/Classes/ViewRelated/Domains/DomainSelectionViewController.swift index 30409d697f9e..ca7f14443a52 100644 --- a/WordPress/Classes/ViewRelated/Domains/DomainSelectionViewController.swift +++ b/WordPress/Classes/ViewRelated/Domains/DomainSelectionViewController.swift @@ -243,7 +243,7 @@ final class DomainSelectionViewController: CollapsableHeaderViewController { override func estimatedContentSize() -> CGSize { guard !isShowingError else { return CGSize(width: view.frame.width, height: 44) } - guard data.count > 0 else { return .zero } + guard !data.isEmpty else { return .zero } let estimatedSectionHeaderHeight: CGFloat = 85 let cellCount = data.count let height = estimatedSectionHeaderHeight + (CGFloat(cellCount) * AddressTableViewCell.estimatedSize.height) @@ -662,7 +662,7 @@ extension DomainSelectionViewController: UITableViewDataSource { } func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { - guard data.count > 0 else { return nil } + guard !data.isEmpty else { return nil } return Strings.suggestions } diff --git a/WordPress/Classes/ViewRelated/Domains/View Models/SiteDomainsViewModel.swift b/WordPress/Classes/ViewRelated/Domains/View Models/SiteDomainsViewModel.swift index d47606b9a0f9..223e9cf8f622 100644 --- a/WordPress/Classes/ViewRelated/Domains/View Models/SiteDomainsViewModel.swift +++ b/WordPress/Classes/ViewRelated/Domains/View Models/SiteDomainsViewModel.swift @@ -97,7 +97,7 @@ final class SiteDomainsViewModel: ObservableObject { sections.append(section) } - if otherDomains.count > 0 { + if !otherDomains.isEmpty { let domainRows = otherDomains.map { SiteDomainsViewModel.Section.Row( viewModel: .init( @@ -120,7 +120,7 @@ final class SiteDomainsViewModel: ObservableObject { sections.append(section) } - if sections.count == 0 || blog.canRegisterDomainWithPaidPlan { + if sections.isEmpty || blog.canRegisterDomainWithPaidPlan { sections.append(Section(title: nil, footer: nil, content: .upgradePlan)) } else { sections.append(Section(title: nil, footer: nil, content: .addDomain)) diff --git a/WordPress/Classes/ViewRelated/Gutenberg/GutenbergMediaPickerHelper.swift b/WordPress/Classes/ViewRelated/Gutenberg/GutenbergMediaPickerHelper.swift index 5c3739d288b4..d3c917580c20 100644 --- a/WordPress/Classes/ViewRelated/Gutenberg/GutenbergMediaPickerHelper.swift +++ b/WordPress/Classes/ViewRelated/Gutenberg/GutenbergMediaPickerHelper.swift @@ -133,7 +133,7 @@ extension GutenbergMediaPickerHelper: PHPickerViewControllerDelegate { func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) { context.dismiss(animated: true) - guard results.count > 0 else { + guard !results.isEmpty else { return } diff --git a/WordPress/Classes/ViewRelated/Gutenberg/Layout Picker/FilterableCategoriesViewController.swift b/WordPress/Classes/ViewRelated/Gutenberg/Layout Picker/FilterableCategoriesViewController.swift index b5a23a25765f..980c64266939 100644 --- a/WordPress/Classes/ViewRelated/Gutenberg/Layout Picker/FilterableCategoriesViewController.swift +++ b/WordPress/Classes/ViewRelated/Gutenberg/Layout Picker/FilterableCategoriesViewController.swift @@ -110,7 +110,7 @@ class FilterableCategoriesViewController: CollapsableHeaderViewController { } private func calculateContentHeight() -> CGFloat { - guard !isLoading, visibleSections.count > 0 else { + guard !isLoading, !visibleSections.isEmpty else { return ghostThumbnailSize.height + CategorySectionTableViewCell.cellVerticalPadding } @@ -258,7 +258,7 @@ extension FilterableCategoriesViewController: CollapsableHeaderFilterBarDelegate func didDeselectFilter(withIndex index: IndexPath, withSelectedIndexes selectedIndexes: [IndexPath]) { trackFiltersChangedEvent(isSelectionEvent: false, changedIndex: index, selectedIndexes: selectedIndexes) - guard selectedIndexes.count == 0 else { + guard selectedIndexes.isEmpty else { removeFilterRow(withIndex: index) return } diff --git a/WordPress/Classes/ViewRelated/Gutenberg/Utils/GutenbergFilesAppMediaSource.swift b/WordPress/Classes/ViewRelated/Gutenberg/Utils/GutenbergFilesAppMediaSource.swift index 0e2e9bab6144..1a80f494219d 100644 --- a/WordPress/Classes/ViewRelated/Gutenberg/Utils/GutenbergFilesAppMediaSource.swift +++ b/WordPress/Classes/ViewRelated/Gutenberg/Utils/GutenbergFilesAppMediaSource.swift @@ -36,7 +36,7 @@ extension GutenbergFilesAppMediaSource: UIDocumentPickerDelegate { defer { mediaPickerCallback = nil } - if urls.count == 0 { + if urls.isEmpty { mediaPickerCallback?(nil) } else { insertOnBlock(with: urls) diff --git a/WordPress/Classes/ViewRelated/Jetpack/Jetpack Scan/JetpackScanCoordinator.swift b/WordPress/Classes/ViewRelated/Jetpack/Jetpack Scan/JetpackScanCoordinator.swift index 4a59f5caf692..0e3703bb1134 100644 --- a/WordPress/Classes/ViewRelated/Jetpack/Jetpack Scan/JetpackScanCoordinator.swift +++ b/WordPress/Classes/ViewRelated/Jetpack/Jetpack Scan/JetpackScanCoordinator.swift @@ -157,7 +157,7 @@ class JetpackScanCoordinator { private func fixThreats(threats: [JetpackScanThreat]) { // If there are no fixable threats just reload the state since it may be out of date - guard threats.count > 0 else { + guard !threats.isEmpty else { refreshData() return } diff --git a/WordPress/Classes/ViewRelated/Jetpack/Jetpack Scan/View Models/JetpackScanStatusViewModel.swift b/WordPress/Classes/ViewRelated/Jetpack/Jetpack Scan/View Models/JetpackScanStatusViewModel.swift index 773ef480b101..7bc9dcf9818e 100644 --- a/WordPress/Classes/ViewRelated/Jetpack/Jetpack Scan/View Models/JetpackScanStatusViewModel.swift +++ b/WordPress/Classes/ViewRelated/Jetpack/Jetpack Scan/View Models/JetpackScanStatusViewModel.swift @@ -183,7 +183,7 @@ struct JetpackScanStatusViewModel { switch scan.state { case .idle: - if let threats = scan.threats, threats.count > 0 { + if let threats = scan.threats, !threats.isEmpty { viewState = scan.hasFixableThreats ? .hasFixableThreats : .hasThreats } else { if scan.mostRecent?.didFail ?? false { diff --git a/WordPress/Classes/ViewRelated/Me/All Domains/View Models/AllDomainsListViewModel.swift b/WordPress/Classes/ViewRelated/Me/All Domains/View Models/AllDomainsListViewModel.swift index 3398aec7821e..bc6388de6dcf 100644 --- a/WordPress/Classes/ViewRelated/Me/All Domains/View Models/AllDomainsListViewModel.swift +++ b/WordPress/Classes/ViewRelated/Me/All Domains/View Models/AllDomainsListViewModel.swift @@ -54,7 +54,7 @@ class AllDomainsListViewModel { self.domainsService = .init(coreDataStack: coreDataStack, wordPressComRestApi: account.wordPressComRestApi) } self.domains = domains - if domains.count > 0 { + if !domains.isEmpty { self.state = self.state(from: domains, searchQuery: lastSearchQuery) } } diff --git a/WordPress/Classes/ViewRelated/Media/SiteMedia/Controllers/SiteMediaAddMediaMenuController.swift b/WordPress/Classes/ViewRelated/Media/SiteMedia/Controllers/SiteMediaAddMediaMenuController.swift index dbf98cac1e9d..8955494bc473 100644 --- a/WordPress/Classes/ViewRelated/Media/SiteMedia/Controllers/SiteMediaAddMediaMenuController.swift +++ b/WordPress/Classes/ViewRelated/Media/SiteMedia/Controllers/SiteMediaAddMediaMenuController.swift @@ -66,7 +66,7 @@ final class SiteMediaAddMediaMenuController: NSObject, PHPickerViewControllerDel func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) { picker.presentingViewController?.dismiss(animated: true) - guard results.count > 0 else { + guard !results.isEmpty else { return } diff --git a/WordPress/Classes/ViewRelated/Media/SiteMedia/SiteMediaViewController.swift b/WordPress/Classes/ViewRelated/Media/SiteMedia/SiteMediaViewController.swift index 19bf41d75f9d..8ec1704a3fb7 100644 --- a/WordPress/Classes/ViewRelated/Media/SiteMedia/SiteMediaViewController.swift +++ b/WordPress/Classes/ViewRelated/Media/SiteMedia/SiteMediaViewController.swift @@ -188,8 +188,8 @@ final class SiteMediaViewController: UIViewController, SiteMediaCollectionViewCo } private func updateToolbarItemsState(for selection: [Media]) { - toolbarItemDelete.isEnabled = selection.count > 0 - toolbarItemShare.isEnabled = selection.count > 0 + toolbarItemDelete.isEnabled = !selection.isEmpty + toolbarItemShare.isEnabled = !selection.isEmpty toolbarItemTitle.setSelection(selection) } diff --git a/WordPress/Classes/ViewRelated/Media/StockPhotos/StockPhotosDataSource.swift b/WordPress/Classes/ViewRelated/Media/StockPhotos/StockPhotosDataSource.swift index 7110ddea0674..f14920cb31c7 100644 --- a/WordPress/Classes/ViewRelated/Media/StockPhotos/StockPhotosDataSource.swift +++ b/WordPress/Classes/ViewRelated/Media/StockPhotos/StockPhotosDataSource.swift @@ -56,7 +56,7 @@ extension StockPhotosDataSource: StockPhotosDataLoaderDelegate { onStopLoading?() } - guard media.count > 0 && searchQuery.count > 0 else { + guard !media.isEmpty && !searchQuery.isEmpty else { clearSearch(notifyObservers: true) return } diff --git a/WordPress/Classes/ViewRelated/Media/Tenor/TenorDataSource.swift b/WordPress/Classes/ViewRelated/Media/Tenor/TenorDataSource.swift index 37a7bd8c2b67..73307ec9a663 100644 --- a/WordPress/Classes/ViewRelated/Media/Tenor/TenorDataSource.swift +++ b/WordPress/Classes/ViewRelated/Media/Tenor/TenorDataSource.swift @@ -58,7 +58,7 @@ extension TenorDataSource: TenorDataLoaderDelegate { onStopLoading?() } - guard media.count > 0, searchQuery.count > 0 else { + guard !media.isEmpty, !searchQuery.isEmpty else { clearSearch(notifyObservers: true) return } diff --git a/WordPress/Classes/ViewRelated/NUX/Controllers/Social Signup/SignupUsernameTableViewController.swift b/WordPress/Classes/ViewRelated/NUX/Controllers/Social Signup/SignupUsernameTableViewController.swift index 83572e7e5c2a..ffbfb4e74c22 100644 --- a/WordPress/Classes/ViewRelated/NUX/Controllers/Social Signup/SignupUsernameTableViewController.swift +++ b/WordPress/Classes/ViewRelated/NUX/Controllers/Social Signup/SignupUsernameTableViewController.swift @@ -115,7 +115,7 @@ class SignupUsernameTableViewController: UITableViewController, SearchTableViewC // MARK: - SearchTableViewCellDelegate func startSearch(for searchTerm: String) { - guard searchTerm.count > 0 else { + guard !searchTerm.isEmpty else { return } @@ -260,7 +260,7 @@ extension SignupUsernameTableViewController { let service = AccountSettingsService(userID: userID.intValue, api: api) service.suggestUsernames(base: searchTerm) { [weak self] (newSuggestions) in - if newSuggestions.count == 0 { + if newSuggestions.isEmpty { WordPressAuthenticator.track(.signupEpilogueUsernameSuggestionsFailed) } self?.isSearching = false diff --git a/WordPress/Classes/ViewRelated/Notifications/Controllers/NotificationContentRouter.swift b/WordPress/Classes/ViewRelated/Notifications/Controllers/NotificationContentRouter.swift index b6749ff15cdb..ad17aa74d345 100644 --- a/WordPress/Classes/ViewRelated/Notifications/Controllers/NotificationContentRouter.swift +++ b/WordPress/Classes/ViewRelated/Notifications/Controllers/NotificationContentRouter.swift @@ -93,7 +93,7 @@ struct NotificationContentRouter { case .stats: /// Backup notifications are configured as "stat" notifications /// For now this is just a workaround to fix the routing - if url.absoluteString.matches(regex: "\\/backup\\/").count > 0 { + if !url.absoluteString.matches(regex: "\\/backup\\/").isEmpty { try coordinator.displayBackupWithSiteID(range.siteID) } else { trackStatsRoute() diff --git a/WordPress/Classes/ViewRelated/Notifications/Controllers/NotificationSettingDetailsViewController.swift b/WordPress/Classes/ViewRelated/Notifications/Controllers/NotificationSettingDetailsViewController.swift index fb885c7bc040..0008e12f2e4c 100644 --- a/WordPress/Classes/ViewRelated/Notifications/Controllers/NotificationSettingDetailsViewController.swift +++ b/WordPress/Classes/ViewRelated/Notifications/Controllers/NotificationSettingDetailsViewController.swift @@ -298,7 +298,7 @@ class NotificationSettingDetailsViewController: UITableViewController { // MARK: - Service Helpers private func saveSettingsIfNeeded() { - if newValues.count == 0 || settings == nil { + if newValues.isEmpty || settings == nil { return } diff --git a/WordPress/Classes/ViewRelated/Notifications/Controllers/NotificationSettingsViewController.swift b/WordPress/Classes/ViewRelated/Notifications/Controllers/NotificationSettingsViewController.swift index 87c758064a2c..7cd623a0bfb4 100644 --- a/WordPress/Classes/ViewRelated/Notifications/Controllers/NotificationSettingsViewController.swift +++ b/WordPress/Classes/ViewRelated/Notifications/Controllers/NotificationSettingsViewController.swift @@ -452,7 +452,7 @@ private extension NotificationSettingsViewController { return followedSites.isEmpty default: - return groupedSettings[section]?.count == 0 + return groupedSettings[section]?.isEmpty ?? true } } diff --git a/WordPress/Classes/ViewRelated/Notifications/Controllers/NotificationsViewController/NotificationsViewController.swift b/WordPress/Classes/ViewRelated/Notifications/Controllers/NotificationsViewController/NotificationsViewController.swift index 43db30c4c9b9..e49a0153c505 100644 --- a/WordPress/Classes/ViewRelated/Notifications/Controllers/NotificationsViewController/NotificationsViewController.swift +++ b/WordPress/Classes/ViewRelated/Notifications/Controllers/NotificationsViewController/NotificationsViewController.swift @@ -1590,7 +1590,7 @@ private extension NotificationsViewController { } var shouldDisplayNoResultsView: Bool { - return tableViewHandler?.resultsController?.fetchedObjects?.count == 0 && !shouldDisplayJetpackPrompt + return tableViewHandler?.resultsController?.fetchedObjects?.isEmpty == true && !shouldDisplayJetpackPrompt } var shouldDisplayFullscreenNoResultsView: Bool { diff --git a/WordPress/Classes/ViewRelated/People/Controllers/InvitePersonViewController.swift b/WordPress/Classes/ViewRelated/People/Controllers/InvitePersonViewController.swift index f8fae9492c03..9a3165cdd87d 100644 --- a/WordPress/Classes/ViewRelated/People/Controllers/InvitePersonViewController.swift +++ b/WordPress/Classes/ViewRelated/People/Controllers/InvitePersonViewController.swift @@ -72,7 +72,7 @@ class InvitePersonViewController: UITableViewController { return } - if blog.inviteLinks?.count == 0 { + if blog.inviteLinks?.isEmpty == true { generateShareCell.accessoryView = inviteActivityView } else { disableLinksCell.accessoryView = inviteActivityView @@ -97,7 +97,7 @@ class InvitePersonViewController: UITableViewController { private var currentInviteLink: InviteLinks? { let links = sortedInviteLinks - guard links.count > 0 && selectedInviteLinkIndex < links.count else { + guard !links.isEmpty && selectedInviteLinkIndex < links.count else { return nil } return links[selectedInviteLinkIndex] @@ -205,7 +205,7 @@ class InvitePersonViewController: UITableViewController { return super.tableView(tableView, numberOfRowsInSection: section) } // One cell for no cached inviteLinks. Otherwise 4. - return blog.inviteLinks?.count == 0 ? 1 : 4 + return blog.inviteLinks?.isEmpty == true ? 1 : 4 } override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { @@ -568,7 +568,7 @@ private extension InvitePersonViewController { } func refreshGenerateShareCell() { - if blog.inviteLinks?.count == 0 { + if blog.inviteLinks?.isEmpty == true { generateShareCell.textLabel?.text = NSLocalizedString("Generate new link", comment: "Title. A call to action to generate a new invite link.") generateShareCell.textLabel?.font = WPStyleGuide.tableviewTextFont() } else { @@ -737,7 +737,7 @@ private extension InvitePersonViewController { } switch row { case .generateShare: - if blog.inviteLinks?.count == 0 { + if blog.inviteLinks?.isEmpty == true { generateInviteLinks() } else { shareInviteLink() diff --git a/WordPress/Classes/ViewRelated/People/Controllers/PeopleViewController.swift b/WordPress/Classes/ViewRelated/People/Controllers/PeopleViewController.swift index 15d236370273..5999b0a61d1a 100644 --- a/WordPress/Classes/ViewRelated/People/Controllers/PeopleViewController.swift +++ b/WordPress/Classes/ViewRelated/People/Controllers/PeopleViewController.swift @@ -431,7 +431,7 @@ private extension PeopleViewController { // MARK: No Results Helpers func refreshNoResultsView() { - guard resultsController.fetchedObjects?.count == 0 else { + guard resultsController.fetchedObjects?.isEmpty == true else { noResultsViewController.removeFromView() return } diff --git a/WordPress/Classes/ViewRelated/People/Controllers/PersonViewController.swift b/WordPress/Classes/ViewRelated/People/Controllers/PersonViewController.swift index e600f6710350..41107a5983a7 100644 --- a/WordPress/Classes/ViewRelated/People/Controllers/PersonViewController.swift +++ b/WordPress/Classes/ViewRelated/People/Controllers/PersonViewController.swift @@ -375,7 +375,7 @@ private extension PersonViewController { headerCell.userNameLabel.font = .preferredFont(forTextStyle: .subheadline) headerCell.userNameLabel.textColor = .secondaryLabel - headerCell.userNameLabel.text = person.username.count > 0 ? "@" + person.username : "" + headerCell.userNameLabel.text = !person.username.isEmpty ? "@" + person.username : "" refreshGravatarImage(in: headerCell.gravatarImageView) } diff --git a/WordPress/Classes/ViewRelated/Plugins/ViewModels/PluginListViewModel.swift b/WordPress/Classes/ViewRelated/Plugins/ViewModels/PluginListViewModel.swift index e4a89e31409f..934d38d71e82 100644 --- a/WordPress/Classes/ViewRelated/Plugins/ViewModels/PluginListViewModel.swift +++ b/WordPress/Classes/ViewRelated/Plugins/ViewModels/PluginListViewModel.swift @@ -184,7 +184,7 @@ class PluginListViewModel: Observable { guard case .feed(let feedType) = query, case .search = feedType, case .directory(let result) = plugins, - result.count == 0 else { + result.isEmpty else { return nil } diff --git a/WordPress/Classes/ViewRelated/Post/Categories/PostCategoryCreateView.swift b/WordPress/Classes/ViewRelated/Post/Categories/PostCategoryCreateView.swift index 251058bfcc1a..2acbcbe80d59 100644 --- a/WordPress/Classes/ViewRelated/Post/Categories/PostCategoryCreateView.swift +++ b/WordPress/Classes/ViewRelated/Post/Categories/PostCategoryCreateView.swift @@ -120,7 +120,7 @@ struct PostCategoryPickerHostingView: UIViewControllerRepresentable { } func postCategoriesViewController(_ controller: PostCategoriesViewController, didUpdateSelectedCategories categories: NSSet) { - if categories.count == 0 { + if categories.isEmpty { onSelectionChanged(nil) } } diff --git a/WordPress/Classes/ViewRelated/Post/Controllers/AbstractPostListViewController.swift b/WordPress/Classes/ViewRelated/Post/Controllers/AbstractPostListViewController.swift index 462bd2dd0557..5a9fe60b334a 100644 --- a/WordPress/Classes/ViewRelated/Post/Controllers/AbstractPostListViewController.swift +++ b/WordPress/Classes/ViewRelated/Post/Controllers/AbstractPostListViewController.swift @@ -71,7 +71,7 @@ class AbstractPostListViewController: UIViewController, private lazy var searchController = UISearchController(searchResultsController: searchResultsViewController) private var emptyResults: Bool { - fetchResultsController?.fetchedObjects?.count == 0 + fetchResultsController?.fetchedObjects?.isEmpty == true } private var atLeastSyncedOnce = false @@ -466,7 +466,7 @@ class AbstractPostListViewController: UIViewController, } func updateFilter(_ filter: PostListFilter, withSyncedPosts posts: [AbstractPost], hasMore: Bool) { - guard posts.count > 0 else { + guard !posts.isEmpty else { wpAssertionFailure("This method should not be called with no posts.") return } @@ -529,7 +529,7 @@ class AbstractPostListViewController: UIViewController, guard let self else { return } - if posts.count > 0 { + if !posts.isEmpty { self.updateFilter(filter, withSyncedPosts: posts, hasMore: hasMore) SearchManager.shared.indexItems(posts) } @@ -561,7 +561,7 @@ class AbstractPostListViewController: UIViewController, // User may have exit the screen when the "syncPosts" call above completes. guard let self else { return } - if posts.count > 0 { + if !posts.isEmpty { self.updateFilter(filter, withSyncedPosts: posts, hasMore: hasMore) SearchManager.shared.indexItems(posts) } diff --git a/WordPress/Classes/ViewRelated/Post/Publishing/Views/PrepublishingAutoSharingView.swift b/WordPress/Classes/ViewRelated/Post/Publishing/Views/PrepublishingAutoSharingView.swift index 380255248981..800d9fb3ef80 100644 --- a/WordPress/Classes/ViewRelated/Post/Publishing/Views/PrepublishingAutoSharingView.swift +++ b/WordPress/Classes/ViewRelated/Post/Publishing/Views/PrepublishingAutoSharingView.swift @@ -27,7 +27,7 @@ struct PrepublishingAutoSharingView: View { private var content: some View { Group { textStack - if model.services.count > 0 { + if !model.services.isEmpty { if !shouldStackContentVertically { Spacer(minLength: .zero) // to push the icons to the trailing side in horizontal layout. } diff --git a/WordPress/Classes/ViewRelated/Reader/Controllers/ReaderSiteSearchViewController.swift b/WordPress/Classes/ViewRelated/Reader/Controllers/ReaderSiteSearchViewController.swift index c7f8e7811cde..10cdf93ac277 100644 --- a/WordPress/Classes/ViewRelated/Reader/Controllers/ReaderSiteSearchViewController.swift +++ b/WordPress/Classes/ViewRelated/Reader/Controllers/ReaderSiteSearchViewController.swift @@ -90,7 +90,7 @@ class ReaderSiteSearchViewController: UITableViewController { private func reloadData(hasMoreResults: Bool = false) { tableView.reloadData() - let noFeeds = feeds.count == 0 + let noFeeds = feeds.isEmpty footerView.isHidden = noFeeds @@ -103,7 +103,7 @@ class ReaderSiteSearchViewController: UITableViewController { } private func handleFailedSearch() { - if feeds.count == 0 { + if feeds.isEmpty { showLoadingFailedView() } diff --git a/WordPress/Classes/ViewRelated/Reader/Controllers/ReaderStreamViewController.swift b/WordPress/Classes/ViewRelated/Reader/Controllers/ReaderStreamViewController.swift index 97c019264956..cfb36a7506f9 100644 --- a/WordPress/Classes/ViewRelated/Reader/Controllers/ReaderStreamViewController.swift +++ b/WordPress/Classes/ViewRelated/Reader/Controllers/ReaderStreamViewController.swift @@ -939,7 +939,7 @@ import AutomatticTracks let successBlock = { [weak self] (count: Int, hasMore: Bool) in DispatchQueue.main.async { if let strongSelf = self { - if strongSelf.recentlyBlockedSitePostObjectIDs.count > 0 { + if !strongSelf.recentlyBlockedSitePostObjectIDs.isEmpty { strongSelf.recentlyBlockedSitePostObjectIDs.removeAllObjects() strongSelf.updateAndPerformFetchRequest() } @@ -1009,7 +1009,7 @@ import AutomatticTracks let successBlock = { [weak self] (count: Int, hasMore: Bool) in DispatchQueue.main.async { if let strongSelf = self { - if strongSelf.recentlyBlockedSitePostObjectIDs.count > 0 { + if !strongSelf.recentlyBlockedSitePostObjectIDs.isEmpty { strongSelf.recentlyBlockedSitePostObjectIDs.removeAllObjects() strongSelf.updateAndPerformFetchRequest() } @@ -1148,7 +1148,7 @@ import AutomatticTracks return predicateForNilTopic } - if recentlyBlockedSitePostObjectIDs.count > 0 { + if !recentlyBlockedSitePostObjectIDs.isEmpty { return NSPredicate(format: "topic = %@ AND (isSiteBlocked = NO OR SELF in %@)", topicInContext, recentlyBlockedSitePostObjectIDs) } @@ -1302,7 +1302,7 @@ extension ReaderStreamViewController: WPTableViewHandlerDelegate { func tableViewHandlerDidRefreshTableViewPreservingOffset(_ tableViewHandler: WPTableViewHandler) { hideResultsStatus() - if tableViewHandler.resultsController?.fetchedObjects?.count == 0 { + if tableViewHandler.resultsController?.fetchedObjects?.isEmpty == true { if let syncHelper, syncHelper.isSyncing { return } diff --git a/WordPress/Classes/ViewRelated/Reader/Select Interests/ReaderSelectInterestsViewController.swift b/WordPress/Classes/ViewRelated/Reader/Select Interests/ReaderSelectInterestsViewController.swift index 5533bef3ebee..fe56b9551fb9 100644 --- a/WordPress/Classes/ViewRelated/Reader/Select Interests/ReaderSelectInterestsViewController.swift +++ b/WordPress/Classes/ViewRelated/Reader/Select Interests/ReaderSelectInterestsViewController.swift @@ -253,7 +253,7 @@ class ReaderSelectInterestsViewController: UIViewController { // MARK: - Private: UI Helpers private func updateNextButtonState() { - nextButton.isEnabled = dataSource.selectedInterests.count > 0 + nextButton.isEnabled = !dataSource.selectedInterests.isEmpty } private func startLoading(hideLabel: Bool = false) { @@ -354,7 +354,7 @@ extension ReaderSelectInterestsViewController: UICollectionViewDelegateFlowLayou // MARK: - ReaderInterestsDataDelegate extension ReaderSelectInterestsViewController: ReaderInterestsDataDelegate { func readerInterestsDidUpdate(_ dataSource: ReaderInterestsDataSource) { - if dataSource.count > 0 { + if !dataSource.isEmpty { hideLoadingView() reloadData() } else if !topics.isEmpty { diff --git a/WordPress/Classes/ViewRelated/Reader/Views/ReaderInterestsCoordinator.swift b/WordPress/Classes/ViewRelated/Reader/Views/ReaderInterestsCoordinator.swift index a45301686118..525a95446e33 100644 --- a/WordPress/Classes/ViewRelated/Reader/Views/ReaderInterestsCoordinator.swift +++ b/WordPress/Classes/ViewRelated/Reader/Views/ReaderInterestsCoordinator.swift @@ -53,7 +53,7 @@ class ReaderSelectInterestsCoordinator { interests.count == 1 { return interest.slug != Post.Strings.promptTag } - return interests.count > 0 + return !interests.isEmpty }() completion(isFollowingInterests) diff --git a/WordPress/Classes/ViewRelated/Stats/Charts/DonutChartView.swift b/WordPress/Classes/ViewRelated/Stats/Charts/DonutChartView.swift index 95005f637975..d2d4e5f90ce3 100644 --- a/WordPress/Classes/ViewRelated/Stats/Charts/DonutChartView.swift +++ b/WordPress/Classes/ViewRelated/Stats/Charts/DonutChartView.swift @@ -233,7 +233,7 @@ class DonutChartView: UIView { // need to adjust it to match the minimum, and add it to the array. let totalAdjustment: CGFloat = belowMinimumSegments.reduce(0) { $0 + minimumSizePercentage - $1.value } - guard belowMinimumSegments.count > 0 else { + guard !belowMinimumSegments.isEmpty else { return segments } diff --git a/WordPress/Classes/ViewRelated/Stats/Charts/SparklineView.swift b/WordPress/Classes/ViewRelated/Stats/Charts/SparklineView.swift index 786f2238edad..42711e573996 100644 --- a/WordPress/Classes/ViewRelated/Stats/Charts/SparklineView.swift +++ b/WordPress/Classes/ViewRelated/Stats/Charts/SparklineView.swift @@ -70,7 +70,7 @@ class SparklineView: UIView { } private func interpolateData(_ inputData: [CGFloat]) -> [CGFloat] { - guard inputData.count > 0, + guard !inputData.isEmpty, let first = inputData.first else { return [] } diff --git a/WordPress/Classes/ViewRelated/Stats/Insights/Insights Management/InsightsManagementViewController.swift b/WordPress/Classes/ViewRelated/Stats/Insights/Insights Management/InsightsManagementViewController.swift index 9e6877a1a3e5..f13a68fb7497 100644 --- a/WordPress/Classes/ViewRelated/Stats/Insights/Insights Management/InsightsManagementViewController.swift +++ b/WordPress/Classes/ViewRelated/Stats/Insights/Insights Management/InsightsManagementViewController.swift @@ -109,7 +109,7 @@ class InsightsManagementViewController: UITableViewController { } override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool { - return insightsShown.count > 0 && isActiveCardsSection(indexPath.section) + return !insightsShown.isEmpty && isActiveCardsSection(indexPath.section) } override func tableView(_ tableView: UITableView, targetIndexPathForMoveFromRowAt sourceIndexPath: IndexPath, toProposedIndexPath proposedDestinationIndexPath: IndexPath) -> IndexPath { @@ -217,7 +217,7 @@ private extension InsightsManagementViewController { // MARK: - Table Sections func selectedStatsSection() -> ImmuTableSection? { - guard insightsShown.count > 0 else { + guard !insightsShown.isEmpty else { return ImmuTableSection(headerText: TextContent.activeCardsHeader, rows: [placeholderRow]) } @@ -232,7 +232,7 @@ private extension InsightsManagementViewController { func inactiveCardsSection() -> ImmuTableSection { let rows = insightsInactive - guard rows.count > 0 else { + guard !rows.isEmpty else { return ImmuTableSection(headerText: TextContent.inactiveCardsHeader, rows: [inactivePlaceholderRow]) } @@ -283,7 +283,7 @@ private extension InsightsManagementViewController { } /// Reload the data of the row to update the accessibility information - if let cell = tableView.cellForRow(at: destination), insightsShown.count > 0 { + if let cell = tableView.cellForRow(at: destination), !insightsShown.isEmpty { tableHandler.viewModel.rowAtIndexPath(destination).configureCell(cell) } } @@ -311,7 +311,7 @@ private extension InsightsManagementViewController { } /// Reload the data of the row to update the accessibility information - if let cell = tableView.cellForRow(at: destination), insightsInactive.count > 0 { + if let cell = tableView.cellForRow(at: destination), !insightsInactive.isEmpty { tableHandler.viewModel.rowAtIndexPath(destination).configureCell(cell) } } diff --git a/WordPress/Classes/ViewRelated/Stats/Insights/TabbedTotalsCell.swift b/WordPress/Classes/ViewRelated/Stats/Insights/TabbedTotalsCell.swift index 7a8f731cc96e..01c1f92fd709 100644 --- a/WordPress/Classes/ViewRelated/Stats/Insights/TabbedTotalsCell.swift +++ b/WordPress/Classes/ViewRelated/Stats/Insights/TabbedTotalsCell.swift @@ -118,7 +118,7 @@ private extension TabbedTotalsCell { func toggleFilterTabBar() { // If none of the tabs have data, hide the FilterTabBar. - let noTabsData = (tabsData.first { $0.dataRows.count > 0 }) == nil + let noTabsData = (tabsData.first { !$0.dataRows.isEmpty }) == nil filterTabBar.isHidden = noTabsData } @@ -189,7 +189,7 @@ private extension TabbedTotalsCell { Style.configureLabelAsSubtitle(itemSubtitleLabel) Style.configureLabelAsSubtitle(dataSubtitleLabel) - let noData = tabData.dataRows.count == 0 + let noData = tabData.dataRows.isEmpty totalCountView.isHidden = !showTotalCount || noData labelsStackView.isHidden = noData } diff --git a/WordPress/Classes/ViewRelated/Stats/Period Stats/SiteStatsPeriodViewModel.swift b/WordPress/Classes/ViewRelated/Stats/Period Stats/SiteStatsPeriodViewModel.swift index 3ebdfd759e3f..39ff488f7b0f 100644 --- a/WordPress/Classes/ViewRelated/Stats/Period Stats/SiteStatsPeriodViewModel.swift +++ b/WordPress/Classes/ViewRelated/Stats/Period Stats/SiteStatsPeriodViewModel.swift @@ -363,7 +363,7 @@ private extension SiteStatsPeriodViewModel { let likesData = intervalData(summaryType: .likes) // If Summary Likes is still loading, show dashes (instead of 0) // to indicate it's still loading. - let likesLoadingStub = likesData.count > 0 ? nil : (store.isFetchingSummary ? "----" : nil) + let likesLoadingStub = !likesData.isEmpty ? nil : (store.isFetchingSummary ? "----" : nil) let likesTabData = OverviewTabData(tabTitle: StatSection.periodOverviewLikes.tabTitle, tabData: likesData.count, tabDataStub: likesLoadingStub, diff --git a/WordPress/Classes/ViewRelated/Stats/Shared Views/Post Stats/PostStatsViewModel.swift b/WordPress/Classes/ViewRelated/Stats/Shared Views/Post Stats/PostStatsViewModel.swift index 5b5f9ceb2322..72b63e588adc 100644 --- a/WordPress/Classes/ViewRelated/Stats/Shared Views/Post Stats/PostStatsViewModel.swift +++ b/WordPress/Classes/ViewRelated/Stats/Shared Views/Post Stats/PostStatsViewModel.swift @@ -187,7 +187,7 @@ private extension PostStatsViewModel { let rowValue: Int = { if forAverages { - return months.count > 0 ? (yearTotalViews / months.count) : 0 + return !months.isEmpty ? (yearTotalViews / months.count) : 0 } return yearTotalViews }() diff --git a/WordPress/Classes/ViewRelated/Stats/Shared Views/Stats Detail/SiteStatsDetailsViewModel.swift b/WordPress/Classes/ViewRelated/Stats/Shared Views/Stats Detail/SiteStatsDetailsViewModel.swift index 17a265195951..629668b6c2d3 100644 --- a/WordPress/Classes/ViewRelated/Stats/Shared Views/Stats Detail/SiteStatsDetailsViewModel.swift +++ b/WordPress/Classes/ViewRelated/Stats/Shared Views/Stats Detail/SiteStatsDetailsViewModel.swift @@ -853,7 +853,7 @@ private extension SiteStatsDetailsViewModel { let rowValue: Int = { if forAverages { - return months.count > 0 ? (yearTotalViews / months.count) : 0 + return !months.isEmpty ? (yearTotalViews / months.count) : 0 } return yearTotalViews }() diff --git a/WordPress/Classes/ViewRelated/Stats/Shared Views/Stats Detail/SiteStatsInsightsDetailsViewModel.swift b/WordPress/Classes/ViewRelated/Stats/Shared Views/Stats Detail/SiteStatsInsightsDetailsViewModel.swift index 959e449a3480..8cd01ce8d6dd 100644 --- a/WordPress/Classes/ViewRelated/Stats/Shared Views/Stats Detail/SiteStatsInsightsDetailsViewModel.swift +++ b/WordPress/Classes/ViewRelated/Stats/Shared Views/Stats Detail/SiteStatsInsightsDetailsViewModel.swift @@ -1131,7 +1131,7 @@ private extension SiteStatsInsightsDetailsViewModel { let rowValue: Int = { if forAverages { - return months.count > 0 ? (yearTotalViews / months.count) : 0 + return !months.isEmpty ? (yearTotalViews / months.count) : 0 } return yearTotalViews }() diff --git a/WordPress/Classes/ViewRelated/Stats/Shared Views/Stats Detail/StatsReferrersChartViewModel.swift b/WordPress/Classes/ViewRelated/Stats/Shared Views/Stats Detail/StatsReferrersChartViewModel.swift index 44935e3464b1..5da0fdcbaade 100644 --- a/WordPress/Classes/ViewRelated/Stats/Shared Views/Stats Detail/StatsReferrersChartViewModel.swift +++ b/WordPress/Classes/ViewRelated/Stats/Shared Views/Stats Detail/StatsReferrersChartViewModel.swift @@ -29,7 +29,7 @@ struct StatsReferrersChartViewModel { } // Then add groups from the top of the list to make up our target group count - while topReferrers.count < (Constants.referrersMaxGroupCount - 1) && allReferrers.count > 0 { + while topReferrers.count < (Constants.referrersMaxGroupCount - 1) && !allReferrers.isEmpty { topReferrers.append(allReferrers.removeFirst()) } diff --git a/WordPress/Classes/ViewRelated/Stats/Shared Views/TopTotalsCell.swift b/WordPress/Classes/ViewRelated/Stats/Shared Views/TopTotalsCell.swift index 4534f7523d3f..0ab587338787 100644 --- a/WordPress/Classes/ViewRelated/Stats/Shared Views/TopTotalsCell.swift +++ b/WordPress/Classes/ViewRelated/Stats/Shared Views/TopTotalsCell.swift @@ -356,7 +356,7 @@ extension TopTotalsCell: Accessible { func prepareForVoiceOver() { accessibilityTraits = .summaryElement - guard dataRows.count > 0 else { + guard !dataRows.isEmpty else { return } diff --git a/WordPress/Classes/ViewRelated/Suggestions/SuggestionsListViewModel.swift b/WordPress/Classes/ViewRelated/Suggestions/SuggestionsListViewModel.swift index c1ea9d4b31ee..4ef20858170b 100644 --- a/WordPress/Classes/ViewRelated/Suggestions/SuggestionsListViewModel.swift +++ b/WordPress/Classes/ViewRelated/Suggestions/SuggestionsListViewModel.swift @@ -141,7 +141,7 @@ import WordPressKit // Call callback and return result self.searchResultUpdated?(self) - return sections.count > 0 + return !sections.isEmpty } private static func searchResult(searchQuery: String, suggestions: Suggestions, suggestionType: SuggestionType, prominentSuggestionsIds: [NSNumber]) -> SearchResult { @@ -198,7 +198,7 @@ import WordPressKit // Move suggestions to the beginning of `searchResults` array. var userSuggestions = userSuggestions - if !prominentSuggestions.isEmpty && suggestionIndexesToRemove.count > 0 { + if !prominentSuggestions.isEmpty && !suggestionIndexesToRemove.isEmpty { let prominentSuggestions = prominentSuggestions.compactMap { $0 } suggestionIndexesToRemove = suggestionIndexesToRemove.sorted(by: >) suggestionIndexesToRemove.forEach { userSuggestions.remove(at: $0) } diff --git a/WordPress/Classes/ViewRelated/Tags/SiteTagsView.swift b/WordPress/Classes/ViewRelated/Tags/SiteTagsView.swift index b92a59297996..0a7f74abdd9b 100644 --- a/WordPress/Classes/ViewRelated/Tags/SiteTagsView.swift +++ b/WordPress/Classes/ViewRelated/Tags/SiteTagsView.swift @@ -168,7 +168,7 @@ private struct TagRowContent: View { Spacer() - if showPostCount, tag.count > 0 { + if showPostCount, !tag.isEmpty { Text("\(tag.count)") .font(.callout) .foregroundColor(.secondary) diff --git a/WordPress/Classes/ViewRelated/Tools/SettingsListEditorViewController.swift b/WordPress/Classes/ViewRelated/Tools/SettingsListEditorViewController.swift index 34df597a976e..690e0ac847ba 100644 --- a/WordPress/Classes/ViewRelated/Tools/SettingsListEditorViewController.swift +++ b/WordPress/Classes/ViewRelated/Tools/SettingsListEditorViewController.swift @@ -173,7 +173,7 @@ open class SettingsListEditorViewController: UITableViewController { } fileprivate func isEmpty() -> Bool { - return rows.count == 0 + return rows.isEmpty } // MARK: - Constants diff --git a/WordPress/WordPressShareExtension/Sources/Services/AppExtensionsService.swift b/WordPress/WordPressShareExtension/Sources/Services/AppExtensionsService.swift index 1bb9e704f7a0..ea86a0d63760 100644 --- a/WordPress/WordPressShareExtension/Sources/Services/AppExtensionsService.swift +++ b/WordPress/WordPressShareExtension/Sources/Services/AppExtensionsService.swift @@ -310,7 +310,7 @@ extension AppExtensionsService { requestEnqueued() }, success: { remoteMedia in guard let returnedMedia = remoteMedia as? [RemoteMedia], - returnedMedia.count > 0, + !returnedMedia.isEmpty, let mediaUploadOps = self.coreDataStack.fetchMediaUploadOps(for: self.groupIdentifier) else { DDLogError("Error creating post in share extension. RemoteMedia info not returned from server.") return diff --git a/WordPress/WordPressShareExtension/Sources/Services/ShareExtractor.swift b/WordPress/WordPressShareExtension/Sources/Services/ShareExtractor.swift index 834375e39451..86c379ea83f8 100644 --- a/WordPress/WordPressShareExtension/Sources/Services/ShareExtractor.swift +++ b/WordPress/WordPressShareExtension/Sources/Services/ShareExtractor.swift @@ -171,7 +171,7 @@ private extension ShareExtractor { return } textExtractor.extract(context: extensionContext) { extractedItems in - guard extractedItems.count > 0 else { + guard !extractedItems.isEmpty else { completion(nil) return } @@ -204,7 +204,7 @@ private extension ShareExtractor { return } imageExtractor.extract(context: extensionContext) { extractedItems in - guard extractedItems.count > 0 else { + guard !extractedItems.isEmpty else { completion([]) return } @@ -251,7 +251,7 @@ private extension TypeBasedExtensionContentExtractor { let itemProviders = context.itemProviders(ofType: acceptedType) print(acceptedType) var results = [ExtractedItem]() - guard itemProviders.count > 0 else { + guard !itemProviders.isEmpty else { DispatchQueue.main.async { completion(results) } diff --git a/WordPress/WordPressShareExtension/Sources/UI/ShareModularViewController.swift b/WordPress/WordPressShareExtension/Sources/UI/ShareModularViewController.swift index 4ea782921dec..57f452a74709 100644 --- a/WordPress/WordPressShareExtension/Sources/UI/ShareModularViewController.swift +++ b/WordPress/WordPressShareExtension/Sources/UI/ShareModularViewController.swift @@ -443,7 +443,7 @@ fileprivate extension ShareModularViewController { } cell.detailTextLabel?.text = shareData.selectedCategoriesNameString - if (shareData.userSelectedCategories == nil || shareData.userSelectedCategories?.count == 0) + if (shareData.userSelectedCategories == nil || shareData.userSelectedCategories?.isEmpty == true) && shareData.defaultCategoryID == Constants.unknownDefaultCategoryID { cell.detailTextLabel?.textColor = UIAppColor.neutral(.shade30) } else { @@ -596,7 +596,7 @@ fileprivate extension ShareModularViewController { clearAllSelectedSiteRows() cell.accessoryType = .checkmark shareData.selectedSiteID = site.blogID.intValue - shareData.selectedSiteName = site.name.count > 0 ? site.name : URL(string: site.url)?.host + shareData.selectedSiteName = !site.name.isEmpty ? site.name : URL(string: site.url)?.host fetchCategoriesForSelectedSite() updatePublishButtonStatus() self.refreshModulesTable() From 3d2e533dca1c588fb7af813d25161ce95be7df7e Mon Sep 17 00:00:00 2001 From: Gio Lodi Date: Tue, 24 Mar 2026 15:46:20 +1100 Subject: [PATCH 2/5] Fix false positive on AggregatedDataPoint `AggregatedDataPoint.count` is an `Int` property, not a collection count. Revert to `.count != 0` with inline disable. --- Generated with the help of Claude Code, https://claude.ai/code Co-Authored-By: Claude Code Opus 4.6 --- .../JetpackStats/Services/Mocks/StatsDataAggregator.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Modules/Sources/JetpackStats/Services/Mocks/StatsDataAggregator.swift b/Modules/Sources/JetpackStats/Services/Mocks/StatsDataAggregator.swift index e934cfd22043..9822afaf3cca 100644 --- a/Modules/Sources/JetpackStats/Services/Mocks/StatsDataAggregator.swift +++ b/Modules/Sources/JetpackStats/Services/Mocks/StatsDataAggregator.swift @@ -61,7 +61,8 @@ struct StatsDataAggregator { case .sum: normalizedData[date] = dataPoint.sum case .average: - if !dataPoint.isEmpty { + // swiftlint:disable:next empty_count + if dataPoint.count != 0 { normalizedData[date] = dataPoint.sum / dataPoint.count } } From c7bedddfc710c7672b199e719e97874a673a81c7 Mon Sep 17 00:00:00 2001 From: Gio Lodi Date: Tue, 24 Mar 2026 17:28:31 +1100 Subject: [PATCH 3/5] Fix 4 more empty_count false positives MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Non-collection types with a `.count` property but no `.isEmpty`: - `ReaderInterestsDataSource` - `AnyTermWithViewContext` - `NSMutableOrderedSet` - Tuple `(count: Int, difference: Int, percentage: Int)` Found via Jetpack CI build — these targets aren't compiled by the WordPress scheme locally. --- Generated with the help of Claude Code, https://claude.ai/code Co-Authored-By: Claude Code Opus 4.6 --- .../Select Interests/ReaderSelectInterestsViewController.swift | 3 ++- .../Stats/Period Stats/SiteStatsPeriodViewModel.swift | 3 ++- WordPress/Classes/ViewRelated/Tags/SiteTagsView.swift | 3 ++- .../ViewRelated/Tools/SettingsListEditorViewController.swift | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/WordPress/Classes/ViewRelated/Reader/Select Interests/ReaderSelectInterestsViewController.swift b/WordPress/Classes/ViewRelated/Reader/Select Interests/ReaderSelectInterestsViewController.swift index fe56b9551fb9..64a6ac6ada5a 100644 --- a/WordPress/Classes/ViewRelated/Reader/Select Interests/ReaderSelectInterestsViewController.swift +++ b/WordPress/Classes/ViewRelated/Reader/Select Interests/ReaderSelectInterestsViewController.swift @@ -354,7 +354,8 @@ extension ReaderSelectInterestsViewController: UICollectionViewDelegateFlowLayou // MARK: - ReaderInterestsDataDelegate extension ReaderSelectInterestsViewController: ReaderInterestsDataDelegate { func readerInterestsDidUpdate(_ dataSource: ReaderInterestsDataSource) { - if !dataSource.isEmpty { + // swiftlint:disable:next empty_count + if dataSource.count != 0 { hideLoadingView() reloadData() } else if !topics.isEmpty { diff --git a/WordPress/Classes/ViewRelated/Stats/Period Stats/SiteStatsPeriodViewModel.swift b/WordPress/Classes/ViewRelated/Stats/Period Stats/SiteStatsPeriodViewModel.swift index 39ff488f7b0f..f4b23543b901 100644 --- a/WordPress/Classes/ViewRelated/Stats/Period Stats/SiteStatsPeriodViewModel.swift +++ b/WordPress/Classes/ViewRelated/Stats/Period Stats/SiteStatsPeriodViewModel.swift @@ -363,7 +363,8 @@ private extension SiteStatsPeriodViewModel { let likesData = intervalData(summaryType: .likes) // If Summary Likes is still loading, show dashes (instead of 0) // to indicate it's still loading. - let likesLoadingStub = !likesData.isEmpty ? nil : (store.isFetchingSummary ? "----" : nil) + // swiftlint:disable:next empty_count + let likesLoadingStub = likesData.count != 0 ? nil : (store.isFetchingSummary ? "----" : nil) let likesTabData = OverviewTabData(tabTitle: StatSection.periodOverviewLikes.tabTitle, tabData: likesData.count, tabDataStub: likesLoadingStub, diff --git a/WordPress/Classes/ViewRelated/Tags/SiteTagsView.swift b/WordPress/Classes/ViewRelated/Tags/SiteTagsView.swift index 0a7f74abdd9b..59988e7b9bf7 100644 --- a/WordPress/Classes/ViewRelated/Tags/SiteTagsView.swift +++ b/WordPress/Classes/ViewRelated/Tags/SiteTagsView.swift @@ -168,7 +168,8 @@ private struct TagRowContent: View { Spacer() - if showPostCount, !tag.isEmpty { + // swiftlint:disable:next empty_count + if showPostCount, tag.count != 0 { Text("\(tag.count)") .font(.callout) .foregroundColor(.secondary) diff --git a/WordPress/Classes/ViewRelated/Tools/SettingsListEditorViewController.swift b/WordPress/Classes/ViewRelated/Tools/SettingsListEditorViewController.swift index 690e0ac847ba..64996d723d6f 100644 --- a/WordPress/Classes/ViewRelated/Tools/SettingsListEditorViewController.swift +++ b/WordPress/Classes/ViewRelated/Tools/SettingsListEditorViewController.swift @@ -173,7 +173,8 @@ open class SettingsListEditorViewController: UITableViewController { } fileprivate func isEmpty() -> Bool { - return rows.isEmpty + // swiftlint:disable:next empty_count + return rows.count == 0 } // MARK: - Constants From 1ef6bd9de8f23bb43ae898053d236490e4dc2884 Mon Sep 17 00:00:00 2001 From: Gio Lodi Date: Wed, 25 Mar 2026 09:28:10 +1100 Subject: [PATCH 4/5] Fix 3 more empty_count false positives `NSMutableArray` and `UIViewController`-typed `self` in closures have no `.isEmpty`. All 3 in `ReaderStreamViewController.swift`. --- Generated with the help of Claude Code, https://claude.ai/code Co-Authored-By: Claude Code Opus 4.6 --- .../Reader/Controllers/ReaderStreamViewController.swift | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/WordPress/Classes/ViewRelated/Reader/Controllers/ReaderStreamViewController.swift b/WordPress/Classes/ViewRelated/Reader/Controllers/ReaderStreamViewController.swift index cfb36a7506f9..b283b5770670 100644 --- a/WordPress/Classes/ViewRelated/Reader/Controllers/ReaderStreamViewController.swift +++ b/WordPress/Classes/ViewRelated/Reader/Controllers/ReaderStreamViewController.swift @@ -939,7 +939,8 @@ import AutomatticTracks let successBlock = { [weak self] (count: Int, hasMore: Bool) in DispatchQueue.main.async { if let strongSelf = self { - if !strongSelf.recentlyBlockedSitePostObjectIDs.isEmpty { + // swiftlint:disable:next empty_count + if strongSelf.recentlyBlockedSitePostObjectIDs.count > 0 { strongSelf.recentlyBlockedSitePostObjectIDs.removeAllObjects() strongSelf.updateAndPerformFetchRequest() } @@ -1009,7 +1010,8 @@ import AutomatticTracks let successBlock = { [weak self] (count: Int, hasMore: Bool) in DispatchQueue.main.async { if let strongSelf = self { - if !strongSelf.recentlyBlockedSitePostObjectIDs.isEmpty { + // swiftlint:disable:next empty_count + if strongSelf.recentlyBlockedSitePostObjectIDs.count > 0 { strongSelf.recentlyBlockedSitePostObjectIDs.removeAllObjects() strongSelf.updateAndPerformFetchRequest() } @@ -1148,7 +1150,8 @@ import AutomatticTracks return predicateForNilTopic } - if !recentlyBlockedSitePostObjectIDs.isEmpty { + // swiftlint:disable:next empty_count + if recentlyBlockedSitePostObjectIDs.count > 0 { return NSPredicate(format: "topic = %@ AND (isSiteBlocked = NO OR SELF in %@)", topicInContext, recentlyBlockedSitePostObjectIDs) } From 1551effa5dd4c0996523e053a8ad091a82cddbbd Mon Sep 17 00:00:00 2001 From: Gio Lodi Date: Wed, 25 Mar 2026 11:09:12 +1100 Subject: [PATCH 5/5] Fix NSSet empty_count false positive MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `NSSet` has no `.isEmpty` — revert to `.count == 0`. --- Generated with the help of Claude Code, https://claude.ai/code Co-Authored-By: Claude Code Opus 4.6 --- .../ViewRelated/Post/Categories/PostCategoryCreateView.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/WordPress/Classes/ViewRelated/Post/Categories/PostCategoryCreateView.swift b/WordPress/Classes/ViewRelated/Post/Categories/PostCategoryCreateView.swift index 2acbcbe80d59..68436b00480f 100644 --- a/WordPress/Classes/ViewRelated/Post/Categories/PostCategoryCreateView.swift +++ b/WordPress/Classes/ViewRelated/Post/Categories/PostCategoryCreateView.swift @@ -120,7 +120,8 @@ struct PostCategoryPickerHostingView: UIViewControllerRepresentable { } func postCategoriesViewController(_ controller: PostCategoriesViewController, didUpdateSelectedCategories categories: NSSet) { - if categories.isEmpty { + // swiftlint:disable:next empty_count + if categories.count == 0 { onSelectionChanged(nil) } }