chore(Feed): Improve Feed performance by fetching statuses in batches (#914)
This commit is contained in:
parent
0a9689c67f
commit
3b87916d9a
|
@ -518,6 +518,12 @@ extension HomeTimelineViewController: UITableViewDelegate, AutoGenerateTableView
|
|||
}
|
||||
|
||||
// sourcery:end
|
||||
|
||||
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
|
||||
if indexPath.row == tableView.numberOfRows(inSection: indexPath.section) - 1 {
|
||||
viewModel.timelineDidReachEnd()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - TimelineMiddleLoaderTableViewCellDelegate
|
||||
|
|
|
@ -65,7 +65,7 @@ extension HomeTimelineViewModel.LoadLatestState {
|
|||
guard let viewModel else { return }
|
||||
|
||||
let latestFeedRecords = viewModel.fetchedResultsController.records.prefix(APIService.onceRequestStatusMaxCount)
|
||||
let parentManagedObjectContext = viewModel.fetchedResultsController.fetchedResultsController.managedObjectContext
|
||||
let parentManagedObjectContext = viewModel.fetchedResultsController.managedObjectContext
|
||||
let managedObjectContext = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
|
||||
managedObjectContext.parent = parentManagedObjectContext
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ extension HomeTimelineViewModel.LoadOldestState {
|
|||
}
|
||||
|
||||
Task {
|
||||
let managedObjectContext = viewModel.fetchedResultsController.fetchedResultsController.managedObjectContext
|
||||
let managedObjectContext = viewModel.fetchedResultsController.managedObjectContext
|
||||
let _maxID: Mastodon.Entity.Status.ID? = try await managedObjectContext.perform {
|
||||
guard let feed = lastFeedRecord.object(in: managedObjectContext),
|
||||
let status = feed.status
|
||||
|
|
|
@ -119,6 +119,12 @@ extension HomeTimelineViewModel {
|
|||
}
|
||||
}
|
||||
|
||||
extension HomeTimelineViewModel {
|
||||
func timelineDidReachEnd() {
|
||||
fetchedResultsController.fetchNextBatch()
|
||||
}
|
||||
}
|
||||
|
||||
extension HomeTimelineViewModel {
|
||||
|
||||
// load timeline gap
|
||||
|
|
|
@ -16,11 +16,19 @@ import MastodonSDK
|
|||
|
||||
final public class FeedFetchedResultsController: NSObject {
|
||||
|
||||
private enum Constants {
|
||||
static let defaultFetchLimit = 100
|
||||
}
|
||||
|
||||
public let logger = Logger(subsystem: "FeedFetchedResultsController", category: "DB")
|
||||
|
||||
var disposeBag = Set<AnyCancellable>()
|
||||
|
||||
public let fetchedResultsController: NSFetchedResultsController<Feed>
|
||||
private let fetchedResultsController: NSFetchedResultsController<Feed>
|
||||
|
||||
public var managedObjectContext: NSManagedObjectContext {
|
||||
fetchedResultsController.managedObjectContext
|
||||
}
|
||||
|
||||
// input
|
||||
@Published public var predicate = Feed.predicate(kind: .none, acct: .none)
|
||||
|
@ -28,6 +36,11 @@ final public class FeedFetchedResultsController: NSObject {
|
|||
// output
|
||||
private let _objectIDs = PassthroughSubject<[NSManagedObjectID], Never>()
|
||||
@Published public var records: [ManagedObjectRecord<Feed>] = []
|
||||
|
||||
public func fetchNextBatch() {
|
||||
fetchedResultsController.fetchRequest.fetchLimit += Constants.defaultFetchLimit
|
||||
try? fetchedResultsController.performFetch()
|
||||
}
|
||||
|
||||
public init(managedObjectContext: NSManagedObjectContext) {
|
||||
self.fetchedResultsController = {
|
||||
|
@ -36,6 +49,7 @@ final public class FeedFetchedResultsController: NSObject {
|
|||
fetchRequest.returnsObjectsAsFaults = false
|
||||
fetchRequest.shouldRefreshRefetchedObjects = true
|
||||
fetchRequest.fetchBatchSize = 15
|
||||
fetchRequest.fetchLimit = Constants.defaultFetchLimit
|
||||
let controller = NSFetchedResultsController(
|
||||
fetchRequest: fetchRequest,
|
||||
managedObjectContext: managedObjectContext,
|
||||
|
|
Loading…
Reference in New Issue