diff --git a/Classes/Bookmark/BookmarkViewController.swift b/Classes/Bookmark/BookmarkViewController.swift index 80ee444f..2fb1cf85 100644 --- a/Classes/Bookmark/BookmarkViewController.swift +++ b/Classes/Bookmark/BookmarkViewController.swift @@ -160,12 +160,12 @@ TabNavRootViewControllerType { var bookmarks: [ListDiffable] switch state { case .idle: - bookmarks = bookmarkStore.values.flatMap { + bookmarks = bookmarkStore.values.compactMap { BookmarkViewModel(bookmark: $0, contentSizeCategory: contentSizeCategory, width: width) } case .filtering(let term): bookmarks = filtered(array: bookmarkStore.values, query: term) - .flatMap { + .compactMap { BookmarkViewModel(bookmark: $0, contentSizeCategory: contentSizeCategory, width: width) } } diff --git a/Classes/Issues/Files/IssueFilesViewController.swift b/Classes/Issues/Files/IssueFilesViewController.swift index 6b9fd0e9..9df5af51 100644 --- a/Classes/Issues/Files/IssueFilesViewController.swift +++ b/Classes/Issues/Files/IssueFilesViewController.swift @@ -23,9 +23,9 @@ ListSingleSectionControllerDelegate { self.model = model self.client = client super.init( - emptyErrorMessage: NSLocalizedString("Cannot load changes.", comment: ""), - dataSource: self + emptyErrorMessage: NSLocalizedString("Cannot load changes.", comment: "") ) + self.dataSource = self let titleFormat = NSLocalizedString("Files (%d)", comment: "") title = String(format: titleFormat, fileCount) } diff --git a/Classes/Issues/Issue+IssueType.swift b/Classes/Issues/Issue+IssueType.swift index 58d4e6f1..96113d38 100644 --- a/Classes/Issues/Issue+IssueType.swift +++ b/Classes/Issues/Issue+IssueType.swift @@ -66,7 +66,7 @@ extension IssueOrPullRequestQuery.Data.Repository.IssueOrPullRequest.AsIssue: Is width: CGFloat ) -> (models: [ListDiffable], mentionedUsers: [AutocompleteUser]) { guard let nodes = timeline.nodes else { return ([], []) } - let cleanNodes = nodes.flatMap { $0 } + let cleanNodes = nodes.compactMap { $0 } var results = [ListDiffable]() var mentionedUsers = [AutocompleteUser]() diff --git a/Classes/Issues/PullRequest+IssueType.swift b/Classes/Issues/PullRequest+IssueType.swift index 400475f5..457c579f 100644 --- a/Classes/Issues/PullRequest+IssueType.swift +++ b/Classes/Issues/PullRequest+IssueType.swift @@ -90,7 +90,7 @@ extension IssueOrPullRequestQuery.Data.Repository.IssueOrPullRequest.AsPullReque width: CGFloat ) -> (models: [ListDiffable], mentionedUsers: [AutocompleteUser]) { guard let nodes = timeline.nodes else { return ([], []) } - let cleanNodes = nodes.flatMap { $0 } + let cleanNodes = nodes.compactMap { $0 } var results = [ListDiffable]() var mentionedUsers = [AutocompleteUser]() diff --git a/Classes/Labels/LabelsViewController.swift b/Classes/Labels/LabelsViewController.swift index d0d0112d..3d8d97e3 100644 --- a/Classes/Labels/LabelsViewController.swift +++ b/Classes/Labels/LabelsViewController.swift @@ -47,7 +47,7 @@ final class LabelsViewController: UITableViewController { self?.feedRefresh.endRefreshing() switch result { case .success(let nodes): - self?.update(labels: nodes.flatMap { + self?.update(labels: nodes.compactMap { guard let node = $0 else { return nil } return RepositoryLabel(color: node.color, name: node.name) }) diff --git a/Classes/Notifications/NotificationClient.swift b/Classes/Notifications/NotificationClient.swift index 5f5b0a1f..ae950458 100644 --- a/Classes/Notifications/NotificationClient.swift +++ b/Classes/Notifications/NotificationClient.swift @@ -89,7 +89,7 @@ final class NotificationClient { ) { let content = "state comments{totalCount}" - let notificationQueries: String = notifications.flatMap { + let notificationQueries: String = notifications.compactMap { guard let alias = $0.stateAlias else { return nil } return """ \(alias.key): repository(owner: "\($0.owner)", name: "\($0.repo)") { issueOrPullRequest(number: \(alias.number)) { ...on Issue {\(content)} ...on PullRequest {\(content)} } } diff --git a/Classes/Notifications/NotificationsViewController.swift b/Classes/Notifications/NotificationsViewController.swift index 74eb8d61..62d07391 100644 --- a/Classes/Notifications/NotificationsViewController.swift +++ b/Classes/Notifications/NotificationsViewController.swift @@ -38,10 +38,9 @@ FlatCacheListener { self.inboxType = inboxType super.init( - emptyErrorMessage: NSLocalizedString("Cannot load your inbox.", comment: ""), - dataSource: self + emptyErrorMessage: NSLocalizedString("Cannot load your inbox.", comment: "") ) - + self.dataSource = self self.foreground.delegate = self switch inboxType { diff --git a/Classes/People/PeopleViewController.swift b/Classes/People/PeopleViewController.swift index 1a7e7863..317d4b78 100644 --- a/Classes/People/PeopleViewController.swift +++ b/Classes/People/PeopleViewController.swift @@ -41,7 +41,9 @@ PeopleSectionControllerDelegate { self.owner = owner self.repo = repo - super.init(emptyErrorMessage: "Cannot load users.", dataSource: self) + super.init(emptyErrorMessage: "Cannot load users.") + + self.dataSource = self switch type { case .assignee: title = NSLocalizedString("Assignees", comment: "") diff --git a/Classes/Repository/RepositoryClient.swift b/Classes/Repository/RepositoryClient.swift index e9bcb138..399aa095 100644 --- a/Classes/Repository/RepositoryClient.swift +++ b/Classes/Repository/RepositoryClient.swift @@ -20,7 +20,7 @@ extension RepoIssuePagesQuery: RepositoryQuery { func summaryTypes(from data: GraphQLSelectionSet) -> [RepositoryIssueSummaryType] { guard let issues = data as? Data else { return [] } - return issues.repository?.issues.nodes?.flatMap { $0 } ?? [] + return issues.repository?.issues.nodes?.compactMap { $0 } ?? [] } func nextPageToken(from data: GraphQLSelectionSet) -> String? { @@ -35,7 +35,7 @@ extension RepoPullRequestPagesQuery: RepositoryQuery { func summaryTypes(from data: GraphQLSelectionSet) -> [RepositoryIssueSummaryType] { guard let prs = data as? RepoPullRequestPagesQuery.Data else { return [] } - return prs.repository?.pullRequests.nodes?.flatMap { $0 } ?? [] + return prs.repository?.pullRequests.nodes?.compactMap { $0 } ?? [] } func nextPageToken(from data: GraphQLSelectionSet) -> String? { diff --git a/Classes/Repository/RepositoryCodeDirectoryViewController.swift b/Classes/Repository/RepositoryCodeDirectoryViewController.swift index 51bfe46e..7996ddc3 100644 --- a/Classes/Repository/RepositoryCodeDirectoryViewController.swift +++ b/Classes/Repository/RepositoryCodeDirectoryViewController.swift @@ -31,10 +31,11 @@ ListSingleSectionControllerDelegate { self.path = path super.init( - emptyErrorMessage: NSLocalizedString("Cannot load directory.", comment: ""), - dataSource: self + emptyErrorMessage: NSLocalizedString("Cannot load directory.", comment: "") ) + self.dataSource = self + // set on init in case used by Tabman self.title = NSLocalizedString("Code", comment: "") } diff --git a/Classes/Repository/RepositoryIssuesViewController.swift b/Classes/Repository/RepositoryIssuesViewController.swift index e36d47e6..8c819ab2 100644 --- a/Classes/Repository/RepositoryIssuesViewController.swift +++ b/Classes/Repository/RepositoryIssuesViewController.swift @@ -31,9 +31,10 @@ SearchBarSectionControllerDelegate { self.type = type super.init( - emptyErrorMessage: NSLocalizedString("Cannot load issues.", comment: ""), - dataSource: self + emptyErrorMessage: NSLocalizedString("Cannot load issues.", comment: "") ) + + self.dataSource = self switch type { case .issues: title = NSLocalizedString("Issues", comment: "") diff --git a/Classes/Repository/RepositoryOverviewViewController.swift b/Classes/Repository/RepositoryOverviewViewController.swift index bb57779f..2b1e9e75 100644 --- a/Classes/Repository/RepositoryOverviewViewController.swift +++ b/Classes/Repository/RepositoryOverviewViewController.swift @@ -21,9 +21,9 @@ BaseListViewControllerDataSource { self.repo = repo self.client = RepositoryClient(githubClient: client, owner: repo.owner, name: repo.name) super.init( - emptyErrorMessage: NSLocalizedString("Cannot load README.", comment: ""), - dataSource: self + emptyErrorMessage: NSLocalizedString("Cannot load README.", comment: "") ) + self.dataSource = self title = NSLocalizedString("Overview", comment: "") } diff --git a/Classes/Search/SearchViewController.swift b/Classes/Search/SearchViewController.swift index 28655f5a..006ea749 100644 --- a/Classes/Search/SearchViewController.swift +++ b/Classes/Search/SearchViewController.swift @@ -141,7 +141,7 @@ SearchResultSectionControllerDelegate { func objects(for listAdapter: ListAdapter) -> [ListDiffable] { switch state { case .idle: - var recents: [ListDiffable] = recentStore.values.flatMap { SearchRecentViewModel(query: $0) } + var recents: [ListDiffable] = recentStore.values.compactMap { SearchRecentViewModel(query: $0) } if recents.count > 0 { recents.insert(recentHeaderKey, at: 0) } diff --git a/Classes/Systems/GithubEmoji.swift b/Classes/Systems/GithubEmoji.swift index dc84e26e..d79b4d68 100644 --- a/Classes/Systems/GithubEmoji.swift +++ b/Classes/Systems/GithubEmoji.swift @@ -56,7 +56,7 @@ let GithubEmojis: EmojiStore = { let json = try? JSONSerialization.jsonObject(with: data, options: .init(rawValue: 0)), let dict = json as? [[String: Any]] else { return ([:], [:]) } - let emojis = dict.flatMap { GitHubEmoji(dict: $0) } + let emojis = dict.compactMap { GitHubEmoji(dict: $0) } var aliasMap = [String: GitHubEmoji]() var searchMap = [String: [GitHubEmoji]]() diff --git a/Classes/Utility/Accessibility.swift b/Classes/Utility/Accessibility.swift index eeea3ce6..18b94f2b 100644 --- a/Classes/Utility/Accessibility.swift +++ b/Classes/Utility/Accessibility.swift @@ -28,7 +28,7 @@ enum AccessibilityHelper { private extension AccessibilityHelper { static func generatedLabel(forContentViewContainer cell: ContentViewContaining) -> String { - let labels = cell.contentView.subviews.flatMap { $0.accessibilityLabel } + let labels = cell.contentView.subviews.compactMap { $0.accessibilityLabel } if labels.count == 1, let label = labels.first { return label } else { diff --git a/Classes/Utility/SearchQueryTokenizer.swift b/Classes/Utility/SearchQueryTokenizer.swift index 56b624e6..283a4d58 100644 --- a/Classes/Utility/SearchQueryTokenizer.swift +++ b/Classes/Utility/SearchQueryTokenizer.swift @@ -25,7 +25,7 @@ func tokenizeSearchQuery(_ query: String) -> SearchQueryParseResults { let chunks = query.components(separatedBy: " ") var leftover: String = query - let tokens: [Token] = chunks.flatMap { chunk -> Token? in + let tokens: [Token] = chunks.compactMap { chunk -> Token? in let chunk = chunk.trimmingCharacters(in: .whitespacesAndNewlines) let valueChunks = chunk.components(separatedBy: ":") guard !valueChunks.isEmpty else { return nil } diff --git a/Classes/View Controllers/BaseListViewController.swift b/Classes/View Controllers/BaseListViewController.swift index 653bb6b6..d882f488 100644 --- a/Classes/View Controllers/BaseListViewController.swift +++ b/Classes/View Controllers/BaseListViewController.swift @@ -35,7 +35,7 @@ LoadMoreSectionControllerDelegate { // required on init private let emptyErrorMessage: String - private weak var dataSource: BaseListViewControllerDataSource? + public weak var dataSource: BaseListViewControllerDataSource? public private(set) lazy var feed: Feed = { Feed(viewController: self, delegate: self) }() private var page: PagingType? @@ -43,12 +43,8 @@ LoadMoreSectionControllerDelegate { private let emptyKey: ListDiffable = "emptyKey" as ListDiffable private var filterQuery: String? - init( - emptyErrorMessage: String, - dataSource: BaseListViewControllerDataSource - ) { + init(emptyErrorMessage: String) { self.emptyErrorMessage = emptyErrorMessage - self.dataSource = dataSource super.init(nibName: nil, bundle: nil) } diff --git a/Classes/Views/Date+Display.swift b/Classes/Views/Date+Display.swift index d6143f62..b304c7be 100644 --- a/Classes/Views/Date+Display.swift +++ b/Classes/Views/Date+Display.swift @@ -23,28 +23,28 @@ extension Date { private var ago: Ago { let seconds = timeIntervalSinceNow if seconds > 0 { - return .future(Int(seconds)) + return Ago.future(Int(seconds)) } else { // negative and casted so other values are implied let minute: TimeInterval = -60 - let hour = minute * 60 - let day = hour * 24 - let month = day * 30 - let year = month * 12 + let hour: TimeInterval = minute * 60 + let day: TimeInterval = hour * 24 + let month: TimeInterval = day * 30 + let year: TimeInterval = month * 12 switch seconds { case minute+1 ... 0: - return .seconds(Int(seconds)) + return Ago.seconds(Int(seconds)) case hour+1 ..< minute+1: - return .minutes(Int(round(seconds / minute))) + return Ago.minutes(Int(round(seconds / minute))) case day+1 ..< hour+1: - return .hours(Int(round(seconds / hour))) + return Ago.hours(Int(round(seconds / hour))) case month+1 ..< day+1: - return .days(Int(round(seconds / day))) + return Ago.days(Int(round(seconds / day))) case year+1 ..< month+1: - return .months(Int(round(seconds / month))) + return Ago.months(Int(round(seconds / month))) default: - return .years(Int(round(seconds / year))) + return Ago.years(Int(round(seconds / year))) } } } diff --git a/Freetime.xcodeproj/project.pbxproj b/Freetime.xcodeproj/project.pbxproj index 6aa933a9..a2224b1f 100644 --- a/Freetime.xcodeproj/project.pbxproj +++ b/Freetime.xcodeproj/project.pbxproj @@ -1937,7 +1937,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0830; - LastUpgradeCheck = 0900; + LastUpgradeCheck = 0930; ORGANIZATIONNAME = "Ryan Nystrom"; TargetAttributes = { 297AE8331EC0D58A00B44A1F = { @@ -2735,6 +2735,7 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; @@ -2742,6 +2743,7 @@ CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; @@ -2773,8 +2775,8 @@ ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_COMPILATION_MODE = wholemodule; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_WHOLE_MODULE_OPTIMIZATION = YES; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; @@ -2793,6 +2795,7 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; @@ -2800,6 +2803,7 @@ CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; @@ -2824,7 +2828,6 @@ MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_WHOLE_MODULE_OPTIMIZATION = YES; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; @@ -2934,6 +2937,7 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; @@ -2941,6 +2945,7 @@ CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; @@ -2965,7 +2970,6 @@ MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_WHOLE_MODULE_OPTIMIZATION = YES; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; diff --git a/Freetime.xcodeproj/xcshareddata/xcschemes/Freetime-AppCenter.xcscheme b/Freetime.xcodeproj/xcshareddata/xcschemes/Freetime-AppCenter.xcscheme index 674c7614..40cf6c82 100644 --- a/Freetime.xcodeproj/xcshareddata/xcschemes/Freetime-AppCenter.xcscheme +++ b/Freetime.xcodeproj/xcshareddata/xcschemes/Freetime-AppCenter.xcscheme @@ -1,6 +1,6 @@