forked from shadowfacts/Tusker
Fix crash when viewing instance public timelines
Use a CoreData in-memory store for public timelines.
This commit is contained in:
parent
04496aca1d
commit
cd78287a87
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
public final class Status: StatusProtocol, Decodable {
|
public final class Status: /*StatusProtocol,*/ Decodable {
|
||||||
public let id: String
|
public let id: String
|
||||||
public let uri: String
|
public let uri: String
|
||||||
public let url: URL?
|
public let url: URL?
|
||||||
|
@ -23,8 +23,8 @@ public final class Status: StatusProtocol, Decodable {
|
||||||
// public let repliesCount: Int
|
// public let repliesCount: Int
|
||||||
public let reblogsCount: Int
|
public let reblogsCount: Int
|
||||||
public let favouritesCount: Int
|
public let favouritesCount: Int
|
||||||
public let reblogged: Bool
|
public let reblogged: Bool?
|
||||||
public let favourited: Bool
|
public let favourited: Bool?
|
||||||
public let muted: Bool?
|
public let muted: Bool?
|
||||||
public let sensitive: Bool
|
public let sensitive: Bool
|
||||||
public let spoilerText: String
|
public let spoilerText: String
|
||||||
|
|
|
@ -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
|
let instanceURL: URL
|
||||||
var accountInfo: LocalData.UserAccountInfo?
|
var accountInfo: LocalData.UserAccountInfo?
|
||||||
|
@ -40,10 +41,11 @@ class MastodonController {
|
||||||
var account: Account!
|
var account: Account!
|
||||||
var instance: Instance!
|
var instance: Instance!
|
||||||
|
|
||||||
init(instanceURL: URL) {
|
init(instanceURL: URL, transient: Bool = false) {
|
||||||
self.instanceURL = instanceURL
|
self.instanceURL = instanceURL
|
||||||
self.accountInfo = nil
|
self.accountInfo = nil
|
||||||
self.client = Client(baseURL: instanceURL)
|
self.client = Client(baseURL: instanceURL)
|
||||||
|
self.transient = transient
|
||||||
}
|
}
|
||||||
|
|
||||||
func run<Result>(_ request: Request<Result>, completion: @escaping Client.Callback<Result>) {
|
func run<Result>(_ request: Request<Result>, completion: @escaping Client.Callback<Result>) {
|
||||||
|
|
|
@ -22,9 +22,18 @@ class MastodonCachePersistentStore: NSPersistentContainer {
|
||||||
|
|
||||||
let statusSubject = PassthroughSubject<String, Never>()
|
let statusSubject = PassthroughSubject<String, Never>()
|
||||||
let accountSubject = PassthroughSubject<String, Never>()
|
let accountSubject = PassthroughSubject<String, Never>()
|
||||||
|
|
||||||
init(for controller: MastodonController) {
|
init(for accountInfo: LocalData.UserAccountInfo?, transient: Bool = false) {
|
||||||
super.init(name: "\(controller.accountInfo!.id)_cache", managedObjectModel: MastodonCachePersistentStore.managedObjectModel)
|
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
|
loadPersistentStores { (description, error) in
|
||||||
if let error = error {
|
if let error = error {
|
||||||
fatalError("Unable to load persistent store: \(error)")
|
fatalError("Unable to load persistent store: \(error)")
|
||||||
|
|
|
@ -106,7 +106,7 @@ extension StatusMO {
|
||||||
self.content = status.content
|
self.content = status.content
|
||||||
self.createdAt = status.createdAt
|
self.createdAt = status.createdAt
|
||||||
self.emojis = status.emojis
|
self.emojis = status.emojis
|
||||||
self.favourited = status.favourited
|
self.favourited = status.favourited ?? false
|
||||||
self.favouritesCount = status.favouritesCount
|
self.favouritesCount = status.favouritesCount
|
||||||
self.hashtags = status.hashtags
|
self.hashtags = status.hashtags
|
||||||
self.inReplyToAccountID = status.inReplyToAccountID
|
self.inReplyToAccountID = status.inReplyToAccountID
|
||||||
|
@ -115,7 +115,7 @@ extension StatusMO {
|
||||||
self.mentions = status.mentions
|
self.mentions = status.mentions
|
||||||
self.muted = status.muted ?? false
|
self.muted = status.muted ?? false
|
||||||
self.pinnedInternal = status.pinned ?? false
|
self.pinnedInternal = status.pinned ?? false
|
||||||
self.reblogged = status.reblogged
|
self.reblogged = status.reblogged ?? false
|
||||||
self.reblogsCount = status.reblogsCount
|
self.reblogsCount = status.reblogsCount
|
||||||
self.sensitive = status.sensitive
|
self.sensitive = status.sensitive
|
||||||
self.spoilerText = status.spoilerText
|
self.spoilerText = status.spoilerText
|
||||||
|
|
|
@ -37,7 +37,7 @@ class InstanceTimelineViewController: TimelineTableViewController {
|
||||||
self.instanceURL = url
|
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
|
// 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)
|
super.init(for: .public(local: true), mastodonController: instanceMastodonController)
|
||||||
|
|
||||||
|
|
|
@ -261,7 +261,7 @@ class BaseStatusTableViewCell: UITableViewCell {
|
||||||
mastodonController.run(request) { response in
|
mastodonController.run(request) { response in
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
if case let .success(newStatus, _) = response {
|
if case let .success(newStatus, _) = response {
|
||||||
self.favorited = newStatus.favourited
|
self.favorited = newStatus.favourited ?? false
|
||||||
self.mastodonController.persistentContainer.addOrUpdate(status: newStatus, incrementReferenceCount: false)
|
self.mastodonController.persistentContainer.addOrUpdate(status: newStatus, incrementReferenceCount: false)
|
||||||
UIImpactFeedbackGenerator(style: .light).impactOccurred()
|
UIImpactFeedbackGenerator(style: .light).impactOccurred()
|
||||||
} else {
|
} else {
|
||||||
|
@ -286,7 +286,7 @@ class BaseStatusTableViewCell: UITableViewCell {
|
||||||
mastodonController.run(request) { response in
|
mastodonController.run(request) { response in
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
if case let .success(newStatus, _) = response {
|
if case let .success(newStatus, _) = response {
|
||||||
self.reblogged = newStatus.reblogged
|
self.reblogged = newStatus.reblogged ?? false
|
||||||
self.mastodonController.persistentContainer.addOrUpdate(status: newStatus, incrementReferenceCount: false)
|
self.mastodonController.persistentContainer.addOrUpdate(status: newStatus, incrementReferenceCount: false)
|
||||||
UIImpactFeedbackGenerator(style: .light).impactOccurred()
|
UIImpactFeedbackGenerator(style: .light).impactOccurred()
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue