Fix crash when viewing instance public timelines

Use a CoreData in-memory store for public timelines.
This commit is contained in:
Shadowfacts 2020-05-11 17:57:50 -04:00
parent 04496aca1d
commit cd78287a87
Signed by: shadowfacts
GPG Key ID: 94A5AB95422746E5
6 changed files with 24 additions and 13 deletions

View File

@ -8,7 +8,7 @@
import Foundation
public final class Status: StatusProtocol, Decodable {
public final class Status: /*StatusProtocol,*/ Decodable {
public let id: String
public let uri: String
public let url: URL?
@ -23,8 +23,8 @@ public final class Status: StatusProtocol, Decodable {
// public let repliesCount: Int
public let reblogsCount: Int
public let favouritesCount: Int
public let reblogged: Bool
public let favourited: Bool
public let reblogged: Bool?
public let favourited: Bool?
public let muted: Bool?
public let sensitive: Bool
public let spoilerText: String

View File

@ -30,7 +30,8 @@ class MastodonController {
}
}
private(set) lazy var persistentContainer = MastodonCachePersistentStore(for: self)
private let transient: Bool
private(set) lazy var persistentContainer = MastodonCachePersistentStore(for: accountInfo, transient: transient)
let instanceURL: URL
var accountInfo: LocalData.UserAccountInfo?
@ -40,10 +41,11 @@ class MastodonController {
var account: Account!
var instance: Instance!
init(instanceURL: URL) {
init(instanceURL: URL, transient: Bool = false) {
self.instanceURL = instanceURL
self.accountInfo = nil
self.client = Client(baseURL: instanceURL)
self.transient = transient
}
func run<Result>(_ request: Request<Result>, completion: @escaping Client.Callback<Result>) {

View File

@ -22,9 +22,18 @@ class MastodonCachePersistentStore: NSPersistentContainer {
let statusSubject = PassthroughSubject<String, Never>()
let accountSubject = PassthroughSubject<String, Never>()
init(for controller: MastodonController) {
super.init(name: "\(controller.accountInfo!.id)_cache", managedObjectModel: MastodonCachePersistentStore.managedObjectModel)
init(for accountInfo: LocalData.UserAccountInfo?, transient: Bool = false) {
if transient {
super.init(name: "transient_cache", managedObjectModel: MastodonCachePersistentStore.managedObjectModel)
let storeDescription = NSPersistentStoreDescription()
storeDescription.type = NSInMemoryStoreType
persistentStoreDescriptions = [storeDescription]
} else {
super.init(name: "\(accountInfo!.id)_cache", managedObjectModel: MastodonCachePersistentStore.managedObjectModel)
}
loadPersistentStores { (description, error) in
if let error = error {
fatalError("Unable to load persistent store: \(error)")

View File

@ -106,7 +106,7 @@ extension StatusMO {
self.content = status.content
self.createdAt = status.createdAt
self.emojis = status.emojis
self.favourited = status.favourited
self.favourited = status.favourited ?? false
self.favouritesCount = status.favouritesCount
self.hashtags = status.hashtags
self.inReplyToAccountID = status.inReplyToAccountID
@ -115,7 +115,7 @@ extension StatusMO {
self.mentions = status.mentions
self.muted = status.muted ?? false
self.pinnedInternal = status.pinned ?? false
self.reblogged = status.reblogged
self.reblogged = status.reblogged ?? false
self.reblogsCount = status.reblogsCount
self.sensitive = status.sensitive
self.spoilerText = status.spoilerText

View File

@ -37,7 +37,7 @@ class InstanceTimelineViewController: TimelineTableViewController {
self.instanceURL = url
// the timeline VC only stores a weak reference to it, so we need to store a strong reference to make sure it's not released immediately
instanceMastodonController = MastodonController(instanceURL: url)
instanceMastodonController = MastodonController(instanceURL: url, transient: true)
super.init(for: .public(local: true), mastodonController: instanceMastodonController)

View File

@ -261,7 +261,7 @@ class BaseStatusTableViewCell: UITableViewCell {
mastodonController.run(request) { response in
DispatchQueue.main.async {
if case let .success(newStatus, _) = response {
self.favorited = newStatus.favourited
self.favorited = newStatus.favourited ?? false
self.mastodonController.persistentContainer.addOrUpdate(status: newStatus, incrementReferenceCount: false)
UIImpactFeedbackGenerator(style: .light).impactOccurred()
} else {
@ -286,7 +286,7 @@ class BaseStatusTableViewCell: UITableViewCell {
mastodonController.run(request) { response in
DispatchQueue.main.async {
if case let .success(newStatus, _) = response {
self.reblogged = newStatus.reblogged
self.reblogged = newStatus.reblogged ?? false
self.mastodonController.persistentContainer.addOrUpdate(status: newStatus, incrementReferenceCount: false)
UIImpactFeedbackGenerator(style: .light).impactOccurred()
} else {