Replaces PatreonAccount.isFriendZone with ManagedPatron

Rather than store both the current user’s Patreon account and all cached Friend Zone patrons in the same table, we now store Friend Zone patrons in the new ManagedPatron table. This avoids the need to distinguish between the two at runtime.
This commit is contained in:
Riley Testut
2022-04-18 15:31:29 -07:00
parent aa8dd80e54
commit dfd49de8d1
5 changed files with 17 additions and 41 deletions

View File

@@ -70,24 +70,15 @@ class UpdatePatronsOperation: ResultOperation<Void>
do
{
let patrons = try result.get()
let managedPatrons = patrons.map { (patron) -> PatreonAccount in
let account = PatreonAccount(patron: patron, context: self.context)
account.isFriendZonePatron = true
return account
}
let managedPatrons = patrons.map { ManagedPatron(patron: $0, context: self.context) }
var patronIDs = Set(managedPatrons.map { $0.identifier })
if let userAccountID = Keychain.shared.patreonAccountID
{
// Insert userAccountID into patronIDs to prevent it from being deleted.
patronIDs.insert(userAccountID)
}
let patronIDs = Set(managedPatrons.map { $0.identifier })
let nonFriendZonePredicate = NSPredicate(format: "NOT (%K IN %@)", #keyPath(ManagedPatron.identifier), patronIDs)
let removedPredicate = NSPredicate(format: "NOT (%K IN %@)", #keyPath(PatreonAccount.identifier), patronIDs)
let removedPatrons = PatreonAccount.all(satisfying: removedPredicate, in: self.context)
for patreonAccount in removedPatrons
let nonFriendZonePatrons = ManagedPatron.all(satisfying: nonFriendZonePredicate, in: self.context)
for managedPatron in nonFriendZonePatrons
{
self.context.delete(patreonAccount)
self.context.delete(managedPatron)
}
try self.context.save()

View File

@@ -75,24 +75,23 @@ class PatreonViewController: UICollectionViewController
private extension PatreonViewController
{
func makeDataSource() -> RSTCompositeCollectionViewDataSource<PatreonAccount>
func makeDataSource() -> RSTCompositeCollectionViewDataSource<ManagedPatron>
{
let aboutDataSource = RSTDynamicCollectionViewDataSource<PatreonAccount>()
let aboutDataSource = RSTDynamicCollectionViewDataSource<ManagedPatron>()
aboutDataSource.numberOfSectionsHandler = { 1 }
aboutDataSource.numberOfItemsHandler = { _ in 0 }
let dataSource = RSTCompositeCollectionViewDataSource<PatreonAccount>(dataSources: [aboutDataSource, self.patronsDataSource])
let dataSource = RSTCompositeCollectionViewDataSource<ManagedPatron>(dataSources: [aboutDataSource, self.patronsDataSource])
dataSource.proxy = self
return dataSource
}
func makePatronsDataSource() -> RSTFetchedResultsCollectionViewDataSource<PatreonAccount>
func makePatronsDataSource() -> RSTFetchedResultsCollectionViewDataSource<ManagedPatron>
{
let fetchRequest: NSFetchRequest<PatreonAccount> = PatreonAccount.fetchRequest()
fetchRequest.predicate = NSPredicate(format: "%K == YES", #keyPath(PatreonAccount.isFriendZonePatron))
fetchRequest.sortDescriptors = [NSSortDescriptor(key: #keyPath(PatreonAccount.name), ascending: true, selector: #selector(NSString.caseInsensitiveCompare(_:)))]
let fetchRequest: NSFetchRequest<ManagedPatron> = ManagedPatron.fetchRequest()
fetchRequest.sortDescriptors = [NSSortDescriptor(key: #keyPath(ManagedPatron.name), ascending: true, selector: #selector(NSString.caseInsensitiveCompare(_:)))]
let patronsDataSource = RSTFetchedResultsCollectionViewDataSource<PatreonAccount>(fetchRequest: fetchRequest, managedObjectContext: DatabaseManager.shared.viewContext)
let patronsDataSource = RSTFetchedResultsCollectionViewDataSource<ManagedPatron>(fetchRequest: fetchRequest, managedObjectContext: DatabaseManager.shared.viewContext)
patronsDataSource.cellConfigurationHandler = { (cell, patron, indexPath) in
let cell = cell as! PatronCollectionViewCell
cell.textLabel.text = patron.name

View File

@@ -87,7 +87,6 @@
<entity name="PatreonAccount" representedClassName="PatreonAccount" syncable="YES">
<attribute name="firstName" optional="YES" attributeType="String"/>
<attribute name="identifier" attributeType="String"/>
<attribute name="isFriendZonePatron" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
<attribute name="isPatron" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="name" attributeType="String"/>
<uniquenessConstraints>
@@ -178,7 +177,7 @@
<element name="InstalledApp" positionX="-63" positionY="0" width="128" height="268"/>
<element name="InstalledExtension" positionX="-45" positionY="135" width="128" height="163"/>
<element name="NewsItem" positionX="-45" positionY="126" width="128" height="238"/>
<element name="PatreonAccount" positionX="-45" positionY="117" width="128" height="104"/>
<element name="PatreonAccount" positionX="-45" positionY="117" width="128" height="89"/>
<element name="RefreshAttempt" positionX="-45" positionY="117" width="128" height="105"/>
<element name="Source" positionX="-45" positionY="99" width="128" height="133"/>
<element name="StoreApp" positionX="-63" positionY="-18" width="128" height="343"/>

View File

@@ -38,7 +38,6 @@ public class PatreonAccount: NSManagedObject, Fetchable
@NSManaged public var firstName: String?
@NSManaged public var isPatron: Bool
@NSManaged public var isFriendZonePatron: NSNumber?
private override init(entity: NSEntityDescription, insertInto context: NSManagedObjectContext?)
{
@@ -63,16 +62,6 @@ public class PatreonAccount: NSManagedObject, Fetchable
self.isPatron = false
}
}
public init(patron: Patron, context: NSManagedObjectContext)
{
super.init(entity: PatreonAccount.entity(), insertInto: context)
self.identifier = patron.identifier
self.name = patron.name
self.firstName = nil
self.isPatron = (patron.status == .active)
}
}
public extension PatreonAccount

View File

@@ -246,10 +246,8 @@ public extension PatreonAPI
DatabaseManager.shared.persistentContainer.performBackgroundTask { (context) in
do
{
if let account = DatabaseManager.shared.patreonAccount(in: context)
{
context.delete(account)
}
let accounts = PatreonAccount.all(in: context, requestProperties: [\.returnsObjectsAsFaults: true])
accounts.forEach(context.delete(_:))
self.deactivateBetaApps(in: context)